测试表

在核心测试逻辑重复时,将表驱动测试与子测试一起使用,以避免重复代码。

BadGood
  1. // func TestSplitHostPort(t testing.T)
  2. host, port, err := net.SplitHostPort("192.0.2.0:8000")
  3. require.NoError(t, err)
  4. assert.Equal(t, "192.0.2.0", host)
  5. assert.Equal(t, "8000", port)
  6. host, port, err = net.SplitHostPort("192.0.2.0:http")
  7. require.NoError(t, err)
  8. assert.Equal(t, "192.0.2.0", host)
  9. assert.Equal(t, "http", port)
  10. host, port, err = net.SplitHostPort(":8000")
  11. require.NoError(t, err)
  12. assert.Equal(t, "", host)
  13. assert.Equal(t, "8000", port)
  14. host, port, err = net.SplitHostPort("1:8")
  15. require.NoError(t, err)
  16. assert.Equal(t, "1", host)
  17. assert.Equal(t, "8", port)
  1. // func TestSplitHostPort(t testing.T)
  2. tests := []struct{
  3. give string
  4. wantHost string
  5. wantPort string
  6. }{
  7. {
  8. give: "192.0.2.0:8000",
  9. wantHost: "192.0.2.0",
  10. wantPort: "8000",
  11. },
  12. {
  13. give: "192.0.2.0:http",
  14. wantHost: "192.0.2.0",
  15. wantPort: "http",
  16. },
  17. {
  18. give: ":8000",
  19. wantHost: "",
  20. wantPort: "8000",
  21. },
  22. {
  23. give: "1:8",
  24. wantHost: "1",
  25. wantPort: "8",
  26. },
  27. }
  28. for _, tt := range tests {
  29. t.Run(tt.give, func(t *testing.T) {
  30. host, port, err := net.SplitHostPort(tt.give)
  31. require.NoError(t, err)
  32. assert.Equal(t, tt.wantHost, host)
  33. assert.Equal(t, tt.wantPort, port)
  34. })
  35. }

测试表使得向错误消息注入上下文信息,减少重复的逻辑,添加新的测试用例变得更加容易。

我们遵循这样的约定:将结构体切片称为 tests。 每个测试用例称为 tt 。此外,我们鼓励使用 give 和 want 前缀说明每个测试用例的输入和输出值。

  1. tests := []struct{
  2. give string
  3. wantHost string
  4. wantPort string
  5. }{
  6. // ...
  7. }
  8. for _, tt := range tests {
  9. // ...
  10. }