官术网_书友最值得收藏!

41.2 xUnit家族模式

在Java、Python、C#等主流編程語言中,測試代碼的組織形式深受由極限編程倡導(dǎo)者Kent Beck和Erich Gamma建立的xUnit家族測試框架(如JUnit、PyUnit等)的影響。

使用了xUnit家族單元測試框架的典型測試代碼組織形式(這里稱為xUnit家族模式)如圖41-1所示。

015-01

圖41-1 xUnit家族單元測試代碼組織形式

我們看到這種測試代碼組織形式主要有測試套件(Test Suite)和測試用例(Test Case)兩個層級。一個測試工程(Test Project)由若干個測試套件組成,而每個測試套件又包含多個測試用例。

在Go 1.7版本之前,使用Go原生工具和標(biāo)準(zhǔn)庫是無法按照上述形式組織測試代碼的。但Go 1.7中加入的對subtest的支持讓我們在Go中也可以使用上面這種方式組織Go測試代碼。還以上面標(biāo)準(zhǔn)庫strings包的測試代碼為例,這里將其部分測試代碼的組織形式改造一下(代碼較多,這里僅摘錄能體現(xiàn)代碼組織形式的必要代碼):

// chapter8/sources/strings-test-demo/compare_test.go
package strings_test

...

func testCompare(t *testing.T) {
    ...
}

func testCompareIdenticalString(t *testing.T) {
    ...
}

func testCompareStrings(t *testing.T) {
    ...
}

func TestCompare(t *testing.T) {
    t.Run("Compare", testCompare)
    t.Run("CompareString", testCompareStrings)
    t.Run("CompareIdenticalString", testCompareIdenticalString)
}

// chapter8/sources/strings-test-demo/builder_test.go
package strings_test

...

func testBuilder(t *testing.T) {
    ...
}
func testBuilderString(t *testing.T) {
    ...
}
func testBuilderReset(t *testing.T) {
    ...
}
func testBuilderGrow(t *testing.T) {
    ...
}

func TestBuilder(t *testing.T) {
    t.Run("TestBuilder", testBuilder)
    t.Run("TestBuilderString", testBuilderString)
    t.Run("TestBuilderReset", testBuilderReset)
    t.Run("TestBuilderGrow", testBuilderGrow)
}

改造前后測試代碼的組織結(jié)構(gòu)對比如圖41-2所示。

015-01

圖41-2 strings測試代碼組織形式對比

從圖41-2中我們看到,改造后的名字形如TestXxx的測試函數(shù)對應(yīng)著測試套件,一般針對被測包的一個導(dǎo)出函數(shù)或方法的所有測試都放入一個測試套件中。平鋪模式下的測試函數(shù)TestXxx都改名為testXxx,并作為測試套件對應(yīng)的測試函數(shù)內(nèi)部的子測試(subtest)。上面的代碼中,原先的TestBuilderString變?yōu)榱藅estBuilderString。這樣的一個子測試等價于一個測試用例。通過對比,我們看到,僅通過查看測試套件內(nèi)的子測試(測試用例)即可全面了解到究竟對被測函數(shù)/方法進行了哪些測試。僅僅增加了一個層次,測試代碼的組織就更加清晰了。

運行一下改造后的測試:

$go test -v .
=== RUN   TestBuilder
=== RUN   TestBuilder/TestBuilder
=== RUN   TestBuilder/TestBuilderString
=== RUN   TestBuilder/TestBuilderReset
=== RUN   TestBuilder/TestBuilderGrow
--- PASS: TestBuilder (0.00s)
    --- PASS: TestBuilder/TestBuilder (0.00s)
    --- PASS: TestBuilder/TestBuilderString (0.00s)
    --- PASS: TestBuilder/TestBuilderReset (0.00s)
    --- PASS: TestBuilder/TestBuilderGrow (0.00s)
=== RUN   TestCompare
=== RUN   TestCompare/Compare
=== RUN   TestCompare/CompareString
=== RUN   TestCompare/CompareIdenticalString
--- PASS: TestCompare (0.44s)
    --- PASS: TestCompare/Compare (0.00s)
    --- PASS: TestCompare/CompareString (0.44s)
    --- PASS: TestCompare/CompareIdenticalString (0.00s)
PASS
ok         strings-test-demo     0.446s

我們看到go test的輸出也更有層次感了,我們可以一眼看出對哪些函數(shù)/方法進行了測試、這些被測對象對應(yīng)的測試套件以及套件中的每個測試用例。

主站蜘蛛池模板: 奉化市| 化德县| 大名县| 台湾省| 张家界市| 天祝| 特克斯县| 阿荣旗| 陈巴尔虎旗| 侯马市| 库伦旗| 民和| 布拖县| 武隆县| 宁陵县| 崇明县| 保康县| 禹州市| 兰州市| 海丰县| 万盛区| 通渭县| 宝兴县| 罗甸县| 科技| 东辽县| 九龙县| 基隆市| 宁城县| 溧阳市| 井陉县| 邵东县| 天津市| 安龙县| 洛川县| 北辰区| 高尔夫| 论坛| 牙克石市| 巴彦淖尔市| 宜阳县|