【譯】如何寫一手漂亮的測試程式碼

tynam-yang發表於2021-02-07

在編寫 Junit 測試時,我採用了同一套格式。如此,對於測試用例我就可以遵循這套格式進行編寫和閱讀,使所有的測試都整體劃一。這種格式模板可以幫助我更快的編寫測試,提高工作效率。今天我就與大家分享我的這套格式模板。

(譯者評:與我在測試建設原則中提出的繼承原則相同,都是在進行一項測試工作之前,將公共的進行提取,統一格式模板,然後在以後的測試活動中都繼承這套模板開展。)

檔案格式

首先,在專案的測試包下新建一個測試檔案/測試類,並且建立測試方法。在編寫測試檔案/測試類時,所有的測試檔案/測試類都以 Test 結束,這樣會容易理解其是一個測試檔案/測試類,也方便後期維護時檢視,編輯。例如一個名字為 SomeService 的類就會有一個名為 SomeServiceTest 對應的測試類。

(譯者評:這是一個很好的習慣,在專案測試中可以考慮作為一種規定。就是開發在程式中寫了一個 SomeService 類,那麼在測試 SomeService 類時檔名就需要是 SomeServiceTest ,以 類名 + Test 的形式進行命名測試類。)

然後,給測試取一個容易識別,區分,好聽的名字,筆者個人比較喜歡省略單詞 test,因為就是在測試類中進行的,繼續在名字中新增 test 看起來就有點累贅。對於測試名字需要從名字中讀取出所測的內容,這樣我們就可以更好的對每一個測試進行區分。

public SomeServiceTest{
    @Test
    public void sortByPopularVoteDesc() {

    }
    @Test
    public void sortByPopularVoteAsc() {

    }
}

(譯者評:對於測試名,取一個易於理解的還是比較支援的,見名知意。但對於省略單詞 test,譯者理解的是一般情況下可以省略,但是某些必要的場景還是希望新增。)

大綱

接下來,筆者會在測試方法中寫入一些模板,這種模板是我在寫所有測試中都會使用的模板。首先在測試方法中設定了一個預置條件 setup,然後對方法進行測試 test,最後進行斷言 assert/validate,透過斷言來確保與期望結果一致。

public TestClass{
    @Test
    public void sortByPopularVote() {
      // setup
      // test
      // assert/validate
    }
}

上面程式碼中部分內容的含義:

  • setup: 測試預製條件寫的地方。
  • test: 對方法進行測試地方。
  • assert/validate: 此處寫斷言。

(譯者評:作者在此寫的並不是很全。有準備條件,但是沒有銷燬條件。我們都知道,在進行自動化測試時非常重要的一個步驟就是資料復原。如果測試後資料沒有復原,將會影響一次的執行。所以在上面三個過程後,還應該存在一個銷燬條件 teardown,雖然可能 teardown 不是一個必須項。所以一共應該有四個步驟,setup、test、assert/validate、teardown。)

(譯者評:上面寫的範圍有點小。不僅在測試類中需要有這樣的設定,在測試類層面、測試檔案層面也需要 setup、test、assert/validate、teardown 四個步驟。)

預製條件

最後,我簡單的填充了一下空白。如果預置條件和所有其他測試的預製條件相似,筆者會將此邏輯抽象為 @Before 函式。每個測試之前都會執行此函式。如果多個測試,但不是所有測試,之間需要設定一個預製條件,那麼就將其設定為一個私有函式進行封裝。對於一般的測試,使用這兩種方法設定預製條件都可以提高程式碼的複用性。如果需要改變測試的預製條件,那麼只需要對一個地方進行改變便可以達到目的。在進行測試重構時這將是非常實用的。

public TestClass{
  private List<SortableObj> expected;
  private final SortableObj first = new SortableObj();
  private final SortableObj second = new SortableObj();
  private final SortableObj third = new SortableObj();
  private final SortableObj fourth = new SortableObj();

   @Before
   public void before{
     // some decoration on objects
     // ...
     expected = Arrays.asList(first, second, third, fourth);
   }

    @Test
    public void sortByPopularVote() {
      // setup
      List<SortableObj> actual = Arrays.asList(fourth, third, first, second);
      // test
      Collections.sort(actual);
      // assert/validate
      assertThat(actual).isEqualTo(expected);
    }
}

測試命名

在進行預期結果和實際結果命名時,使用 expected 和 actual 是非常有效的。 使用這兩個關鍵字寫斷言也非常易於閱讀。actual 是實際結果,expected 是預期結果,使用這兩個結果進行對比。

  • expected :這是預期結果,即是希望的結果是什麼。預期結果可能有多條,在寫的時候請按照一定的順序進行。
  • actual :測試執行後,實際輸出的結果。 命名是對一個事物進行設計或選擇的名字,特別是在科學或其他學科中。在軟體開發和測試中,涉及到 API、響應結果、變數、函式、文件名稱。 (譯者評:四個字,見名知意。)

結論

使用這個格式模板進行測試,可以提高測試效率,使程式碼更易維護。

(譯者評:全文所說的檔案格式、測試順序、斷言命名、預期結果排序還是值的學習的,特別對於沒有經歷過痛苦的維護程式碼的人員來說非常又必要。就是內容太少,總結的太少。)

原文:https://dev.to/ninan_phillip/how-to-write-great-tests-4719

相關文章