1 单元测试概念
在计算机编程中,单元测试(英语:Unit Testing)又称为模块测试,是针对程序模块来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最小单元就是方法,包括基类(超类)、抽象类、或者派生类(子类)中的方法。
通常来说,程序员每修改一次程序就会进行最少一次单元测试,在编写程序的过程中前后很可能要进行多次单元测试,以证实程序达到软件规格书要求的工作目标,没有程序错误;虽然单元测试不是必须的,但也不坏,这牵涉到项目管理的政策决定。
每个理想的测试案例独立于其它案例;为测试时隔离模块,经常使用stubs、mock或fake等测试马甲程序。单元测试通常由软件开发人员编写,用于确保他们所写的代码符合软件需求和遵循开发目标。它的实施方式可以是非常手动的(透过纸笔),或者是做成构建自动化的一部分。
2 Go语言单元测试基本规则和流程
(1)写好(修改)需要测试的程序模块
(2)新建测试go文件,要是以“_test”结尾的go文件,并且该测试文件需要与待测试的文件置于同一目录下
(3)编写测试函数,对于测试函数,其命名需要以“Test”开头,并且其后的字符串的第一个字符必须是大写,或者是数字。如果没有按照此规则进行命名,则该函数在测试时不会被执行。
其次,测试函数的参数必须为(t *testing.T)
(4)go test 命令运行(或IDE运行)
(5)查看测试结果
3 单元测试实例
(1)写好(修改)需要测试的程序模块
main.go
func SayHello(name string) (error, string) { if name == "" { err := errors.New("name not can is nil") return err, "" } return nil, "Hello " + name + "." }
func TestSayHello(t *testing.T) { err, s := SayHello("") if err != nil { t.Errorf(err.Error()) } fmt.Println(s) }
func TestSayHello(t *testing.T) { err, s := SayHello("zs") if err != nil { t.Errorf(err.Error()) } fmt.Println(s) }
func PrintNum(i int) (error, int) { if i <= 0 { err := errors.New("i not can <=0 ") return err,-1 } return nil,i * i }
(2)新建测试go文件,要是以“_test”结尾的go文件
(3)编写测试函数
main_test.go
func TestSayHello(t *testing.T) { err, s := SayHello("zs") if err != nil { t.Errorf(err.Error()) } fmt.Println(s) } func TestPrintNum(t *testing.T) { var numTest = []struct { in int out int }{ {1, 1}, {2, 4}, {3, 9}, {4, 16}, {5, 25}, {6, 36}, {7, 49}, } for _, tt := range numTest { err, actual := PrintNum(tt.in) if err != nil { t.Errorf(err.Error()) } if actual != tt.out { t.Errorf("算错了...") } } }
(4)go test 命令运行(或IDE运行)
(5)查看测试结果
4 解析*testing.T类型
结构体:
type T struct { common isParallel bool //并行方法,必须仅从运行的goroutine调用 context *testContext }
实现的接口:
// TB is the interface common to T and B. type TB interface { Cleanup(func()) Error(args ...interface{}) //报告出错继续 [Log + Fail] Errorf(format string, args ...interface{}) //报告出错继续 [ Logf + Fail] Fail() //失败继续 FailNow() //失败终止 Failed() bool Fatal(args ...interface{}) Fatalf(format string, args ...interface{}) Helper() Log(args ...interface{}) //数据流 Logf(format string, args ...interface{}) //format 数据流 Name() string Setenv(key, value string) Skip(args ...interface{}) //报告并跳过 [Log + SkipNow] SkipNow() //跳过当前测试 Skipf(format string, args ...interface{})// 报告并跳过 [Logf + SkipNow] Skipped() bool //检测是否跳过 TempDir() string private() }
参考文章:
https://zh.wikipedia.org/wiki/%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95
https://books.studygolang.com/The-Golang-Standard-Library-by-Example/chapter09/09.1.html