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

42.2 表驅動的測試實踐

Go測試代碼的邏輯十分簡單,約束也甚少,但我們發現:上面僅有三組預置輸入數據的示例的測試代碼已顯得十分冗長,如果為測試預置的數據組數增多,測試函數本身就將變得十分龐大。并且,我們看到上述示例的測試邏輯中存在很多重復的代碼,顯得十分煩瑣。我們來嘗試對上述示例做一些改進:

// chapter8/sources/table_driven_strings_test.go
func TestCompare(t *testing.T) {
    compareTests := []struct {
        a, b string
        i    int
    }{
        {"", "", 0},
        {"a", "", 1},
        {"", "a", -1},
    }

    for _, tt := range compareTests {
        cmp := strings.Compare(tt.a, tt.b)
        if cmp != tt.i {
            t.Errorf(`want %v, but Compare(%q, %q) = %v`, tt.i, tt.a, tt.b, cmp)
        }
    }
}

在上面這個改進的示例中,我們將之前示例中重復的測試邏輯合并為一個,并將預置的輸入數據放入一個自定義結構體類型的切片中。這個示例的長度看似并沒有比之前的實例縮減多少,但它卻是一個可擴展的測試設計。如果增加輸入測試數據的組數,就像下面這樣:

// chapter8/sources/table_driven_strings_more_cases_test.go
func TestCompare(t *testing.T) {
    compareTests := []struct {
        a, b string
        i    int
    }{
        {"", "", 0},
        {"a", "", 1},
        {"", "a", -1},
        {"abc", "abc", 0},
        {"ab", "abc", -1},
        {"abc", "ab", 1},
        {"x", "ab", 1},
        {"ab", "x", -1},
        {"x", "a", 1},
        {"b", "x", -1},
        {"abcdefgh", "abcdefgh", 0},
        {"abcdefghi", "abcdefghi", 0},
        {"abcdefghi", "abcdefghj", -1},
    }

    for _, tt := range compareTests {
        cmp := strings.Compare(tt.a, tt.b)
        if cmp != tt.i {
            t.Errorf(`want %v, but Compare(%q, %q) = %v`, tt.i, tt.a, tt.b, cmp)
        }
    }
}

可以看到,無須改動后面的測試邏輯,只需在切片中增加數據條目即可。在這種測試設計中,這個自定義結構體類型的切片(上述示例中的compareTests)就是一個(自定義結構體類型的字段就是列),而基于這個數據表的測試設計和實現則被稱為“表驅動的測試”

主站蜘蛛池模板: 玉林市| 高邮市| 广南县| 焦作市| 水富县| 崇阳县| 长春市| 彰化市| 衡山县| 昭苏县| 无为县| 龙陵县| 清镇市| 澎湖县| 金昌市| 谷城县| 三江| 延川县| 武冈市| 定兴县| 库伦旗| 镇原县| 玉田县| 镇安县| 嘉祥县| 邓州市| 宜兴市| 钟祥市| 河西区| 昭苏县| 花垣县| 三亚市| 犍为县| 婺源县| 射洪县| 宜黄县| 宝山区| 武冈市| 邛崃市| 怀宁县| 宁强县|