ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

go test 命令详解

go test 命令详解 文章目录1.简介2.命令格式3.test flag4.test/binary flags4.1 测试行为选项-coverpkg4.2 状态分析选项详细介绍-short5.常用选项6.示例7.FAQ7.1 禁用缓存7.2 禁止内联参考文献1.简介go test 是 Go 用来执行测试函数test function、基准函数benchmark function和示例函数example function的命令。执行 go test 命令它会在*_test.go文件中寻找 test、benchmark 和 example 函数来执行。测试函数名必须以 TestXXX 开头。基准函数名必须以 BenchmarkXXX 开头。示例函数名必须以 ExampleXXX 开头。// test 测试函数funcTestXXX(t*testing.T){...}// benchmark 基准函数funcBenchmarkXXX(b*testing.B){...}// examples 示例函数其相关命名方式可以查看第一篇文章funcExamplePrintln(){Println(The output of\nthis example.)// Output: The output of// this example.}更多关于测试函数的信息请查看go help testfunc。2.命令格式gotest[build/test flags][packages][build/test flagstestbinary flags]可以指定多个被测试的包用空格分隔。go test 自动测试指定的包按如下格式打印测试结果摘要ok archive/tar 0.011s FAIL archive/zip 0.022s ok compress/gzip 0.033s ...然后是每个失败包的详细输出。go test 重新编译每个包中后缀为_test.go的文件。这些文件可以包含测试函数、基准函数和示例函数。有关更多信息请参阅“go help testfunc”。每个列出的包都会导致执行一个单独的测试二进制文件。注意名称以_或.开头的文件即使后缀是_test.go将被忽略。测试文件中如果声明的包后缀为_test将被作为单独的包来编译然后与主测试二进制文件链接并运行。go test 命令还会忽略 testdata 目录该目录用来保存测试需要用到的辅助数据。go test 有两种运行模式1本地目录模式。在没有包参数调用时go test 编译当前目录中找到的包和测试然后运行测试二进制文件。在这种模式下caching 是禁用的。在包测试完成后go test 打印一行概要显示测试状态、包名和运行时间。2包列表模式。显示指明包参数调用 go test如gotestmath gotest./... gotest.此模式下go test 编译并测试在命令行上列出的每个包。如果一个包测试通过go test 只打印最终的 ok 总结行。如果一个包测试失败go test 将输出完整的测试输出。如果使用 -bench 或 -v 选项则 go test 会输出完整的输出包括通过测试的包的信息以显示所请求的基准测试结果或详细日志。在对所有列出的包进行包测试并打印其输出之后如果任何包测试失败go test 将打印最终的“FAIL”状态。注意描述软件包列表时使用三个点作为通配符。如测试当前目录及其子目录中的所有包。gotest./...仅在包列表模式下go test 会缓存成功的包测试结果以避免不必要的重复运行测试。当测试结果可以从缓存中恢复时go tes t将重新显示以前的输出而不是再次运行测试二进制文件。发生这种情况时go test 打印 “(cached)” 以代替摘要行中的已用时间。缓存中匹配的规则是运行涉及相同的测试二进制文件命令行上的选项完全来自一组受限的“可缓存”测试选项定义为 -benchtime、-cpu、-list、-parallel、-run、-short 和 -v。如果运行 go test 时任何测试选项或非测试选项在此集合之外则不会缓存结果。要禁用缓存请使用除可缓存选项之外的任何测试选项或参数。明确禁用测试缓存的惯用方法是使用 -count1。测试在包的根目录通常为 $GOPATH打开的文件和依赖的环境变量只有不发生变化时才能匹配缓存。被缓存的测试结果将被视为立即执行因此无论 -timeout 如何设置成功的包测试结果都将被缓存和重用。3.test flag除 build 选项外go test 本身处理的选项包括-args Pass the remainder of the command line (everything after -args) to the test binary, uninterpreted and unchanged. Because this flag consumes the remainder of the command line, the package list (if present) must appear before this flag. -c Compile the test binary to pkg.test but do not run it (where pkg is the last element of the packages import path). The file name can be changed with the -o flag. -exec xprog Run the test binary using xprog. The behavior is the same as in go run. See go help run for details. -i Install packages that are dependencies of the test. Do not run the test. The -i flag is deprecated. Compiled packages are cached automatically. -json Convert test output to JSON suitable for automated processing. See go doc test2json for the encoding details. -o file Compile the test binary to the named file. The test still runs (unless -c or -i is specified).有关构建选项的更多信息请参阅“go help build”。有关指定软件包的更多信息请参阅“go help packages”。4.test/binary flags以下选项同时被 go test 命令和编译生成的测试二进制文件支持。主要分为两类一类控制测试行为一类用于状态分析。4.1 测试行为选项-bench regexp Run only those benchmarks matching a regular expression. By default, no benchmarks are run. To run all benchmarks, use -bench . or -bench.. The regular expression is split by unbracketed slash (/) characters into a sequence of regular expressions, and each part of a benchmarks identifier must match the corresponding element in the sequence, if any. Possible parents of matches are run with b.N1 to identify sub-benchmarks. For example, given -benchX/Y, top-level benchmarks matching X are run with b.N1 to find any sub-benchmarks matching Y, which are then run in full. -benchtime t Run enough iterations of each benchmark to take t, specified as a time.Duration (for example, -benchtime 1h30s). The default is 1 second (1s). The special syntax Nx means to run the benchmark N times (for example, -benchtime 100x). -count n Run each test and benchmark n times (default 1). If -cpu is set, run n times for each GOMAXPROCS value. Examples are always run once. -cover Enable coverage analysis. Note that because coverage works by annotating the source code before compilation, compilation and test failures with coverage enabled may report line numbers that dont correspond to the original sources. -covermode set,count,atomic Set the mode for coverage analysis for the package[s] being tested. The default is set unless -race is enabled, in which case it is atomic. The values: set: bool: does this statement run? count: int: how many times does this statement run? atomic: int: count, but correct in multithreaded tests; significantly more expensive. Sets -cover. -coverpkg pattern1,pattern2,pattern3 Apply coverage analysis in each test to packages matching the patterns. The default is for each test to analyze only the package being tested. See go help packages for a description of package patterns. Sets -cover. -cpu 1,2,4 Specify a list of GOMAXPROCS values for which the tests or benchmarks should be executed. The default is the current value of GOMAXPROCS. -failfast Do not start new tests after the first test failure. -list regexp List tests, benchmarks, or examples matching the regular expression. No tests, benchmarks or examples will be run. This will only list top-level tests. No subtest or subbenchmarks will be shown. -parallel n Allow parallel execution of test functions that call t.Parallel. The value of this flag is the maximum number of tests to run simultaneously; by default, it is set to the value of GOMAXPROCS. Note that -parallel only applies within a single test binary. The go test command may run tests for different packages in parallel as well, according to the setting of the -p flag (see go help build). -run regexp Run only those tests and examples matching the regular expression. For tests, the regular expression is split by unbracketed slash (/) characters into a sequence of regular expressions, and each part of a tests identifier must match the corresponding element in the sequence, if any. Note that possible parents of matches are run too, so that -runX/Y matches and runs and reports the result of all tests matching X, even those without sub-tests matching Y, because it must run them to look for those sub-tests. -short Tell long-running tests to shorten their run time. It is off by default but set during all.bash so that installing the Go tree can run a sanity check but not spend time running exhaustive tests. -shuffle off,on,N Randomize the execution order of tests and benchmarks. It is off by default. If -shuffle is set to on, then it will seed the randomizer using the system clock. If -shuffle is set to an integer N, then N will be used as the seed value. In both cases, the seed will be reported for reproducibility. -timeout d If a test binary runs longer than duration d, panic. If d is 0, the timeout is disabled. The default is 10 minutes (10m). -v Verbose output: log all tests as they are run. Also print all text from Log and Logf calls even if the test succeeds. -vet list Configure the invocation of go vet during go test to use the comma-separated list of vet checks. If list is empty, go test runs go vet with a curated list of checks believed to be always worth addressing. If list is off, go test does not run go vet at all.-coverpkg用于指定在计算测试覆盖率时将哪些包纳入统计范围。-coverpkg 指定的包集合就是覆盖率统计的“分母”代码总行数而实际被执行到的代码行数是“分子”。默认情况下go test -cover只统计当前正在测试的包自身。而 -coverpkg 可以让你跨包统计覆盖率包括被当前测试代码间接调用的其他包。支持通配符模式匹配如...匹配所有子包多个包名用逗号分隔。gotest-coverpkgpattern1,pattern2,...-coverprofilefilepackages常见用法与最佳实践需求命令说明集成测试全量统计go test -cover -coverpkg./... ./...统计整个项目的覆盖率适合在 CI 中全面评估测试质量。只统计关键核心包go test -cover -coverpkg./internal/... ./...只关注内部核心包的覆盖率忽略第三方或外围代码。生成覆盖率报告go test -coverprofilecov.out -coverpkg./... ./...生成覆盖率文件便于后续用go tool cover分析。在 CI 中使用同上并将覆盖率文件上传到 Codecov、Coveralls 等平台用于质量门禁、趋势分析、PR 评论等。运行特定包的测试并统计依赖go test -cover -coverpkg./pkgA,./pkgB ./pkgA测试pkgA时同时统计pkgA和pkgB的覆盖率。4.2 状态分析选项-benchmem Print memory allocation statistics for benchmarks. -blockprofile block.out Write a goroutine blocking profile to the specified file when all tests are complete. Writes test binary as -c would. -blockprofilerate n Control the detail provided in goroutine blocking profiles by calling runtime.SetBlockProfileRate with n. See go doc runtime.SetBlockProfileRate. The profiler aims to sample, on average, one blocking event every n nanoseconds the program spends blocked. By default, if -test.blockprofile is set without this flag, all blocking events are recorded, equivalent to -test.blockprofilerate1. -coverprofile cover.out Write a coverage profile to the file after all tests have passed. Sets -cover. -cpuprofile cpu.out Write a CPU profile to the specified file before exiting. Writes test binary as -c would. -memprofile mem.out Write an allocation profile to the file after all tests have passed. Writes test binary as -c would. -memprofilerate n Enable more precise (and expensive) memory allocation profiles by setting runtime.MemProfileRate. See go doc runtime.MemProfileRate. To profile all memory allocations, use -test.memprofilerate1. -mutexprofile mutex.out Write a mutex contention profile to the specified file when all tests are complete. Writes test binary as -c would. -mutexprofilefraction n Sample 1 in n stack traces of goroutines holding a contended mutex. -outputdir directory Place output files from profiling in the specified directory, by default the directory in which go test is running. -trace trace.out Write an execution trace to the specified file before exiting.详细介绍-short-short 选项是一个用于调整测试行为的标志。-short 可以通知测试代码在运行时减少其执行时间。这是通过在测试函数内部检查testing.Short()函数的返回值来实现的。如果testing.Short()返回 true则测试应该跳过耗时较长的操作从而缩短总的测试时间。假设你有一个测试函数 TestTimeConsuming它在默认情况下会运行较长时间。你可以使用 testing.Short() 来根据 -short 标志条件性地跳过某些部分funcTestTimeConsuming(t*testing.T){iftesting.Short(){t.Skip(skipping test in short mode.)}// 长时间运行的测试逻辑// ...}在上面的代码中使用 -short 和 -v 选项执行运行单测TestTimeConsuming 函数会立即跳过并显示跳过测试的消息从而缩短测试运行时间。gotest-v-short-runTestTimeConsumingRUN TestTimeConsuming perf_test.go:53: skippingtestinshort mode. --- SKIP: TestTimeConsuming(0.00s)PASS ok main/perf0.431s5.常用选项-bench regexp 只执行匹配对应正则表达式的 benchmark 函数如执行所有性能测试 -bench . 或 -bench. -benchtime t 对每个 benchmark 函数运行指定时间。如 -benchtime 1h30默认值为 1s。特殊语法 Nx 表示运行基准测试 N 次如 -benchtime 100x -run regexp 只运行匹配对应正则表达式的 test 和 example 函数例如 -run Array 那么就执行函数名包含 Array 的单测函数 -cover 开启测试覆盖率。 -v 显示测试的详细信息。这会显示所有测试的名称和运行状态包括通过 fmt 包输出的信息。6.示例假设在文件 add.go 有一个被测试函数。packagehellofuncAdd(a,bint)int{returnab}测试函数test function在测试文件 add_test.go 添加一个单元测试函数 TestAddpackagehellofuncTestAdd(t*testing.T){sum:Add(5,5)ifsum10{t.Log(the result is ok)}else{t.Fatal(the result is wrong)}}比如使用 -run 来运行指定单元测试函数发现只运行了 TestAdd 测试函数。go test -v -run TestAdd main/hello RUN TestAdd add_test.go:16: the result is ok --- PASS: TestAdd (0.00s) PASS ok main/hello 0.170s基准函数benchmark function添加一个性能测试函数 BenchmarkAddpackagehellofuncBenchmarkAdd(b*testing.B){forn:0;nb.N;n{Add(1,2)}}运行指定基准函数go test -bench BenchmarkAdd main/hello goos: windows goarch: amd64 pkg: main/contain cpu: Intel(R) Core(TM) i7-9700 CPU 3.00GHz BenchmarkAdd-8 1000000000 0.2333 ns/op PASS ok main/contain 0.586s示例函数example functionpackagehellofuncExampleAdd(){fmt.Println(Add(1,2))// Output: 3}运行指定示例函数go test -v -run ExampleAdd main/contain RUN ExampleAdd --- PASS: ExampleAdd (0.00s) PASS ok main/contain (cached)注意示例函数类似于测试函数但不是使用 *testing.T 来报告成功或失败而是将输出打印到 os.Stdout。如果示例函数中的最后一条注释以“Output:”开头则将输出与注释进行精确比较参见上面的示例。如果最后一条注释以“Unordered output:”开头则将输出与注释进行比较但忽略行的顺序。编译了一个没有此类注释的示例函数会被编译但不会被执行。如果在“Output:”之后没有文本示例函数仍会被编译并执行并且预期不会产生任何输出。获取每个函数的单测覆盖率。如果您想查找没有被测试覆盖的函数可以使用 -coverprofile 选项将覆盖率报告输出到文件中。gotest-coverprofilecover.out ./...然后使用内置的 go tool cover 命令来查看单测覆盖率报告。go tool cover-funccover.out上面使用 -func 选项可以输出每个函数的单测覆盖率概要信息。github.com/dablelv/cyan/cmp/cmp.go:21: Cmp 100.0% github.com/dablelv/cyan/cmp/cmp.go:35: Compare 95.5% github.com/dablelv/cyan/cmp/cmp.go:85: CompareLT 0.0% ...查看具体代码行的覆盖情况。如果想查看代码行的单测覆盖情况可以使用内置的 go tool cover 命令将覆盖率报告转换为 HTML 文件。然后通过浏览器打开查看。go tool cover-htmlcoverage.out-ocoverage.html7.FAQ7.1 禁用缓存测试结果不及预期可能的原因是测试使用了上一次缓存。当使用 go test 命令运行测试时如果测试文件或依赖文件没有发生变化测试缓存会自动生效测试将直接使用缓存结果。如果测试文件或依赖文件发生了变化测试缓存会自动失效下一次测试将重新运行。测试缓存的使用可以通过 -count 选项进行控制-count 选项用于指定运行测试的次数。明确禁用测试缓存的惯用方法是使用 -count1每次测试都将重新运行一次。gotest-v-count1.7.2 禁止内联如果编译器决定内联一个函数这可能会影响到你尝试通过 mock 框架替换或拦截该函数的能力。为了避免这种情况你可以通过禁止内联来确保 mock 可以正常工作。要在进行单元测试时禁止内联你可以使用 go test 命令的 -gcflags 参数。这个参数允许你向Go编译器传递特定的编译标志。禁止所有函数的内联如果你想要在测试时禁止所有函数的内联可以执行以下命令gotest-gcflagsall-l这里-l 标志指示编译器禁用内联。禁止特定函数的内联如果只有某些特定的函数需要禁止内联你可以使用更详细的 -gcflags 设置来指定这些函数。例如如果你只想禁止 myFunc 函数的内联可以使用gotest-gcflags-lmyFunc参考文献Command Documentationgo command documentation
返回列表