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的順序執行。
總結
今天就到此為止,東西不難,但是知識點還是挺多的,都需要我們慢慢消化,我也是用的時候,偶爾還得複習一遍。
聽同事說今天立冬,啥也別說了,先填飽我的肚子把,各位拜拜~