SeatGeek 团队 日前宣布 为Sixpack A/B测试框架增加了一个新的客户端,也就是Sixpack-java,它的目标是简化Android和Java应用的A/B测试。
A/B测试通常用来优化Web网站。开发者准备好网站的各种不同方案,这些方案在一些次要方面如颜色方案或者按钮标签等存在一些差异。这些不同的方案以预定的比例呈现给用户,然后根据转换率、时间或者数量目标确定更成功的方案。最后将最成功的方案呈现给网站所有用户。
Sixpack是一个与语言无关的A/B测试框架,具有非常易用的API和内置的dashboard。Sixpack有两个主要的组件,即Sixpack server和Sixpack web。其中sixpack server负责收集experiment 数据并决定要将哪一个可选方案展现给哪些人。Sixpack web是一个基于Web的dashboard。Sixpack支持多种语言的客户端,目前包括 PHP 、 Ruby 、 Python 和 JavaScript 。
借助最新提供的Java客户端,可以编写针对Android应用的A/B测试用例。在使用Java客户端之前,需要预先安装并运行Sixpack server,在该项目的Github主页上提供了 安装指导 。
在编写A/B测试时,首先需要引入对Sixpack-java的依赖,目前它已经发布到了Sonatype的快照仓库中,因此可以通过Gradle声明依赖:
repositories { maven { url 'https://oss.sonatype.org/content/repositories/snapshots' } } dependencies { compile 'com.seatgeek:sixpack:0.1-SNAPSHOT' }
依赖正确解析之后,就能够为应用编写A/B测试了,我们需要初始化Sixpack客户端,在这个过程中可以使用SixpackBuilder来创建新的Sixpack实例:
Sixpack sixpack = new SixpackBuilder() .setSixpackUrl("http://api.mycompany.com/sixpack") .setClientId(getCachedClientId()) .build();
在这里所引用的getCachedClientId()方法可能会如下所示:
public String getCachedClientId() { SharedPreferences prefs = context.getSharedPreferences("sixpack", Context.MODE_PRIVATE); String clientId = prefs.getString("sixpack_client_id"); if (clientId == null) { clientId = Sixpack.generateRandomClientId(); prefs.edit().put("sixpack_client_id", clientId).apply(); } return clientId; }
这里有两件较为重要的事情需要注意:第一,需要将setSixpackUrl()方法中的URL指向你所部署的Sixpack server的地址,第二件事情就是client id,client id是Sixpack server所使用的一个唯一标识,用来跟踪每个客户端使用了experiment 中的哪一个可选方案,因此在会话中,这个client id不能发生变化。因此,Sixpack给出的建议是只生成client id一次(通过Sixpack.generateRandomClientId()所提供的帮助方法),然后将其缓存在SharedPreferences中,这样就可以下次继续使用了。
当然,SeatGeek团队还建议我们借助依赖注入实现,维护一个单例的Sixpack实例,他们所使用的依赖实现是 dagger 。
一切基础工作就绪后,sixpack提供了一个针对按钮颜色的样例,如下所示:
Experiment buttonColor = sixpack.experiment() .withName("Button Color") .withAlternative(new Alternative("Red")) .withAlternative(new Alternative("Green")) .build();
在这个样例中,创建了名为“Button Color”的experiment,它包含了两个可选方案,分别为“Red”和“Green”。当客户端参与这个experiment的时候,就能够在Sixpack web的dashboard上看到。
要启动测试话,需要调用Experiment#participate()并传入适当的回调方法,使用Java 8的lambda表达式能够使代码更为简化:
buttonColor.participate( (participatingExperiment) -> { // success! save the participating instance for later so that we can convert it and set our button color this.participatingExperiment = participatingExperiment; button.setBackgroundColor(participatingExperiment.selectedAlternative == redAlternative ? R.color.button_red : R.color.button_green); }, (experiment, error) -> { // failure, check network connection and try to participate again, you should also likely fallback to a default } );
当用户点击按钮的时候(假设这就是样例所要衡量的行为),那么我们可以将convert()信息发送到Sixpack上。
通过这样的一个过程,就成功完成了按钮颜色的测试,最终形成的结果在dashboard上可能会如下所示:
最后,sixpack还给出了一些高级的用法,比如将ParticipatingExperiment暴露为RxJava的Observables并缓存结果;除了将单例的Sixpack保存在DI中以外,还可以将Experiment和ParticipatingExperiment放到dagger模块中,这样它们的生命周期与应用中的其他一些组件就会相互独立;如果在系统中,用户进行了注册,并且有id的话,可以使用这个id作为client id,然后使用 Sixpack-server的API 将A/B测试的结果与应用的用户进行关联。
随着移动应用对用户体验越来越重视,出现了Splitforce、sixpack等可以用在移动应用上的A/B测试框架,这些框架将会有助于分析用户的行为,实现更优的用户体验。
感谢徐川对本文的审校。
给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ,@丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入InfoQ读者交流群 )。