我們測試過了幾個案例,像是 測試更新標籤時如過濾Admin,結果應不出現Admin
和 測試更新標籤時如過濾Admin和Author,結果應不出現Admin和Author
。
不過,我們會發現到,我們不太可能去撰寫 removeTag()
所有的組合出來,然後每組都加上測試。這樣既大量增加測試案例的數量,又導致測試很難維護。
這時,我們導入另一個觀念:整合測試和單元測試。
簡單的說,整合測試就是我們之前所做的 測試更新標籤時如過濾Admin和Author,結果應不出現Admin和Author
這類測試。
要能成功執行這段測試,我們需要 removeTag()
和 updateUsersTags()
兩個函數進行互動,才能通過這個測試案例。
實務上根據程式碼的調整,隨著程式逐漸拆細,滿足一個功能所需的互動元件越來越多,會有很多的案例屬於這種情況。
整合測試可以實際的呈現滿足這段需求時,各個元件互動是否正確,是非常重要的一種測試方式。
但是,隨著元件越來越多,我們不太可能將所有元件互動的可能都列舉出測試案例。這時候我們可能會開始構思,是否該測試單一的元件就好。
這時候,我們就可以引入單元測試的概念了。
單元測試,也就是我們測試的對象,從一堆元件之間互動所滿足的功能,變成了針對單一個元件的功能所進行的測試。
以目前這些程式來說,我們最小的元件單位,也就是函數們。更具體來說,就是 updateUsersTags()
和 removeTag()
不考慮組合出來的功能,而是單看這些元件的話,其實 removeTag()
要滿足的是給他一堆 tag
,能夠移除不要的 tag
。 updateUsersTags()
則是要更新 tag
並執行 filter
參數內的內容。
所以,我們來寫第一個單元測試吧!
removeTag()
的單元測試首先,我們先建立 tests/kotlin/RemoveTagKtTest.kt
針對 removeTag()
我們測試看看以下幾個案例:
能正確移除標籤,不移除多餘標籤
能正確處理移除標籤不存在的狀況
能正確處理無標籤傳入的狀況
我們來寫看看 能正確移除標籤,不移除多餘標籤()
@Test
fun `能正確移除標籤,不移除多餘標籤`() {
initDatabase()
transaction {
val testTags = makeTestTags(2)
testTags[0].name = "Admin"
val filteredTag = testTags.removeTag("Admin")
Assert.assertThat(filteredTag, not(hasItem(testTags[0])))
Assert.assertThat(filteredTag, hasItem(testTags[1]))
}
}
這邊我們一樣利用 initDatabase()
和 makeTestTags()
協助我們建立測試環境。
通過測試之後,這個測試情境我們就通過了。
能正確處理移除標籤不存在的狀況()
@Test
fun `能正確處理移除標籤不存在的狀況`() {
initDatabase()
transaction {
val testTags = makeTestTags(2)
val filteredTag = testTags.removeTag("Admin")
Assert.assertThat(filteredTag, `is`(testTags))
}
}
這段邏輯很簡單,應該不會有什麼難以理解的部分。
最後,我們來寫看看 能正確處理無標籤傳入的狀況()
@Test
fun `能正確處理無標籤傳入的狀況`() {
initDatabase()
transaction {
val testTags = makeTestTags(0)
val filteredTag = testTags.removeTag("Admin")
Assert.assertThat(filteredTag, `is`(makeTestTags(0)))
}
}
撰寫之後執行看看,如果順利的話,這段測試應該也能正常通過。
這樣,針對 removeTag()
的三個情境,我們就都成功的測試過了!