1. 程式人生 > >Android單元測試的利器:Juint(三):Juint的詳細用法(上)

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

前言

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

當我開始寫這篇的時候是上週五,沒想到這麼快就星期二了,東西越寫越多,為了保持文章儘量短小精悍,Juint的詳細用法就分成多篇來寫把,具體能寫幾篇我也不清楚…

正文

Assertions(斷言)

斷言我們之前已經在demo中使用過了,他的作用就是明確我們期望發生的情況,如果不滿足就會報錯,就是一種突然成為上帝的感覺,不符合條件的情況我們就不允許發生。

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

assertArrayEquals:斷言兩個陣列是否相等
assertEquals:斷言字串是否相等
assertTrue:斷言判斷為true
assertNotNull:斷言不為空
assertSame:斷言相同

他們還有相反的斷言,例如assertEquals,對應就有assertNotEquals,這裡就不全都列舉出來了。

斷言最多有三個引數:

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

其中稍微複雜一點的assertThat,他相當於上面列舉的斷言的升級版,他更加靈活,接下來我們舉一個例子:

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

上面的程式碼中,我們通過assertThat,assertEquals都去判斷同一個字串是否相等,第三個斷言是判斷整型是否相等。

執行之後沒有報錯,說明assertThat,assertEquals都測試通過了,這兩種用法得到的結果是相同的。

assertThat只能判斷相同型別,例如要判斷的引數為int型,對比的引數也只能是int型。對比的引數要使用Matcher引數,類似於一個判斷語句,比如的有:

is():相當於 “是” 的意思
not():相當於 “不是的意思”

ok,以上就是斷言的用法,通常我們沒有必要使用assertThat,其他的斷言幾乎可以滿足我們所有的需求,但是我們仍然要牢記他的用法。

Test Runners

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

Test Runners 是具有特殊功能的執行測試用例的通道,也可以理解為測試的執行者,例如可以同時執行多個測試用例,也可以具有這個測試執行者特有的功能。

用法1

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

我們可以通過org.junit.runner.JUnitCore.runClasses()方法來同時執行多個測試class檔案,裡面的引數個數是隨意的,例如示例程式碼中按照順序運行了ExampleUnitTest.class和StudentTest.class。

用法2

/**
 *      Test Runner 例項程式碼2
 */
@RunWith(Suite.class)
// 繫結的測試用例集合
@Suite.SuiteClasses({ExampleUnitTest.class, StudentTest.class})
public class TestRunnerDemo2 {
}

通過註解@RunWith與其他測試用例進行繫結,然後@Suite.SuiteClasses({ExampleUnitTest.class, StudentTest.class})來設定繫結的測試用例的集合,當執行這個測試用例的時候,繫結的集合也會執行。

用法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可以用來描述這個測試的資訊
     * 其中{index}表示當前的索引值,因為執行的時候會遍歷集合
     * {0} 表示引數鍵值對的第一個位置
     * {1} 表示引數鍵值對的第二個位置,座標以此類推
     */
    @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;

    /**
     * 這裡模擬了建立物件的過程,Juit會自動把@Parameters裡面的資料集合,按照順序依次放入構造方法中
     * */
    public TestRunnerDemo3(int input, int expected) {
        fInput = input;
        fExpected = expected;
        System.out.println(input + " :" + expected);
    }

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

使用@RunWith(Parameterized.class)會稍微複雜一點,但是使用起來非常的方便,我們可以建立很多個相同型別的物件,然後通過測試方法對屬性進行操作,驗證我們建立的類是否符合我們的期望。

用法4

@RunWith(Categories.class)
// 為這個測試新增分類
@Category(MyCategory.class)
// 繫結的測試類集合
@Suite.SuiteClasses( { TestRunnerDemo.class, TestRunnerDemo3.class })
// 交集,執行SuiteClasses中與自己分類相同的測試類
//@Categories.IncludeCategory(MyCategory.class)
// 除去交集,執行SuiteClasses中與自己分類不同的測試類
@Categories.ExcludeCategory(MyCategory.class)
public class TestRunnerDemo4 {
    @Test
    public void test(){
        assertEquals(4, 2 + 2);
    }
}

使用@Category可以對測試類新增分類,然後和@Suit結合使用,可以同時執行相同分類或不同分類的測試,算是上一種用法的升級版。

用法5

用法6

使用第三方的Test Runner:
這裡寫圖片描述

這是官網的舉例,之後我們會用到MockitoJUnitRunner,其他的大家可以自己去百度學習一下如何使用。

Test execution order(測試執行順序)

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

@FixMethodOrder() 指明類中測試方法的執行順序。

MethodSorters.DEFAULT:不可預測的順序,可以認為是隨機的順序。
MethodSorters.JVM:按照JVM編譯的順序,順序也可能發生變化
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,為了讓測試結果更明顯,我把testC()移動到了第一位,看一下執行結果:

這裡寫圖片描述

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

總結

今天就到此為止,東西不難,但是知識點還是挺多的,都需要我們慢慢消化,我也是用的時候,偶爾還得複習一遍。

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