0


一、Go基础知识22、单元测试详解

一、编写单元测试用例

Go语言(也称为Golang)是一种开源的编程语言,具有简洁、高效、并发支持等特点。在Go语言中,单元测试是一种重要的测试方法,用于验证代码的各个单元(函数、方法等)是否按照预期进行工作。Go语言内置了一套测试框架。

举一个简单的Go语言单元测试的例子。假设有一个计算器的包,其中包含加法函数

Add

和减法函数

Sub

。我们将编写单元测试来验证这两个函数的正确性。

首先,创建一个名为

calculator.go

的文件,包含以下代码:

// calculator.gopackage calculator

// Add 函数用于两个整数相加funcAdd(a, b int)int{return a + b
}// Sub 函数用于两个整数相减funcSub(a, b int)int{return a - b
}

接下来,创建一个名为

calculator_test.go

的文件,包含以下单元测试代码:

// calculator_test.gopackage calculator

import"testing"// TestAdd 函数用于测试 Add 函数funcTestAdd(t *testing.T){
    result :=Add(2,3)
    expected :=5if result != expected {
        t.Errorf("Add(2, 3) returned %d, expected %d", result, expected)}}// TestSub 函数用于测试 Sub 函数funcTestSub(t *testing.T){
    result :=Sub(5,2)
    expected :=3if result != expected {
        t.Errorf("Sub(5, 2) returned %d, expected %d", result, expected)}}

在这个例子中,我们使用了Go语言的测试框架,其中

TestAdd

TestSub

分别测试了

Add

Sub

函数。在每个测试函数中,我们调用相应的函数,然后使用

t.Errorf

函数来报告测试失败,并输出实际结果和期望结果。

接下来,打开命令行,进入包含这两个文件的目录,并运行以下命令来执行测试:

go test

如果一切正常,你将看到输出类似于以下内容:

PASS
ok      your/package/directory   0.001s

这表示所有的测试都通过了。如果有测试失败,将会显示相应的错误信息。

二、跳过耗时的测试用例

在Go语言中,你可以使用测试框架提供的

-short

标志来跳过耗时的单元测试用例。这个标志用于标识短测试,通常用于跳过那些可能需要较长时间才能完成的测试。通过这种方式,你可以在快速迭代和构建过程中跳过一些耗时的测试,以提高开发效率。

下面是一个简单的例子,演示如何在Go语言中使用

-short

标志跳过某些测试。假设有一个包含两个测试用例的文件

example_test.go

// example_test.gopackage example

import("testing""time")// TestShort 单元测试用例,通常执行较快funcTestShort(t *testing.T){
    time.Sleep(100* time.Millisecond)// 你的测试逻辑...}// TestLong 单元测试用例,可能执行较长时间funcTestLong(t *testing.T){
    time.Sleep(2* time.Second)// 你的测试逻辑...}

在这个例子中,

TestShort

是一个执行较快的测试用例,而

TestLong

可能需要较长时间来完成。

现在,如果你想跳过那些执行时间较长的测试用例,可以在运行

go test

命令时使用

-short

标志。例如:

go test-short

这将会跳过执行时间较长的测试用例,只运行执行时间较短的测试用例。

在输出中,你可能会看到类似以下的内容:

=== RUN   TestShort
--- PASS: TestShort (0.10s)
PASS
ok      your/package/directory   0.120s

这表示只有

TestShort

被运行,并且通过了测试。

TestLong

被跳过,因为我们使用了

-short

标志。

请注意,使用

-short

标志是一个约定,你需要在编写测试用例时考虑哪些测试是短暂的,并使用

-short

来标识它们。这样,在需要时,你可以选择性地跳过一些测试,以加快测试运行的速度。

三、基于表格驱动测试

Go语言中的表格驱动测试是一种测试方法,通过在测试用例中使用表格结构,可以轻松地测试同一函数或方法的多个输入和输出组合。

假设有一个包含两个函数的文件

math.go

,其中包含一个加法函数

Add

和一个减法函数

Sub

// math.gopackage math

// Add 函数用于两个整数相加funcAdd(a, b int)int{return a + b
}// Sub 函数用于两个整数相减funcSub(a, b int)int{return a - b
}

现在,我们将创建一个测试文件

math_test.go

,使用表格驱动测试来测试这两个函数:

// math_test.gopackage math

import("testing")// TestAddTableDriven 表格驱动测试 Add 函数funcTestAddTableDriven(t *testing.T){// 定义测试用例的表格
    testCases :=[]struct{
        a, b     int
        expected int}{{1,2,3},// 第一个测试用例{-1,1,0},// 第二个测试用例{0,0,0},// 第三个测试用例{10,-5,5},// 第四个测试用例}// 遍历测试用例表格for_, tc :=range testCases {// 执行测试
        result :=Add(tc.a, tc.b)// 检查结果是否符合预期if result != tc.expected {
            t.Errorf("Add(%d, %d) returned %d, expected %d", tc.a, tc.b, result, tc.expected)}}}// TestSubTableDriven 表格驱动测试 Sub 函数funcTestSubTableDriven(t *testing.T){// 定义测试用例的表格
    testCases :=[]struct{
        a, b     int
        expected int}{{5,2,3},// 第一个测试用例{10,5,5},// 第二个测试用例{0,0,0},// 第三个测试用例{-5,-10,5},// 第四个测试用例}// 遍历测试用例表格for_, tc :=range testCases {// 执行测试
        result :=Sub(tc.a, tc.b)// 检查结果是否符合预期if result != tc.expected {
            t.Errorf("Sub(%d, %d) returned %d, expected %d", tc.a, tc.b, result, tc.expected)}}}

在这个例子中,我们定义了一个包含输入参数和期望输出的测试用例表格。然后,通过循环遍历表格中的每个测试用例,并对每个测试用例执行相应的函数。如果结果不符合预期,就使用

t.Errorf

报告测试失败。

运行测试的方式与之前相同:

go test

如果所有测试通过,你将看到类似以下的输出:

PASS
ok      your/package/directory   0.120s

表格驱动测试使得添加新的测试用例变得简单,只需在表格中添加新的行。

四、benchmark性能测试

在Go语言中,性能测试(Benchmark)是一种用于度量代码执行性能的测试方法。性能测试使用

testing

包提供的

Benchmark

函数,允许你对函数或方法的执行时间进行基准测试。

假设有一个包含两个函数的文件

math.go

,其中包含一个加法函数

Add

和一个减法函数

Sub

// math.gopackage math

// Add 函数用于两个整数相加funcAdd(a, b int)int{return a + b
}// Sub 函数用于两个整数相减funcSub(a, b int)int{return a - b
}

现在,我们将创建一个性能测试文件

math_benchmark_test.go

,用于对

Add

函数进行性能测试:

// math_benchmark_test.gopackage math

import("testing")// BenchmarkAdd 性能测试 Add 函数funcBenchmarkAdd(b *testing.B){// 循环运行测试函数 b.N 次for i :=0; i < b.N; i++{// 执行测试
        result :=Add(2,3)// 避免编译器优化删除对结果的引用_= result
    }}

在这个例子中,我们使用了

testing

包的

Benchmark

函数,并创建了一个

BenchmarkAdd

函数。在这个函数中,我们使用

b.N

来指定测试运行的次数,然后在循环中执行

Add

函数。我们还将结果存储在一个变量中,以防止编译器优化删除对结果的引用。

运行性能测试的方式如下:

go test-bench.

上述命令中的

.

表示运行当前目录下的所有性能测试。如果一切正常,你将看到类似以下的输出:

goos: linux
goarch: amd64
pkg: your/package/directory
BenchmarkAdd-4       1000000000               0.300 ns/op
PASS
ok      your/package/directory   0.318s

输出中的

BenchmarkAdd-4

表示运行在 4 个 CPU 核心上的

BenchmarkAdd

函数的性能测试。

1000000000

表示测试运行的次数,

0.300 ns/op

表示每次操作的平均纳秒数。

通过性能测试,你可以了解到函数在不同输入条件下的执行时间,以便进行性能优化或对比不同实现的性能。
请注意,性能测试的结果可能受到多种因素的影响,包括硬件、操作系统和其他正在运行的程序。因此,谨慎解释和使用性能测试的结果是很重要的。

五、主要参数

1、

-bench regexp
  • 解释: 运行与指定的正则表达式匹配的基准测试。
  • 使用方式:go test -bench=RegExp,其中RegExp是一个正则表达式,用于匹配要运行的基准测试函数的名称。
  • 导致结果: 只有函数名与指定的正则表达式匹配的基准测试将被运行。

2、

-cover
  • 解释: 启用测试覆盖率分析。
  • 使用方式:go test -cover,在测试运行时收集覆盖率数据。
  • 导致结果: 测试完成后,将输出每个文件的代码覆盖率统计。

3、

-race
  • 解释: 启用数据竞争检测。
  • 使用方式:go test -race,对测试执行数据竞争检测。
  • 导致结果: 如果测试中存在数据竞争,测试会报错并提供相关信息。

4、

-v
  • 解释: 详细模式,打印所有测试的名称和运行时间。
  • 使用方式:go test -v,在测试运行时输出详细的测试信息。
  • 导致结果: 输出更详细的测试执行信息,包括每个测试的名称和运行时间。

5、

-run regexp
  • 解释: 运行与指定的正则表达式匹配的测试函数。
  • 使用方式:go test -run=RegExp,其中RegExp是一个正则表达式,用于匹配要运行的测试函数的名称。
  • 导致结果: 只有函数名与指定的正则表达式匹配的测试将被运行。

6、

-short
  • 解释: 启用短模式测试。
  • 使用方式:go test -short,在测试函数中,可以使用testing.Short()来决定是否跳过某些长时间运行的测试。
  • 导致结果: 测试运行时将跳过那些标记为长时间运行的测试。

7、

-timeout d
  • 解释: 设置测试的超时时间。
  • 使用方式:go test -timeout=d,其中d是时间持续值,如5s2m等。
  • 导致结果: 如果测试运行时间超过指定时间,测试将被中断并报错。

8、

-parallel n
  • 解释: 设置并行运行测试的最大数量。
  • 使用方式:go test -parallel=n,其中n指定了可以并行运行的测试的最大数量。
  • 导致结果: 测试将并行运行,但并行数量不会超过指定的数量。

本文转载自: https://blog.csdn.net/weixin_49015143/article/details/134643035
版权归原作者 风不归 所有, 如有侵权,请联系我们删除。

“一、Go基础知识22、单元测试详解”的评论:

还没有评论