Go单元测试示例

example/
|--division.go
|--division_test.go

为什么被测试文件和测试文件通常放到同一个文件夹下以及同一个声明包里

通常情况下,我们把被测试的文件与另外写的测试文件放到同一个声明包里面,称为包内测试

当然也可以把测试函数的文件放到独立的一个包里面,称为包外测试

不过,包外测试源码文件存在一个弊端,那就是在它们的测试函数中无法测试被测源码文件中的包级私有的程序实体,比如包级私有的变量函数结构体类型。这是因为这两者的所属代码包是不相同的。所以,一般很少会编写包外测试源码文件。

单元测试规则

  • 测试文件名必须是_test.go结尾的,这样在执行go test的时候才会执行到相应的代码
  • 你必须import testing这个包
  • 所有的测试用例函数必须是Test开头
  • 测试用例会按照源代码中写的顺序依次执行
  • 测试函数TestXxx(t *testing.T)只有一个参数 t, 可以用 t 记录错误或者是测试状态
  • 测试函数的格式:func TestXxx (t *testing.T),Xxx部分可以为任意的字母数字的组合,但是首字母不能是小写字母[a-z],例如Testintdiv是错误的函数名。
  • 函数中通过调用testing.T的Error, Errorf, FailNow, Fatal, FatalIf方法,说明测试不通过,调用Log方法用来记录测试的信息。

单元测试写法

两种写法:自己手写、借助工具生成

方法1:自己手写

等待被测试的文件 division.go 如下,需要在同一个包里写一个测试文件命名为mydivision_test.go

 1 package math
2
3 import (
4 "errors"
5 )
6
7 func Division(a, b float64) (float64, error) {
8 if b == 0 {
9 return 0, errors.New("除数不能为0")
10 }
11
12 return a / b, nil
13 }

直接自己撸测试函数,这样比较灵活想怎么测就怎么测

mydivision_test.go

 1 package math
2
3 import (
4 "testing"
5 )
6
7 //用例1
8 func Test_Division_1(t *testing.T) {
9 if i, e := Division(6, 2); i != 3 || e != nil {
10 t.Error("除法函数测试没通过") // 如果不是如预期的那么就报错
11 } else {
12 t.Log("第一个测试通过了") //记录一些你期望记录的信息
13 }
14 }
15 //用例2
16 func Test_Division_2(t *testing.T) {
17 t.Error("执行t.Error分支就会提示测试失败")
18 }

运行命令go test -v .结果如下

$ go test  -v .
=== RUN Test_Division_1
--- PASS: Test_Division_1 (0.00s)
mydivision_test.go:11: 第一个测试通过了
=== RUN Test_Division_2
--- FAIL: Test_Division_2 (0.00s)
mydivision_test.go:16: 执行t.Error分支就会提示测试失败
FAIL
exit status 1
FAIL mytest/goTest 0.001s

方法二:借助工具生成

步骤:

  1. 先安装gotests工具包:  go get -v github.com/cweill/gotests/...
  2. 运行命令gotests -all -w .为当前目录所有文件生成对应测试文件

结果为division.go生成了division_test.go文件如下,生成文件的默认前缀为对应的原文件名

division_test.go,然后留出一片“// TODO: Add test cases.”区域来填用例

 1 package math
2
3 import "testing"
4
5 func TestDivision(t *testing.T) {
6 type args struct {
7 a float64
8 b float64
9 }
10 tests := []struct {
11 name string //用例名字
12 args args //传给被测函数的参数
13 want float64 //预期返回结果
14 wantErr bool //用bool方便判断是否返回error,如果类型改为error反而不好判断
15 }{
16 // TODO: Add test cases.
17 {"case 0", args{6, 2}, 3, false},
18 {"case 1", args{6, 0}, 0, true},//注意第二个用例是会返回error的,因为除数不能为0,所以此处wantErr为true
19 }
20 for _, tt := range tests {
21 t.Run(tt.name, func(t *testing.T) {
22 got, err := Division(tt.args.a, tt.args.b)
23 if (err != nil) != tt.wantErr {
24 t.Errorf("Division() error = %v, wantErr %v", err, tt.wantErr)
25 return
26 }
27 if got != tt.want {
28 t.Errorf("Division() = %v, want %v", got, tt.want)
29 }
30 })
31 }
32 }

运行结果
两个用例都通过了测试

$ go test -v .
=== RUN TestDivision
=== RUN TestDivision/case_0
=== RUN TestDivision/case_1
--- PASS: TestDivision (0.00s)
--- PASS: TestDivision/case_0 (0.00s)
--- PASS: TestDivision/case_1 (0.00s)
PASS
ok mytest/goTest 0.001s

Go语言编写单元测试用例的更多相关文章

  1. JUint4的下载、配置及对一个算法编写单元测试用例(测试多组数据每组多个参数)

    一.JUnit4 jar包下载 链接:https://pan.baidu.com/s/1AdeVGGikcY5dfL151ZnWHA 提取码:h1am 下载完成后,解压一下即可. 二.导入JUnit4 ...

  2. 最完整的自动化测试流程:Python编写执行测试用例及定时自动发送最新测试报告邮件

    今天笔者就要归纳总结下一整套测试流程,从无到有,实现零突破,包括如何编写测试用例,定时执行测试用例,查找最新生成的测试报告文件,自动发送最新测试报告邮件,一整套完整的测试流程.以后各位只要着重如何编写 ...

  3. Selenium 2自动化测试实战29(组织单元测试用例和discover更多测试用例)

    一.组织单元测试用例 看看unittest单元测试框架是如何扩展和组织新增的测试用例以之前的calculator.py文件为例,为其扩展sub()方法,用来计算两个数相减的结果. #coding:ut ...

  4. 基于php基础语言编写的小程序之计算器

    基于php基础语言编写的小程序之计算器 需求:在输入框中输入数字进行加.减.乘.除运算(html+php) 思路: 1首先要创建输入数字和运算符的输入框,数字用input的text属性,运算符用sel ...

  5. 如何用C语言编写病毒‘

    怎样用C语言编写病毒在分析病毒机理的基础上,用C语言写了一个小病毒作为实例,用TURBOC2.0实现.[Abstract] This paper introduce the charateristic ...

  6. 【转】SpringTest框架JUnit单元测试用例获取ApplicationContext实例的方法

    转自:http://www.coderli.com/junit-spring-test-applicationcontext JUnit单元测试用例中使用Spring框架,直接方式如下. @RunWi ...

  7. 选择使用c语言编写的phalcon框架

    使用这个框架,我总结了如下几点考虑 1.这个框架速度快.纯c语言编写的框架,速度都比php框架快,省去了中间环节.当然,使用它不仅仅是性能考虑.因为如果为了解决php性能问题,完全可以有很多种方式,不 ...

  8. 教你快速写出多线程Junit单元测试用例 - GroboUtils

    摘自: http://mushiqianmeng.blog.51cto.com/3970029/897786/ 本文出自One Coder博客,转载请务必注明出处: http://www.coderl ...

  9. [改善Java代码]易变业务使用脚本语言编写

    建议16: 易变业务使用脚本语言编写 Java世界一直在遭受着异种语言的入侵,比如PHP.Ruby.Groovy.JavaScript等,这些“入侵者”都有一个共同特征:全是同一类语言—脚本语言,它们 ...

  10. 运用Python语言编写获取Linux基本系统信息(三):Python与数据库编程,把获取的信息存入数据库

    运用Python语言编写获取Linux基本系统信息(三):Python与数据库编程 有关前两篇的链接: 运用Python语言编写获取Linux基本系统信息(一):获得Linux版本.内核.当前时间 运 ...

随机推荐

  1. 使用Jackson读取xml

    找了不少,什么峰的,什么dn的参差不齐的资料,废话不少,问题是导入的包也没有.不多废话,看下面代码直接复用. package bean;import com.fasterxml.jackson.dat ...

  2. 推荐5款免费、开箱即用的Vue后台管理系统模板

    前言 在现今的软件开发领域,Vue凭借其高效.灵活和易于上手的特性,成为了前端开发的热门选择.对于需要快速搭建企业级后台管理系统的开发者而言,使用现成的Vue后台管理系统模板无疑是一个明智之举.本文大 ...

  3. Viper:强大的Go配置解析库

    1 介绍 Viper是适用于Go应用程序的完整配置解决方案.它被设计用于在应用程序中工作,并且可以处理所有类型的配置需求和格式.目前Star 26.6k, 它支持以下特性: 设置默认值 从JSON.T ...

  4. kafka 运维

    查看kafka topic列表 #集群需要先执行unset JMX_PORT ./kafka-topics.sh --zookeeper gitee-zookeeper:2181 --list 查看t ...

  5. nginx配置请求头防止点击劫持

    在返回index.html配置中加入add_header X-Frame-Options DENY; location / {undefined root /data/nginx/html/dist/ ...

  6. JavaScript设计模式样例二十 —— 中介者模式

    中介者模式(Mediator Pattern) 定义:用来降低多个对象和类之间的通信复杂性.目的:用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独 ...

  7. JVM深入学习-ClassLoader篇(一)

    初识JVM --- ClassLoader深入理解 ClassLoader.SPI机制 Class对象的理解 java在诞生之初,就有一次编译到处运行的名言,今天我们来探究一下,从java代码到cla ...

  8. C# 获取PDF页面大小、方向、旋转角度

    在处理PDF文件时,了解页面的大小.方向和旋转角度等信息对于PDF的显示.打印和布局设计至关重要.本文将介绍如何使用免费.NET 库通过C#来读取PDF页面的这些属性. C# 读取PDF页面大小(宽度 ...

  9. 无分号js风格注意的三个问题

    建议如果一行代码是以   (   [   `  开头的,则最好都在其前面补上一个分号. // 1.( function say() { console.log('hello world') } // ...

  10. 【openGauss】运维常用的SQL

    一.查模式 SELECT pn.oid AS schema_oid, iss.catalog_name, iss.schema_owner, iss.schema_name FROM informat ...