samber/cc-skills-golang

golang-stretchr-testify

Comprehensive guide to stretchr/testify for Golang testing.

ソースを見る

使い方

  1. インストールコマンドをコピーし、自分の環境へ導入する前にソースを確認します。
  2. 必要なツール、認証情報、対応環境を原文で確認します。
  3. 入力と成果物を指定し、出力を資料と照合します。
npx skills add https://github.com/samber/cc-skills-golang --skill golang-stretchr-testify

開始前の確認

  • 導入にはモデル契約、API枠、ファイルへのアクセス許可は含まれません。
  • スター数や導入数は活動の指標であり、独立した品質・安全性試験ではありません。
リポジトリの原文

見出し、例、コード、表、リンク、参照画像を含む原文を表示しています。

Persona: You are a Go engineer who treats tests as executable specifications. You write tests to constrain behavior and make failures self-explanatory — not to hit coverage targets.

Modes:

  • Write mode — adding new tests or mocks to a codebase.
  • Review mode — auditing existing test code for testify misuse.

stretchr/testify

testify complements Go's testing package with readable assertions, mocks, and suites. It does not replace testing — always use *testing.T as the entry point.

This skill is not exhaustive — refer to library documentation and code examples for more information:

  • For Go package docs, symbols, versions, importers, and known vulnerabilities, → See samber/cc-skills-golang@golang-pkg-go-dev skill (godig), preferred over Context7 for Go package facts.
  • To navigate this library's usage in your own code (definitions, call sites, diagnostics), → See samber/cc-skills-golang@golang-gopls skill (gopls).
  • Context7 remains a fallback for docs not indexed on pkg.go.dev.

assert vs require

Both offer identical assertions. The difference is failure behavior:

  • assert: records failure, continues — see all failures at once
  • require: calls t.FailNow() — use for preconditions where continuing would panic or mislead

Use assert.New(t) / require.New(t) for readability. Name them is and must:

go
func TestParseConfig(t *testing.T) {
    is := assert.New(t)
    must := require.New(t)

    cfg, err := ParseConfig("testdata/valid.yaml")
    must.NoError(err)    // stop if parsing fails — cfg would be nil
    must.NotNil(cfg)

    is.Equal("production", cfg.Environment)
    is.Equal(8080, cfg.Port)
    is.True(cfg.TLS.Enabled)
}

Rule: require for preconditions (setup, error checks), assert for verifications. Never mix randomly.

Core Assertions

go
is := assert.New(t)

// Equality
is.Equal(expected, actual)              // DeepEqual + exact type
is.NotEqual(unexpected, actual)
is.EqualValues(expected, actual)        // converts to common type first
is.EqualExportedValues(expected, actual)

// Nil / Bool / Emptiness
is.Nil(obj)                  is.NotNil(obj)
is.True(cond)                is.False(cond)
is.Empty(collection)         is.NotEmpty(collection)
is.Len(collection, n)

// Contains (strings, slices, map keys)
is.Contains("hello world", "world")
is.Contains([]int{1, 2, 3}, 2)
is.Contains(map[string]int{"a": 1}, "a")

// Comparison
is.Greater(actual, threshold)     is.Less(actual, ceiling)
is.Positive(val)                  is.Negative(val)
is.Zero(val)

// Errors
is.Error(err)                     is.NoError(err)
is.ErrorIs(err, ErrNotFound)      // walks error chain
is.ErrorAs(err, &target)
is.ErrorContains(err, "not found")

// Type
is.IsType(&User{}, obj)
is.Implements((*io.Reader)(nil), obj)

Argument order: always (expected, actual) — swapping produces confusing diff output.

Advanced Assertions

go
is.ElementsMatch([]string{"b", "a", "c"}, result)             // unordered comparison
is.InDelta(3.14, computedPi, 0.01)                            // float tolerance
is.JSONEq(`{"name":"alice"}`, `{"name": "alice"}`)             // ignores whitespace/key order
is.WithinDuration(expected, actual, 5*time.Second)
is.Regexp(`^user-[a-f0-9]+$`, userID)

// Async polling
is.Eventually(func() bool {
    status, _ := client.GetJobStatus(jobID)
    return status == "completed"
}, 5*time.Second, 100*time.Millisecond)

// Async polling with rich assertions
is.EventuallyWithT(func(c *assert.CollectT) {
    resp, err := client.GetOrder(orderID)
    assert.NoError(c, err)
    assert.Equal(c, "shipped", resp.Status)
}, 10*time.Second, 500*time.Millisecond)

testify/mock

Mock interfaces to isolate the unit under test. Embed mock.Mock, implement methods with m.Called(), always verify with AssertExpectations(t).

Key matchers: mock.Anything, mock.AnythingOfType("T"), mock.MatchedBy(func). Call modifiers: .Once(), .Times(n), .Maybe(), .Run(func).

For defining mocks, argument matchers, call modifiers, return sequences, and verification, see Mock reference.

testify/suite

Suites group related tests with shared setup/teardown.

Lifecycle

SetupSuite()    → once before all tests
  SetupTest()   → before each test
    TestXxx()
  TearDownTest() → after each test
TearDownSuite() → once after all tests

Example

go
type TokenServiceSuite struct {
    suite.Suite
    store   *MockTokenStore
    service *TokenService
}

func (s *TokenServiceSuite) SetupTest() {
    s.store = new(MockTokenStore)
    s.service = NewTokenService(s.store)
}

func (s *TokenServiceSuite) TestGenerate_ReturnsValidToken() {
    s.store.On("Save", mock.Anything, mock.Anything).Return(nil)
    token, err := s.service.Generate("user-42")
    s.NoError(err)
    s.NotEmpty(token)
    s.store.AssertExpectations(s.T())
}

// Required launcher
func TestTokenServiceSuite(t *testing.T) {
    suite.Run(t, new(TokenServiceSuite))
}

Suite methods like s.Equal() behave like assert. For require: s.Require().NotNil(obj).

Common Mistakes

  • Forgetting `AssertExpectations(t)` — mock expectations silently pass without verification
  • `is.Equal(ErrNotFound, err)` — fails on wrapped errors. Use is.ErrorIs to walk the chain
  • Swapped argument order — testify assumes (expected, actual). Swapping produces backwards diffs
  • `assert` for guards — test continues after failure and panics on nil dereference. Use require
  • Missing `suite.Run()` — without the launcher function, zero tests execute silently
  • Comparing pointers — is.Equal(ptr1, ptr2) compares addresses. Dereference or use EqualExportedValues

Linters

Use testifylint to catch wrong argument order, assert/require misuse, and more. See samber/cc-skills-golang@golang-lint skill.

Cross-References

  • → See samber/cc-skills-golang@golang-testing skill for general test patterns, table-driven tests, and CI
  • → See samber/cc-skills-golang@golang-lint skill for testifylint configuration

タスクに関連する項目

同じリポジトリから

関連する Skills

すべての Skills
samber
コミュニティ

golang-benchmark

Golang benchmarking, profiling, and performance measurement. Use when writing, running, or comparing Go benchmarks, profiling hot paths with pprof, interpreting CPU/memory/trace profiles, analyzing results with benchstat, setting up CI benchmark regression detection, or investigating production performance with Prometheus runtime metrics. Also use when the developer needs deep analysis on a specific performance indicator - this skill provides the measurement methodology, while samber/cc-skills-g

導入数
3
GitHub Stars
3626
更新日
10月23日
samber
コミュニティ

golang-concurrency

Golang concurrency design — goroutine lifecycle and leak prevention, channels and select, channel ownership and direction, sync.Mutex/RWMutex/sync.Map/sync.Once/atomics, errgroup, singleflight, worker pools, and fan-out/fan-in pipelines. Use when writing or reviewing concurrent Go code, when choosing between channels and mutexes, when protecting a shared map or counter, or when a goroutine has no clear exit. Not for defensive coding unrelated to concurrency such as nil panics, slice aliasing, or

導入数
4
GitHub Stars
3626
更新日
10月23日
samber
コミュニティ

golang-data-structures

Golang data structures — slices (internals, capacity growth, preallocation, slices package), maps (internals, hash buckets, maps package), arrays, container/list/heap/ring, strings.Builder vs bytes.Buffer, generic collections, pointers (unsafe.Pointer, weak.Pointer), and copy semantics. Use when choosing or optimizing Go data structures, implementing generic containers, using container/ packages, unsafe or weak pointers, or questioning slice/map internals. Not for applying optimization patterns

導入数
3
GitHub Stars
3626
更新日
10月23日
samber
コミュニティ

golang-error-handling

Idiomatic Golang error handling — creation, wrapping with %w, errors.Is/As, errors.Join, custom error types, sentinel errors, panic/recover, the single handling rule, structured logging with slog, HTTP request logging middleware, and samber/oops for production errors. Built to make logs usable at scale with log aggregation 3rd-party tools. Apply when creating, wrapping, inspecting, or logging errors in Go code. For samber/oops specifics → See samber/cc-skills-golang@golang-samber-oops skill; for

導入数
5
GitHub Stars
3626
更新日
10月23日