Wen

Golang-ユニットテストにおける正しい後処理の書き方:t.Cleanup()

N views

ユニットテストの後処理を行う場合、

defer並列で動いているサブテストの終了を待たずに実行されてしまう問題がある。

全てのサブテストが終了してから後処理を行たいなら t.Cleanup() を使おう。

Deferによる後処理の例

package main

import (
    "log"
    "testing"
)

func TestDefer(t *testing.T) {
    tcs := map[string]string{
        "A": "1",
        "B": "2",
        "C": "3",
    }

    defer log.Printf("End")

    for tn, tc := range tcs {
        tc := tc
        t.Run(tn, func(t *testing.T) {
            t.Parallel()
            log.Println(tc)
        })
    }
}

そのログの抜粋:

2009/11/10 23:00:00 End
2009/11/10 23:00:00 1
2009/11/10 23:00:00 3
2009/11/10 23:00:00 2

demo

t.Cleanup() による後処理

package main

import (
    "log"
    "testing"
)

func TestCleanup(t *testing.T) {
    tcs := map[string]string{
        "A": "1",
        "B": "2",
        "C": "3",
    }

    t.Cleanup(func() {
        log.Printf("End")
    })

    for tn, tc := range tcs {
        tc := tc
        t.Run(tn, func(t *testing.T) {
            t.Parallel()
            log.Println(tc)
        })
    }
}

そのログの抜粋:

2009/11/10 23:00:00 1
2009/11/10 23:00:00 3
2009/11/10 23:00:00 2
2009/11/10 23:00:00 End

demo

参考

Go 言語でのテストの並列化 〜t.Parallel()メソッドを理解する

t.Cleanup()で並列に動かすことのできるテーブルドリブンテストを書く

本記事は 「表示 - 非営利 - 改変禁止 4.0 国際 (CC BY-NC-ND 4.0)」 を採用。