【Android单元测试系列】真正的异步单元测试
2015-06-25 15:27
399 查看
背景
参考了网上诸多的Android异步单元测试的方法之后,发现方法就两种,但是却没有发现这两种方法的一些关键说明,也正是少了这些关键说明,我绕了很大的圈子方法一
public class ExampleInstrumentationTeseCase extends InstrumentationTestCase { private Activity mActivity; private Context mApplicationContext; @Override protected void setUp() throws Exception { super.setUp(); Intent intent = new Intent(); intent.setClassName("com.example.demo", TestcaseActivity.class.getName()); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mActivity = (TestcaseActivity) getInstrumentation().startActivitySync(intent); mApplicationContext = mActivity.getApplicationContext(); } @Override protected void tearDown() throws Exception { mActivity.finish(); try { super.tearDown(); } catch (Exception e) { e.printStackTrace(); } super.tearDown(); } public void testAsyncTask() throws Throwable { final CountDownLatch signal = new CountDownLatch(1); // 在UI线程中执行异步操作 runTestOnUiThread(new Runnable() { @Override public void run() { // 执行异步任务,这个只是例子,没有实际的可以运行的代码,大家知道就好 new MyAsyncTask() { @Override protected void onPostExecute(String result) { super.onPostExecute(result); assertEquals("kale", result); signal.countDown(); } }.execute(); } }); signal.await(); } }
方法二
public void testAsyncTask() throws Throwable { final CountDownLatch signal = new CountDownLatch(1); final String TDD = "TDD"; // 在UI线程中执行异步操作 runTestOnUiThread(new Runnable() { @Override public void run() { // 执行异步任务,这个只是例子,没有实际的可以运行的代码,大家知道就好 new MyAsyncTask() { @Override protected void onPostExecute(String result) { super.onPostExecute(result); assertEquals("kale", result); synchronized (TDD) { TDD.notify(); } } }.execute(); } }); synchronized (TDD) { TDD.notify(); } }
分析&&关键点
上面两种实现方法其实很类似的,就是借助同步工具来进行阻塞辅助,而且网上很多地方都有这种代码,但是,实际上跑起来之后,发现是一直没有跑完的。针对方法一来进行
分析:当执行assertEquals的时候,测试代码就结束了,也不会执行signal.countDown(),因此程序一直阻塞,导致没有跑完
于是,将
signal.countDown();和
assertEquals("kale", result);交换位置
public void testAsyncTask() throws Throwable { final CountDownLatch signal = new CountDownLatch(1); // 在UI线程中执行异步操作 runTestOnUiThread(new Runnable() { @Override public void run() { // 执行异步任务,这个只是例子,没有实际的可以运行的代码,大家知道就好 new MyAsyncTask() { @Override protected void onPostExecute(String result) { super.onPostExecute(result); signal.countDown(); assertEquals("kale", result); } }.execute(); } }); signal.await(); // mark1 }
发现可以跑完了,但是无论如何都是测试通过的,即便值是不一样。
分析:当执行
signal.countDown();之后,代码就会跳转到上面注释的mark1的位置继续执行,而不是执行
assertEquals("kale", result);,因此无论断言的值是什么都会成功的,因为根本没有执行到断言那里
于是,再次修改代码,将回调中的值,用全局的私有变量缓存起来,然后在
signal.await();方法后面才进行断言判断,于是得出
最终可行的代码
private String temp = null; public void testAsyncTask() throws Throwable { final CountDownLatch signal = new CountDownLatch(1); // 在UI线程中执行异步操作 runTestOnUiThread(new Runnable() { @Override public void run() { // 执行异步任务,这个只是例子,没有实际的可以运行的代码,大家知道就好 new MyAsyncTask() { @Override protected void onPostExecute(String result) { super.onPostExecute(result); temp = result; signal.countDown(); } }.execute(); } }); signal.await(); assertEquals("kale", temp); }
亲测可行~~,但是就是写起来有点怪异,因为一个测试方法用到全局全局变量来缓存
相关文章推荐
- 使用eclipse CDT调试android native代码
- 用android动画实现手势动画
- android学习之路(四)----RenderScript
- Android横竖屏切换小结
- Firefly 3288重新制作android和lubuntu双系统固件
- android AndroidManifest.xml 多个android.intent.action.MAIN (
- Android SQLiteStatement 编译、执行 分析
- Android的Library工程
- android 加载图片oom的好的解决方法
- Android 中使用自定义字体的方法
- mono for Android 问题集合
- android 4.4 强制所有应用横屏显示
- [Android Studio] 取消引用库打包出现异常-- provided dependencies can only be jars
- android调用,暂停或停止系统自带音乐播放器
- android dialog
- 将Eclipse代码导入到AndroidStudio的两种方式
- Android 编程下 Touch 事件的分发和消费机制
- android activity切换效果实现
- [Flash 3D] 又是一个难题解决了。(Flash3D在android中运行)
- Android项目结构