android单元测试JUnit 4

JUnit 4

  • 单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。在android中常将一个方法或者一个类作为一个最小可测试单元。
  • JUnit 4是Android Testing Support Library库中提供的用户单元测试的一个框架。在Android studio中可以直接使用。

本地单元测试 Local Unit Tests

  • Local Unit Tests运行在本地开发环境的JVM上,不需要连接android设备,但是同时也无法测试使用了与android相关的API
    的单元。
  • Local Unit Tests测试用例的编写主要依靠一些注解来进行已经依靠assertxxx来断言测试是否通过。

Junit 4注解

  • @Before标注setup方法,每个单元测试用例方法调用之前都会调用
  • @After标注teardown方法,每个单元测试用例方法调用之后都会调用
  • @Test标注的每个方法都是一个测试用例
  • @BeforeClass标注的静态方法,在当前测试类所有用例方法执行之前执行
  • @AfterClass标注的静态方法,在当前测试类所有用例方法执行之后执行
  • @Test(timeout=)为测试用例指定超时时间

断言

  • assertTrue(condition):condition为真pass,否则fail
  • assertFalse(condition):condition为假pass,否则fail
  • fail():直接fail
  • assertEquals(expected, actual):expected equal actual pass,否则fail
  • assertSame(expected, actual):expected == actual pass,否则fail

实例

  • 编写测试用例
/**
 * Created by jason on 2018/2/28.
 */
public class CalculationTest {

    Calculation calculation;

    @BeforeClass
    public static void start() {
        System.out.println("类运行时调用一次");
    }

    @AfterClass
    public static void end() {
        System.out.println("类结束时调用一次");
    }

    @Before
    public void before() {
        calculation = new Calculation();
        System.out.println("每个test方法前都会调用");
    }

    @After
    public void after() {
        System.out.println("每个test方法结束都会调用");
    }

    @Test
    public void add() throws Exception {
        System.out.println("test add");
        int r = calculation.add(2, 3);
        Assert.assertEquals(5, r);
    }

}
  • 输出
类运行时调用一次
每个test方法前都会调用
test add
每个test方法结束都会调用
类结束时调用一次
  • 修改断言使测试不通过
    @Test
    public void add() throws Exception {
        System.out.println("test add");
        int r = calculation.add(2, 3);
        Assert.assertEquals(6, r);//修改为结果为6时测试通过
    }
  • 修改后输出
类运行时调用一次
每个test方法前都会调用
test add
每个test方法结束都会调用

java.lang.AssertionError: 
Expected :6
Actual   :5
 <Click to see difference>
...

  • 修改add方法,添加由Android提供的API,由于Local Unit Tests只能测试jdk提供的方法,所以应该是会报错的。
import static android.content.ContentValues.TAG;

/**
 * Created by jason on 2018/2/28.
 */

public class Calculation {


    public int add(int a , int b) {
        Log.d(TAG, "add: ");
        return a+b;
    }

}
  • 结果报错
类运行时调用一次
每个test方法前都会调用
test add
每个test方法结束都会调用

java.lang.RuntimeException: Method d in android.util.Log not mocked. See http://g.co/androidstudio/not-mocked for details.
...

设备单元测试 Instrumented Unit Tests

  • Instrumented Unit Tests需要连接安卓设备或者模拟器,与上面的本地单元测试相比,自然是多了可以测试android的API。
  • 在使用上相比本地单元测试该测试类必须以@RunWith(AndroidJUnit4.class) 注解作为前缀。
  • 相比Local Unit Tests 多了访问设备信息、测试筛选功能。

访问设备信息

我们可以使用 InstrumentationRegistry 类访问与测试运行相关的信息。此类包括 Instrumentation对象、目标应用Context对象、测试应用Context对象,以及传递到测试中的命令行参数。

测试筛选

  • @RequiresDevice:指定测试仅在物理设备而不在模拟器上运行。
  • @SdkSupress:禁止在低于给定级别的 Android API 级别上运行测试。例如,要禁止在低于 18 的所有 API 级别上运行测试,请使用注解 @SDKSupress(minSdkVersion=18)。
  • @SmallTest、@MediumTest和@LargeTest:指定测试的运行时长以及运行频率。

实例

  • 编写测试用例
@RunWith(AndroidJUnit4.class)
@SdkSuppress(minSdkVersion = 18)
public class ConfigTest {

    private static String userId;

    @Before
    public static void initId() {
        userId  = "123456";
    }

    @Test
    public void setUserId() throws Exception {
        Context context = InstrumentationRegistry.getTargetContext();
        Config.getInstance(context).setUserId(userId);
    }

    @Test
    public void getUserId() throws Exception {
        Context context = InstrumentationRegistry.getTargetContext();
        String id = Config.getInstance(context).getUserId();
        assertEquals(userId, id);
    }

}
  • 输出
Testing started at 1:47 ...

02/28 01:47:20: Launching ConfigTest
$ adb push D:\androidproject\LocalUnitTest\app\build\outputs\apk\debug\app-debug.apk /data/local/tmp/com.jason.localunittest
$ adb shell pm install -t -r "/data/local/tmp/com.jason.localunittest"
    pkg: /data/local/tmp/com.jason.localunittest
Success


$ adb push D:\androidproject\LocalUnitTest\app\build\outputs\apk\androidTest\debug\app-debug-androidTest.apk /data/local/tmp/com.jason.localunittest.test
$ adb shell pm install -t -r "/data/local/tmp/com.jason.localunittest.test"
    pkg: /data/local/tmp/com.jason.localunittest.test
Success


Running tests

$ adb shell am instrument -w -r   -e debug false -e class com.jason.localunittest.ConfigTest com.jason.localunittest.test/android.support.test.runner.AndroidJUnitRunner
Client not ready yet..
Started running tests
Tests ran to completion.

整合自Android自动化测试--学习浅谈系列文章

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

推荐阅读更多精彩内容