Go 单元测试初探

852 阅读1分钟

单测Library选择

goconvey

Mock选择

Bytedance mockey

运行方法

cd project/folder/path/to/your/package
go test -count=1 -v ./... -gcflags="all=-l -N" -coverprofile=coverage.out

-l 表示禁止内联 -N 表示禁止编译器优化,都是为了减少mock时候的一些奇怪的错误

-count=1 会禁掉单测缓存,每次都是全新的,可以设置为更大的数字,让单测多跑几遍,可能会发现一些偶发问题

-cpu=4 使用cpu核数

-p=1 逐个执行测试用例而不是并行执行

-failfast 出错后及时停止,方便定位

-coverprofile=coverage.out 输出覆盖率报告

在MacBook M1上,建议使用-gcflags="all=-l -N"

count=10的时候我发现我代码的问题

panic: re-mock xxxxxx

是因为一开始mock了一些函数,在单测用例结束的时候没有unpatch()导致的,只需要给unpatch掉即可。 也有可能需要把Convey()改成mockey.PatchConvey(),试一下。

一个较为完整的单测例子


convey.Convey("TestSuiteName", t, func() {
   for _, tt := range tests {
      convey.Convey(tt.name, func(c convey.C) {
         t.Run(tt.name, func(t *testing.T) {
            tt.init()
            defer func() {
               for _, mocker := range mockers {
                  mocker.UnPatch()
               }
            }()
            err := YourFunction(tt.args.ctx, tt.args.OtherContent)
            c.SoMsg(fmt.Sprintf("Your Error MSG error =%v, wantErr%v", err, tt.wantErr),
               err != nil, convey.ShouldEqual, tt.wantErr)
         })
      })
   }
})

大部分网上的例子里,都没有使用func(c convey.C),都是使用的func(),当然网上的例子也都是使用的convey.So()这样会带来一个问题

--- FAIL: TestLogFile (0.00s)
panic: Convey operation made without context on goroutine stack.
Hint: Perhaps you meant to use `Convey(..., func(c C){...})` ? [recovered]
	panic: Convey operation made without context on goroutine stack.
Hint: Perhaps you meant to use `Convey(..., func(c C){...})` ? [recovered]
	panic: Convey operation made without context on goroutine stack.
Hint: Perhaps you meant to use `Convey(..., func(c C){...})` ?

可以搜到官方的一个issue但是并没有正确的解答。并且官方的examples也没有convey.C的使用方法,因此在这里做一个备忘记录。