testifylint

Table of Contents

  1. 解決する問題
  2. 設定
  3. オプション
  4. 主要なチェッカー
    1. アサーション選択
    2. エラー処理
    3. テスト品質
  5. サンプル
    1. 検出例
    2. 修正例
  6. 注意点
  7. 参考リンク

testifylint は testify ライブラリの使い方をチェックし、より適切なアサーション関数の使用を促すツールです。

解決する問題

testify は Go で最も広く使われるテストライブラリですが、API が豊富なため不適切な関数の選択が起きやすくなります。失敗メッセージの可読性が低下したり、テストが意図通りに動作しない原因になります。

1
2
3
4
5
6
7
8
9
// Before: 不適切な testify の使い方
func TestUser(t *testing.T) {
user, err := GetUser("123")

assert.Equal(t, nil, err) // error には assert.NoError を使うべき
assert.Equal(t, true, user != nil) // assert.NotNil を使うべき
assert.True(t, user.Name == "Alice") // assert.Equal を使うべき
assert.Equal(t, 0, len(user.Tags)) // assert.Empty を使うべき
}
1
2
3
4
5
6
7
8
9
// After: 適切な testify の使い方
func TestUser(t *testing.T) {
user, err := GetUser("123")

assert.NoError(t, err)
assert.NotNil(t, user)
assert.Equal(t, "Alice", user.Name)
assert.Empty(t, user.Tags)
}

設定

公式ドキュメント

1
2
3
4
5
6
7
8
9
10
11
# .golangci.yml 設定例
version: "2"

linters:
enable:
- testifylint
settings:
testifylint:
enable-all: true
disable:
- suite-thelper

オプション

オプション デフォルト 説明
enable-all bool false すべてのチェッカーを有効化する
disable-all bool false すべてのチェッカーを無効化する
enable []string [] 有効化するチェッカーのリスト
disable []string [suite-thelper] 無効化するチェッカーのリスト

主要なチェッカー

アサーション選択

チェッカー Bad Good
bool-compare assert.Equal(t, true, v) assert.True(t, v)
compares assert.True(t, a == b) assert.Equal(t, a, b)
empty assert.Len(t, arr, 0) assert.Empty(t, arr)
len assert.Equal(t, 3, len(arr)) assert.Len(t, arr, 3)
nil-compare assert.Equal(t, nil, v) assert.Nil(t, v)
negative-positive assert.True(t, v > 0) assert.Positive(t, v)
contains assert.True(t, strings.Contains(s, "x")) assert.Contains(t, s, "x")
regexp assert.True(t, regexp.MatchString(p, s)) assert.Regexp(t, p, s)

エラー処理

チェッカー Bad Good
error-nil assert.Nil(t, err) assert.NoError(t, err)
error-is-as assert.True(t, errors.Is(err, target)) assert.ErrorIs(t, err, target)
require-error assert.NoError(t, err) の後に続行 require.NoError(t, err)

テスト品質

チェッカー 検出内容
expected-actual assert.Equal の引数順序(expected, actual)の誤り
float-compare 浮動小数点数の直接比較(assert.InDelta を使うべき)
useless-assert 常に成功するアサーション
go-require goroutine 内での require の使用(テストを安全に中断できない)
formatter フォーマット文字列の不正使用

サンプル

検出例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func TestOrder(t *testing.T) {
order, err := CreateOrder(item)

// error-nil: assert.Nil ではなく assert.NoError を使うべき
assert.Nil(t, err)

// expected-actual: 引数の順序が逆(expected が先)
assert.Equal(t, order.Total, 100)

// float-compare: 浮動小数点は InDelta で比較すべき
assert.Equal(t, 3.14, order.Tax)

// require-error: エラー後に処理を続行してしまう
assert.NoError(t, err) // require.NoError にすべき
assert.Equal(t, "pending", order.Status) // err が nil でなければパニック
}

修正例

1
2
3
4
5
6
7
8
func TestOrder(t *testing.T) {
order, err := CreateOrder(item)

require.NoError(t, err) // エラー時はここでテスト中断
assert.Equal(t, 100, order.Total)
assert.InDelta(t, 3.14, order.Tax, 0.001)
assert.Equal(t, "pending", order.Status)
}

注意点

  • require-error チェッカーは特に重要。assert.NoError は失敗してもテストを続行するため、後続のアサーションで nil ポインタパニックが発生する可能性がある
  • expected-actual チェッカーはデフォルトで ^(exp(ected)?|want(ed)?) にマッチする変数を expected とみなす
  • 多くのチェッカーが autofix に対応しており、golangci-lint run --fix で自動修正できる

参考リンク