這一篇將對JUnit來做更進一步的介紹。
JUnit是一個用在Java的單元測試框架,當然在Kotlin也可以在JUnit的框架來寫測試。
你可以參考我的出版書,內容更完整。
Android TDD 測試驅動開發:從 UnitTest、TDD 到 DevOps 實踐
天瓏網路書店連結:https://www.tenlong.com.tw/products/9789864344901
目前我們用到了JUnit的這兩個功能:@Test、Assert.assertEqual
@Test:用來表達是一個測試的function
Assert.assertEquals(expected, actual):驗證expected、actual 是否相同
常用的Annotation:
@Before : 在每一個測試之前執行。
@After : 在每一個測試之後執行。
@BeforeClass : 在這個類別開始執行第一個測試之前。
@AfterClass : 在這個類別全部測試完執行。
測試的程式碼也是需要重構的。延續上一篇的測試,我們應將測試程式應視為Production Code的一部份,兩者一樣重要。
下方程式碼的3個測試,可以發現每個測試都會先做val math = Math()。
@Test
fun addTest() {
val math = Math()
val actual = math.add(1, 2)
val expected = 3
Assert.assertEquals(expected, actual)
}
@Test
fun testNumber1LessNumber2_minimumShouldBeNumber1() {
val math = Math()
val expected = math.minimum(1,3)
val actual = 1
Assert.assertEquals(expected, actual)
}
@Test
fun testNumber2LessNumber1_minimumShouldBeNumber2() {
val math = Math()
val expected = math.minimum(3,1)
val actual = 1
Assert.assertEquals(expected, actual)
}
既然這樣,我們何不讓每個測試都先跑這一段,
新增一個方法setup()並加上@Before的annotation,讓每個測試之前都要執行此方法。
這樣就能確保每次測試之前 math都會重新再初始化Math()一次。
這樣是不是就讓程式碼再簡單了一點。減少了重覆的部分。
class MathTest {
lateinit var math: Math
@Before
fun setup(){
math = Math()
}
@Test
fun addTest() {
val actual = math.add(1, 2)
val expected = 3
Assert.assertEquals(expected, actual)
}
@Test
fun testNumber1LessNumber2_minimumShouldBeNumber1() {
val expected = math.minimum(1,3)
val actual = 1
Assert.assertEquals(expected, actual)
}
@Test
fun testNumber2LessNumber1_minimumShouldBeNumber2() {
val expected = math.minimum(3,1)
val actual = 1
Assert.assertEquals(expected, actual)
}
}
請記得@Before是在每個測試之前都會執行,跟下方直接在測試類的Property做初始化的作法是不一樣的。
class MathTest {
var math = Math()
}
@Before 雖然好用,但需要注意以下幾點
assertEquals 判斷2個物件是否相等
assertNotEquals 判斷2個物件是否不為相等
assertTrue 驗證是否為真
assertNull 驗證物件是否為null
assertNotNull 驗證物件是否不為null
assertArrayEquals 驗證陣列是否相同
正確
Assert.assertEquals(string1, string2)
錯誤
Assert.assertTrue(string1 == string2)
正確
assertTrue(condition)
錯誤
assertFalse(!condition)
正確
assertTrue(someBoolean)
錯誤
Assert.assertEquals(true, someBoolean)
正確
assertNull(someNull)
錯誤
Assert.assertEquals(null, someNull)
Ignore用來表示先忽略這個測試。有時程式還沒寫好時,可以暫時加上Ignore忽略。
@Ignore("not implemented yet")
fun test() {
}
範例下載:
https://github.com/evanchen76/TDD_JunitSample
參考
JUnit https://junit.org/junit4/
單元測試的藝術一書 8.2.3 具可維護性的設計來使用Setup方法
在測試類別,按下command + N,可快速產生SetUp Function與TearDown Function。
Android TDD 測試驅動開發:從 UnitTest、TDD 到 DevOps 實踐