[design draft] testcase for your library

上次跟妳講的幾個問題,我把總結(jié)成文檔了,妳有空思考一下。

庫底層 api 的實現(xiàn)決定了庫的使用方法。
testcase 需要模擬用戶使用。

若干因素會影響到使用者
  1. 同步/異步編程模型。
    已實現(xiàn)同步,現(xiàn)有所有代碼基于同步編程模型開發(fā),不需要注冊回調(diào)函數(shù)。異步方式的測試代碼其實和同步的大體相同,只不過調(diào)用、使用方式有所區(qū)別。沒必要寫兩份差不多的代碼。

妳思考一下,如何通過采用統(tǒng)一的 testcase,測試async/sync的api

若干因素會影響到 testcase
  1. 測試邏輯
    比如如下是針對 get 的單元測試,如果它通過,說明 get 命令確實可用(關(guān)于 get:https://redis.io/commands/get)。
test("get"); {
  c.set(foo, bar);
  ASSERT_EQUAL(c.get(foo), bar);
}

比如如下是針對 set 的單元測試,如果它通過,說明 set 命令確實可用(關(guān)于 set:https://redis.io/commands/set)。

test("set"); {
  c.set(foo, bar);
  ASSERT_EQUAL(c.get(foo), bar);
}

但是,
get 的 UT 通過的前提條件是 “set 確實能設(shè)置一個 key 的值”(即 set 的 UT 通過)。
set 的 UT 通過的前提條件是 “get 確實能取得一個 key 的值”(即 get 的 UT 通過)。
由此可以看出,各個api的UT之間是存在依賴關(guān)系的,無法保證這些測試用例從邏輯上完全正確。

以上是實際的一種情況。

如下抽象一下:

logic dependency:

T(A) -> T(B)
T(B) -> T(C)

testcase:

TestA(...);
TestB(...);
TestC(...);

如果
B 的 UT 通過的前提是 A 的 UT 通過。
C 的 UT 通過的前提是 B 的 UT 通過。
就可以通過測試函數(shù)的調(diào)用順序解決問題,A 放在 B 之前,如果 A 不通過,則直接退出,不會執(zhí)行到 B,如此等等。。如果程序執(zhí)行完,則說明 A, B, C 都通過了。
現(xiàn)在的代碼有些是使用這種方法寫的,但是 api 之間的耦合多了,就沒法這么寫了。

妳思考一下,怎么保證 testcase 從邏輯上是完備的。

  1. api太多
    如果這些 testcase 全部都手動寫,確實可以實現(xiàn)測試需求,但是隨著 api 的變化,會導(dǎo)致 testcase 每次都需要改動。其實,testcase 是由api實現(xiàn)決定并由其預(yù)期的,所以理論上是能做到自動生成。這樣作為庫的開發(fā)者,只需要實現(xiàn)底層功能和生成 testcase 的代碼即可,可做到“只改實現(xiàn)和預(yù)期,不改 testcase”。
    妳思考一下,如何做到從預(yù)期出發(fā),最終不需要寫 testcase,讓程序自己生成 testcase。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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