测试2|青训营笔记

104 阅读4分钟

这是我参与「第五届青训营」伴学笔记创作活动的第 16 天


这是我参与「第五届青训营」伴学笔记创作活动的第 16 天

前言

因为项目中接到了负责测试的任务,今天继续深入的聊一聊测试

单元测试

昨天聊到了关于单元测试 了解到了一些不通过的方法

  • 函数中通过调用testing.TErrorErrorfFailNowFatalFatalIf方法,说明测试不通过,调用Log方法用来记录测试的信息。

今天继续聊一聊进一步的东西

子测试

子测试是 Go 语言内置支持的,可以在某个测试用例中,根据测试场景使用 t.Run创建不同的子测试用例:

//  原文见参考文章1
//  calc_test.go 
func TestMul(t *testing.T) {
	cases := []struct {
		Name           string
		A, B, Expected int
	}{
		{"pos", 2, 3, 6},
		{"neg", 2, -3, -6},
		{"zero", 2, 0, 0},
	}

	for _, c := range cases {
		t.Run(c.Name, func(t *testing.T) {
			if ans := Mul(c.A, c.B); ans != c.Expected {
				t.Fatalf("%d * %d expected %d, but %d got",
					c.A, c.B, c.Expected, ans)
			}
		})
	}
}

这里使用了 t.Run 去跑了子测试 当我们对于同一个函数有多个单元测试的case的时候可以利用这种方法更清晰的进行测试

帮助函数

t.helpers()

当我们希望把多个测试的公共部分提取出来以达到提升可读性的要求的时候 我们发现如果出现错误提示的报错是提示在公共部分 很难直接的知道是在哪一个部位出现的错误 当我们使用帮助函数之后 报错的提示位置会变成调用者的信息 这样我们就可以更直观的了解到错误的位置

setup 和 teardown

如果在同一个测试文件中,每一个测试用例运行前后的逻辑是相同的,一般会写在 setup 和 teardown 函数中。例如执行前需要实例化待测试的对象,如果这个对象比较复杂,很适合将这一部分逻辑提取出来;执行后,可能会做一些资源回收类的工作,例如关闭网络连接,释放文件等。标准库 testing 提供了这样的机制:

func TestMain(m *testing.M) {
	setup()
	code := m.Run()
	teardown()
	os.Exit(code)
}
  • 如果测试文件中包含函数 TestMain,那么生成的测试将调用 TestMain(m),而不是直接运行测试。
  • 调用 m.Run() 触发所有测试用例的执行,并使用 os.Exit() 处理返回的状态码,如果不为0,说明有用例失败。
  • 因此可以在调用 m.Run() 前后做一些额外的准备(setup)和回收(teardown)工作。

基准测试

基准测试并没有什么大的变化

mock打桩

mock 测试就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法。这个虚拟的对象就是mock对象。mock对象就是真实对象在调试期间的代替品。

简单来说,就是用 mock 对象模拟依赖项的行为。

mock

mockery

Mockery是一个go语言测试框架,用于帮助开发者更好地测试其代码。它可以模拟函数,接口和结构体,并且可以生成测试友好的代码,以帮助开发者更好地测试其应用程序。 Mockery的使用可以分成三个步骤:

  1. 在测试文件中导入mockery包:

import "github.com/vektra/mockery/v2/mockery"

  1. 创建要模拟的函数,接口或结构体:
// 创建一个模拟函数 
func MockFunc() int { 
    return 0 
} 

// 创建一个模拟接口 
type mockInterface interface { 
    DoSomething() 
} 

// 创建一个模拟结构体 
type mockStruct struct { 
    Name string 
} 
  1. 使用mockery生成测试友好的代码:

mockery.Generate(MockFunc)

mockery.Generate(mockInterface)

mockery.Generate(mockStruct)

生成的代码将会被放置到生成的文件夹中,开发者可以使用这些代码来测试自己的应用程序。

其中步骤三还可以用注释来快速生成

// mockery:generate 
func MockFunc() int { 
    return 0 
}

// mockery:generate 
type mockInterface interface { 
    DoSomething() 
}

。。。

之后使用命令mockery -dir . -all快速生成

如何在go的项目里面进行高覆盖度的测试

  1. 编写单元测试:将代码拆分成最小的单元,并编写测试用例,来测试每个单元的功能。

  2. 编写基准测试:使用Go语言内置的testing包,编写基准测试,测试代码的性能。

  3. 编写集成测试:将多个模块组合起来,测试整个系统的功能,以确保系统中各个模块之间的交互是正确的。

  4. 编写端到端测试:将整个系统的功能进行测试,以模拟用户的行为,验证系统的正确性。

  5. 编写Mock测试:使用Mockery框架,模拟函数,接口和结构体,生成测试友好的代码,以帮助开发者更好地测试其应用程序。

参考材料:


码风略丑 读者见谅 --2023/2/18