Prateek Baheti是ThoughtWorks的开发人员,他做了两年Twist的开发。除了写代码,他还喜欢驾驶,听音乐,看板球比赛,打乒乓球。
Vishnu Karthik是ThoughtWorks的开发人员,他一直从事Twist的开发和测试自动化。之前他在比哈尔(印度东北部一座城市)的医疗保健服务中心工作。除了写代码,他还喜欢玩极限飞盘。
为什么使用BDD?移动应用程序现在已经非常普及,大多数的应用可以支持3种主流平台:iOS、Android和Windows phones。此外Firefox OS平台的市场占有率也在不断提升中。
应用程序的功能是与平台无关的。但是不同的平台还是会有差异,例如处理消息事件的方式等。测试移动应用程序,并保证它们能在所有的平台上正常工作,是一项很有挑战的工作。我们需要为不同的平台编写不同的测试用例并且分别执行。这样就会导致各个平台上的测试覆盖率不一样,而且测试用例也会变得原来越难维护。平台级别的差异实际上和应用程序的功能是无关的,所以理想的中的测试用例应该纯粹使用业务语言进行描述。
行为驱动开发(BDD)风格的测试可以极大地改善这种情况。
1对底层细节进行抽象并提供高层次的步骤(steps):BDD风格的测试用例使用纯业务领域的语言进行描述。这种方式提供了一种更好的理解测试用例的途径。测试用例使用了高层次的逻辑表述,而不会包含具体的实现细节(例如点击一个按钮)。
BDD方法有很多工具的支持,这些工具可以把测试案例规范和底层实现细节关联起来。这种风格的测试已经被证明是易于维护的,也易于描述测试用例。
针对移动应用程序,BDD可以在以下方面提供帮助:
BDD对底层细节进行抽象,并提供高层次的测试用例步骤,这样就会与平台无关了。下面来看一个发短信的应用程序的测试场景。这个测试使用Twist编写而成。

2因此这种测试用例可以被不同平台和团队使用:上面的测试不涉及任何的底层实现,而是使用了平台无关的语言,用业务术语描述测试场景。在这个测试用例中,接收消息提示是一个业务上的术语,对它的实现将会针对平台而不同。
public interface MessagingDriver {会有一个通用的接口来负责和不同的实现进行交互。
void login(String userName);
void sendMessage(String toAddress, String
message);
void checkForNotifications(String
address);
}
public class AndroidMessagingDriverimplements MessagingDriver {public void login(String userName) {// login for android}public void sendMessage(String toAddress,String message) {// send message for android}public void checkForNotifications(Stringaddress) {// check for notification for android}}现在每个平台可以有特定的实现了:
public class MessagingDriverFactory {public static MessagingDrivergetMessagingDriver() {String testPlatform =System.getenv("TEST_PLATFORM");if (testPlatform.equals("android")) {return new AndroidMessagingDriver();} else if (testPlatform.equals("ios")) {return new IOSMessagingDriver();}throw new RuntimeException("Failed to find animplementation");}}这样,测试实现仅仅需要去使用工厂模式和事先设置好的合适的环境变量,测试运行的时候会自动匹配相对应的平台驱动。
测试数据和测试场景不再需要重复,它们被视作一个可以执行的文档,从而共享给同一个应用的不同平台的团队。