当前位置: 首页 > 科技观察

如何在Android上测试异步任务

时间:2023-03-17 11:23:45 科技观察

最近,在Sixt(德国一家比较大的租车网站),我们将我们的开发环境从Eclipse迁移到了AndroidStudio。这也意味着我们进入了一个新的编译系统——Gradle,并将TDD(测试驱动开发)和CI(持续集成)融入到我们的软件开发过程中。这里不是讨论在软件开发中引入CI的好处,而是讨论在Android中测试UI以外的线程时会出现的问题。Android中的测试(广义定义)是单元测试集合的扩展。它涉及初始化和关闭测试,包括setUp()和tearDown()操作,使用反射来推断不同的测试方法(从JUnit4开始,我们可以使用注解来指定优先级并执行所有测试)。一个典型的测试结构如下:("Failingtest");}}这是一个非常明显的例子:在实际开发中,我们想要测试HTTP响应、SQL存储等。在Sixt,我们遵循管理器/模型方法:每个模型包含一个表示实体(汽车、客户等)。每个管理器都聚合了来自不同模型的一组功能(例如,我们的登录管理器可能需要一个用户与之交互的模型)。大多数管理人员专注于执行HTTP请求以从后台获取数据。例如,我们使用下面的代码来执行用户登录:mLoginManager.performLoginWithUsername("username","password",newOnLoginListener(){@OverridepublicvoidonFailure(Throwablethrowable){fail();}OverridepublicvoidonSuccess(Usercustomer){//..}});应用于我们自己的测试集,当我们得到意想不到的结果时,我们只是让那个结果失败。我们可以看到为什么我们在onFailure()函数中调用fail()。接下来,即使我使用了错误的用户名,这个测试也会通过。想了想,测试好像是按照代码顺序执行的,但是并没有等到回调函数的结果返回才往下执行。这显然不是一个好办法。因为现在的程序往往通过异步任务和回调的方式从后台获取数据。尝试过UIThread测试仍然不起作用。***,我发现下面的方法可以奏效。只需要用一个简单的CountDownLatch信号对象来实现wait-notify机制(也可以用synchronized(lock){...lock.notify();},不过这段代码不美观),那么之前的代码就变成了下面的看起来像:finalCountDownLatchsignal=newCountDownLatch(1);mLoginManager.performLoginWithUsername("username","password",newOnLoginListener(){@OverridepublicvoidonFailure(Throwablethrowable){fail();signal.countDown();}OverridepublicvoidonSuccess(Usercustomer){signal。countDown();}});signal.await();