一、前言

  很多開發(fā)不寫單測(cè),可能是沒有意識(shí)到單測(cè)的重要性,或者懶得寫,這里單測(cè)的重要性就不多說了。還有一些同學(xué)寫單測(cè),但是基本上等于沒寫,比如像下面這種單測(cè)代碼:

  @Test

  public void testSave() {

  ItemClassesForm form = new ItemClassesForm();

  form.setName("xx測(cè)試分類");

  form.setParentId(0L);

  form.setSortOrder(0);

  Result result = itemClassesController.save(form);

  System.out.println(result);

  }

  問題比代碼行數(shù)多得多。具體有什么問題這里先不挑明,等大家看完下面的要求應(yīng)該就明白了。

  二、原則

  1、單元測(cè)試應(yīng)該是自動(dòng)化的

  這一項(xiàng)含有的要求很多很多,我覺得最基本的一點(diǎn)就是測(cè)試結(jié)果的成功與否不需要人肉來判斷。如果你還在觀察用System.out.println來打印出的結(jié)果來判斷是否成功,那估計(jì)這個(gè)用例也就是第一次有點(diǎn)用。如果有大量的測(cè)試用例要跑,靠人肉觀察輸出是不可能的。最簡(jiǎn)單的就是使用Assert,Junit和TestNG都有提供。

  2、單元測(cè)試必須充分全面

  單元測(cè)試其實(shí)是白盒測(cè)試,開發(fā)知道自己的代碼邏輯,所以要盡可能地測(cè)試多個(gè)邏輯分支或者執(zhí)行路徑。舉幾個(gè)例子

  查詢接口如果支持批量查詢,最好測(cè)一下傳入單個(gè)參數(shù)或者多個(gè)參數(shù)這兩個(gè)場(chǎng)景

  查詢接口如果有緩存,最好測(cè)一下緩存不命中和緩存命中兩個(gè)情況

  查詢接口如果支持多個(gè)查詢條件,最好把每個(gè)條件都覆蓋一下

  更新接口如果有冪等邏輯,需要重復(fù)調(diào)用測(cè)試一下冪等是否生效

  這些都是基礎(chǔ)的要求,還有一些場(chǎng)景要求比較嚴(yán)格,需要覆蓋異常情況,比如對(duì)外的OpenAPI,需要測(cè)試不同條件下返回的錯(cuò)誤碼是否符合預(yù)期。

  3、單元測(cè)試用例應(yīng)該是可重復(fù)執(zhí)行的

  在不修改代碼的情況下,單測(cè)用例每次跑的結(jié)果必須是一樣的。一般來說這個(gè)對(duì)單測(cè)的數(shù)據(jù)提出了要求,不能使用固定的測(cè)試數(shù)據(jù),比如某個(gè)創(chuàng)建接口要求資源名稱不能重復(fù),那么測(cè)試這個(gè)創(chuàng)建接口的代碼如果使用固定的名稱,那么只能是第一次跑會(huì)成功,后面都會(huì)失敗。一個(gè)簡(jiǎn)單的辦法是使用生成的數(shù)據(jù),保證每次不重復(fù)。

  4、單元測(cè)試應(yīng)該是獨(dú)立的

  這一條其實(shí)包含了下面2個(gè)要求:

  測(cè)試用例之間不能互相影響

  測(cè)試數(shù)據(jù)不能污染測(cè)試環(huán)境正常的數(shù)據(jù)

  有些比較大的公司,可能會(huì)使用獨(dú)立的單元測(cè)試庫,來保證不影響測(cè)試環(huán)境。當(dāng)然也可以采取其他方法來做到這一點(diǎn)

  5、單元測(cè)試應(yīng)該是穩(wěn)定的

  為了盡量不受環(huán)境影響,如果用例所測(cè)試的邏輯需要依賴外部接口,可以通過mock機(jī)制來mock掉這些接口,返回預(yù)期的數(shù)據(jù)。

  關(guān)于單元測(cè)試方面需要注意的事項(xiàng)還有很多,但是看到示例中的單元測(cè)試,我覺得還是先做到上面提到的這幾點(diǎn)吧