Files
OpenFlare/.agents/skills/go-testing/references/VALIDATION-APIS.md
T
2026-08-04 11:40:32 +08:00

3.2 KiB
Raw Blame History

可扩展验证 API

设计可重用测试验证函数的详细参考,调用者可以将其用于验收测试。来源:Google Go Style Guide(最佳实践)。


*test 包导出模式

当你拥有一个由他人实现的接口时,在配套的 *test 包中导出一个验证函数。这使实现者无需复制你的测试逻辑即可验证正确性。

// Package storagetest 为 storage.Backend 提供验收测试。
package storagetest

// Verify 对任何 storage.Backend 运行验证套件。
// 返回描述第一个违规行为的错误,成功时返回 nil。
func Verify(b storage.Backend) error {
    if err := verifyRoundTrip(b); err != nil {
        return fmt.Errorf("round-trip: %w", err)
    }
    if err := verifyNotFound(b); err != nil {
        return fmt.Errorf("not-found: %w", err)
    }
    return nil
}

调用者编写一个薄测试来接入他们的实现:

func TestMyBackend(t *testing.T) {
    b := mybackend.New(t)
    if err := storagetest.Verify(b); err != nil {
        t.Errorf("MyBackend failed acceptance: %v", err)
    }
}

设计可扩展的验证函数

返回错误,而非 *testing.T 失败。 这使验证函数可作为普通 Go 函数使用 — 调用者决定违规是 t.Error 还是 t.Fatal。

// 好:返回错误 — 调用者控制测试流程
func ExercisePlayer(b *chess.Board, p chess.Player) error {
    move := p.Move()
    if putsOwnKingIntoCheck(b, move) {
        return &IllegalMoveError{Move: move, Reason: "puts own king in check"}
    }
    return nil
}

// 不好:调用 t.Fatal — 调用者失去控制
func ExercisePlayer(t *testing.T, b *chess.Board, p chess.Player) {
    t.Helper()
    move := p.Move()
    if putsOwnKingIntoCheck(b, move) {
        t.Fatalf("illegal move: %v puts own king in check", move)
    }
}

在需要丰富诊断信息时使用自定义错误类型:

type IllegalMoveError struct {
    Move   chess.Move
    Reason string
}

func (e *IllegalMoveError) Error() string {
    return fmt.Sprintf("illegal move %v: %s", e.Move, e.Reason)
}

何时使用验证 API vs 简单辅助函数

场景 使用方式
你拥有的接口,由他人实现 *test 包中的验证 API
同一包中跨测试共享设置 使用 t.Helper() 的测试辅助函数
在 2-3 个测试中重用的复杂断言 返回 error 或 bool 的辅助函数
一次性的设置或比较 内联测试代码

验证 API 在以下场景值得额外的包:

  • 多个外部包将实现你的接口
  • 契约有容易被忽略的非显而易见的不变量
  • 你想为"正确行为"提供单一事实来源

简单辅助函数 在以下场景更好:

  • 辅助函数是直接的设置或比较函数
  • 重用是偶然的,不是已发布契约的一部分

命名约定

使用表示范围的动词命名函数:Verify、Exercise、RunConformance。接受被测接口作为参数 — 绝不在验证包内部构造实现。

包 函数 用途
storagetest Verify 验证 storage.Backend
chesstest ExercisePlayer 验证 chess.Player
cachetest RunConformance cache.Cache 的完整一致性套件