我知道你觉得写单元测试很麻烦,所以,蘑菇街开源了一个安卓单元测试框架

我知道你觉得写单元测试很麻烦,所以。。。

我们开源了一个单元测试框架,里面提供了一系列的utility,希望能帮助你更快更轻松的写单元测试,能够少写一点boilerplate code,少一点痛苦,多一点愉悦!
地址在这里:https://github.com/mogujie/natasha

这个project是怎么来的?

蘑菇街目前采用组件化的开发方式,一个app由很多个模块组成,每个模块都有单元测试的部分,然而有很多代码都是类似的。因此,为了减少重复劳动,我们花时间抽出来一个独立的project,专门做unit testing用的。

这个project能帮你做什么?

如前所述,这个project里面主要是一些单元测试都会用到的公共代码,来帮助你更快的做unit testing,减少一些boilerplate code。
说白了就是一些帮助类,里面有些帮助方法。
最核心的是以下几个:

TestBase

TestBase应该是每一个Test Class最顶层的父类,它给你提供的帮助有:

  1. 一个MockitoRule 成员变量,所以在你自己的Test Class里面就不用每次需要@Mock的时候,都定义这个成员变量了。如果你看不懂这里说的什么意思,请看文章: 安卓单元测试(九):使用Mockito Annotation快速创建Mock
  2. 一个CountDownLatch,以及相应的await()countDown() 方法,方便你使用CountDownLatch来测试异步代码,不用每次都自己new一个CountDownLatch对象。默认的CountDown次数是1,你可以用resetLatch(count)来设置次数。如果你看不懂这里这的是什么意思,请看文章: 安卓单元测试(十一):异步代码怎么测试
  3. 读取资源文件的方法:readResource(file_name)把你的资源文件放在 src/test/resources文件夹下面,然后通过这个方法就能读出来。比如你有一个文件名为:person.json,放在src/test/resources文件夹下面,那么readResource("person.json")会把person.json的内容读出来,返回String。
  4. 根据我的经验,一般来说,你的资源文件里面是Json String,经过上面的方法读出来以后,如果你想变成Java Object,那么TestBase里面也有对应的方法:dataFromResource(file_name, clazz),比如上面的例子:dataFromResource(“person.json”, Person.class),就会把person.json里面的内容读出来,使用Gson变成Person类的对象。
  5. 一系列Assert.assert*的方法,简化你的书写,比如:
    1. ae(expected, actual); 等同于Assert.assertEquals(expected, actual);
    2. at(boolValue);等同于Assert.assertTrue(boolValue);;类似的, af(boolValue);等同于Assert.assertFalse(boolValue);
    3. ann(obj);等同于Assert.assertNotNull(obj);;类似的,an(obj);等同于Assert.assertNull(obj);

以上是一些写TestCase最常用到的东西,TestBase给你提供了一些便捷。另外还有一些不那么常用的,这里就不缀述了。如果你觉得自己经常用到一个东西,那么可以看看TestBase里面有没有,如果没有的话怎么办呢?那当然是Fork & PR啦!

ViewTestBase

这个类一般是用来测试Custom View的,你的CustomView对应的TestClass可以继承这个类。它给你提供的辅助有

  1. 上面提到的TestBase的所以辅助,因为ViewTestBase是继承处TestBase的。
  2. 一个需要你现实的createView()方法,这个方法返回的View就应该是待测的View,你可以通过mTargetView获得这个View的实例。
  3. child(viewId)方法,返回这个待测的View的一个子view
  4. assertViewVisible(view)/assertViewGone(view)用来assert 某一个view的visibility是VISIBLE/GONE,这两个方法需要你传一个View对象。类似的有 assertChildVisible(view)/assertChildGone(view),这两个类只需要你传待测View的子View的id就好了。

ActivityTestBase

顾名思义,这个类是用来测试Activity的,所以你的Activity对应的测试类应该继承这个类。它给你提供的便利有:

  1. 上面提到的ViewTestBase和TestBase提到的所以便利,因为这个类是继承自ViewTestBase的。
  2. 一个待实现的activityClass()方法,这个方法返回的应该是你要测的Activity的Class。ActivityTestBase会自动创建这个Activity实例,并保存在mActivity field里面,你可以通过这个field,或者是getActivity()方法获得这个Activity实例对象。如果你要自定义创建这个Activity的Intent,可以override activityIntent()这个方法。
  3. assertToast(text) assert 弹出了一个toast,内容为text
  4. assertEnabled(viewId)/assertDisabled(viewId) assert id为viewId的View的状态是Enabled/Disabled。
  5. view(viewId) 简化令人厌烦的findViewById(viewId)
  6. assertViewHasText(viewId, text) assert id 为viewId的View上面的文字含有text,类似的有assertViewText(viewId, text),这个是将text进行是否相等的对比。
  7. click(viewId) 触发id为viewId的view的点击事情。
  8. assertNextActivity(clazz) assert 启动了一个类是clazz的Activity。
  9. 。。。。。。

再说一遍,这不是一个完整的列表,只是列了一些最为常用的。如果有漏掉的,欢迎PR补上!

怎么样使用?

目前项目已经发布到了jcenter,在build.gradledependencies里面加上

dependencies {
    testCompile 'com.github.mogujie:natasha:0.6.3'
}

就OK了。

Enjoy!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • 当窗外声声鸟鸣, 你, 翻身出门, 骑上摩拜, 观光绿道。 晨雾已散, 空气宜人, 泥土气息, 悠悠飘来。 秧苗的...
    辰辰2008阅读 339评论 0 2
  • 1 就像是摔碎了一角的瓶子,尽管从外观看来还是完整的,但那个碎掉的部分是真实存在的。 而我,就是这样一个破损的敏感...
    大学的故事阅读 365评论 5 13
  • 本教程将告诉你在创建几何背景色。这种技术使用矢量形状图层,图层样式,创建出一个惊人的背景。 步骤1 创建一个新的3...
    3e39d85c28ab阅读 445评论 0 0