Android單元測試的利器:Juint(三):Juint的詳細(xì)用法(上)

前言

這幾天正在成都出差,欣賞著成都的妹紙。

當(dāng)我開始寫這篇的時(shí)候是上周五,沒想到這么快就星期二了,東西越寫越多,為了保持文章盡量短小精悍,Juint的詳細(xì)用法就分成多篇來寫把,具體能寫幾篇我也不清楚...

正文

現(xiàn)在我們看是介紹Junit的用法,如果你想看看官方的介紹,可以訪問http://junit.org/junit4/

Assertions(斷言)

斷言我們之前已經(jīng)在demo中使用過了,他的作用就是明確我們期望發(fā)生的情況,如果不滿足就會(huì)報(bào)錯(cuò),就是一種突然成為上帝的感覺,不符合條件的情況我們就不允許發(fā)生。

Junit中斷言有好幾種,從字面我們就可以知道他們的用途,例如

assertArrayEquals:斷言兩個(gè)數(shù)組是否相等
assertEquals:斷言字符串是否相等
assertTrue:斷言判斷為true
assertNotNull:斷言不為空
assertSame:斷言相同

他們還有相反的斷言,例如assertEquals,對應(yīng)就有assertNotEquals,這里就不全都列舉出來了。

斷言最多有三個(gè)參數(shù):

String reason: 描述要測試的原因,此參數(shù)可以省略
T actual:要判斷的參數(shù)
T matcher:對比的參數(shù)

其中稍微復(fù)雜一點(diǎn)的assertThat,他相當(dāng)于上面列舉的斷言的升級版,他更加靈活,接下來我們舉一個(gè)例子:

int x = 3;
assertThat("assertThat good", "good", is("good"));
assertEquals("assertEquals good", "good", "good");
assertThat(x, is(3));

上面的代碼中,我們通過assertThat,assertEquals都去判斷同一個(gè)字符串是否相等,第三個(gè)斷言是判斷整型是否相等。

運(yùn)行之后沒有報(bào)錯(cuò),說明assertThat,assertEquals都測試通過了,這兩種用法得到的結(jié)果是相同的。

assertThat只能判斷相同類型,例如要判斷的參數(shù)為int型,對比的參數(shù)也只能是int型。對比的參數(shù)要使用Matcher參數(shù),類似于一個(gè)判斷語句,比如的有:

is():相當(dāng)于 “是” 的意思
not():相當(dāng)于 “不是的意思”

ok,以上就是斷言的用法,通常我們沒有必要使用assertThat,其他的斷言幾乎可以滿足我們所有的需求,但是我們?nèi)匀灰斡浰挠梅ā?/p>

Test Runners

我沒想到一個(gè)特別合適的詞來形容Test Runners的作用,所以多說幾句:

Test Runners 是具有特殊功能的執(zhí)行測試用例的通道,也可以理解為測試的執(zhí)行者,例如可以同時(shí)運(yùn)行多個(gè)測試用例,也可以具有這個(gè)測試執(zhí)行者特有的功能。

用法1

/**
 *      Test Runner 示例代碼
 */
public class TestRunnerDemo {
    @Test
    public void runnerTest(){
        org.junit.runner.JUnitCore.runClasses(ExampleUnitTest.class, StudentTest.class);
    }
}

我們可以通過org.junit.runner.JUnitCore.runClasses()方法來同時(shí)運(yùn)行多個(gè)測試class文件,里面的參數(shù)個(gè)數(shù)是隨意的,例如示例代碼中按照順序運(yùn)行了ExampleUnitTest.class和StudentTest.class。

用法2

/**
 *      Test Runner 實(shí)例代碼2
 */
@RunWith(Suite.class)
// 綁定的測試用例集合
@Suite.SuiteClasses({ExampleUnitTest.class, StudentTest.class})
public class TestRunnerDemo2 {
}

通過注解@RunWith與其他測試用例進(jìn)行綁定,然后@Suite.SuiteClasses({ExampleUnitTest.class, StudentTest.class})來設(shè)置綁定的測試用例的集合,當(dāng)運(yùn)行這個(gè)測試用例的時(shí)候,綁定的集合也會(huì)運(yùn)行。

用法3

package com.lzp.unittestdemo.testrunner;

import com.lzp.unittestdemo.Utils;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

import java.util.Arrays;
import java.util.Collection;

/**
 * <p>
 * Test Runner 示例代碼3
 */
@RunWith(Parameterized.class)
public class TestRunnerDemo3 {

    /**
     * name可以用來描述這個(gè)測試的信息
     * 其中{index}表示當(dāng)前的索引值,因?yàn)閳?zhí)行的時(shí)候會(huì)遍歷集合
     * {0} 表示參數(shù)鍵值對的第一個(gè)位置
     * {1} 表示參數(shù)鍵值對的第二個(gè)位置,坐標(biāo)以此類推
     */
    @Parameters()
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][]{
                {0, 0}, {1, 1}, {2, 1}, {3, 2}, {4, 3}, {5, 5}, {6, 8}
        });
    }

    private int fInput;

    private int fExpected;

    /**
     * 這里模擬了創(chuàng)建對象的過程,Juit會(huì)自動(dòng)把@Parameters里面的數(shù)據(jù)集合,按照順序依次放入構(gòu)造方法中
     * */
    public TestRunnerDemo3(int input, int expected) {
        fInput = input;
        fExpected = expected;
        System.out.println(input + " :" + expected);
    }

    /**
     * 測試方法,通過Assert.assertEquals判斷參數(shù)是否符合我們的期望
     * */
    @Test
    public void test() {
        Assert.assertEquals(fExpected, Utils.compute(fInput));
    }
}

使用@RunWith(Parameterized.class)會(huì)稍微復(fù)雜一點(diǎn),但是使用起來非常的方便,我們可以創(chuàng)建很多個(gè)相同類型的對象,然后通過測試方法對屬性進(jìn)行操作,驗(yàn)證我們創(chuàng)建的類是否符合我們的期望。

用法4

@RunWith(Categories.class)
// 為這個(gè)測試添加分類
@Category(MyCategory.class)
// 綁定的測試類集合
@Suite.SuiteClasses( { TestRunnerDemo.class, TestRunnerDemo3.class })
// 交集,運(yùn)行SuiteClasses中與自己分類相同的測試類
//@Categories.IncludeCategory(MyCategory.class)
// 除去交集,運(yùn)行SuiteClasses中與自己分類不同的測試類
@Categories.ExcludeCategory(MyCategory.class)
public class TestRunnerDemo4 {
    @Test
    public void test(){
        assertEquals(4, 2 + 2);
    }
}

使用@Category可以對測試類添加分類,然后和@Suit結(jié)合使用,可以同時(shí)運(yùn)行相同分類或不同分類的測試,算是上一種用法的升級版。

用法5

有時(shí)候我們會(huì)把測試方法卸載內(nèi)部類中,這個(gè)時(shí)候我們需要使用@RunWith(Enclosed.class),這樣可以運(yùn)行內(nèi)部類的測試方法, 這里貼出官方的demo連接:https://github.com/junit-team/junit4/wiki/%27Enclosed%27-test-runner-example,大家可以學(xué)習(xí)一下。

用法6

使用第三方的Test Runner:


這里寫圖片描述

這是官網(wǎng)的舉例,之后我們會(huì)用到MockitoJUnitRunner,其他的大家可以自己去百度學(xué)習(xí)一下如何使用。

Test execution order(測試運(yùn)行順序)

有時(shí)候我們需要一些測試按照我們期望的順序進(jìn)行,例如對同一個(gè)屬性按照某個(gè)順序多次加工,我們想要看到最終的結(jié)果,這種情況下,我們可以使用@FixMethodOrder()。

@FixMethodOrder() 指明類中測試方法的運(yùn)行順序。

MethodSorters.DEFAULT:不可預(yù)測的順序,可以認(rèn)為是隨機(jī)的順序。
MethodSorters.JVM:按照J(rèn)VM編譯的順序,順序也可能發(fā)生變化
MethodSorters.NAME_ASCENDING:按照方法的命名的順序,也就是按照字母的順序,從a到z。

@FixMethodOrder(MethodSorters.DEFAULT)
public class TestMethodOrder {

    @Test
    public void testA() {
        System.out.println("first");
    }
    
    @Test
    public void testC() {
        System.out.println("third");
    }

    @Test
    public void testB() {
        System.out.println("second");
    }

    
}

上面是官方的demo,為了讓測試結(jié)果更明顯,我把testC()移動(dòng)到了第一位,看一下運(yùn)行結(jié)果:

這里寫圖片描述

從截圖上看,確實(shí)是按照A、B、C的順序執(zhí)行。

總結(jié)

今天就到此為止,東西不難,但是知識點(diǎn)還是挺多的,都需要我們慢慢消化,我也是用的時(shí)候,偶爾還得復(fù)習(xí)一遍。

聽同事說今天立冬,啥也別說了,先填飽我的肚子把,各位拜拜~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容