Go-单元测试详解与代码

简介: Go-单元测试详解与代码

概述

常言道,不会测试的程序猿不是好的产品经理!!!现在越来越多测试和运维的工作也需要研发来做了,本篇文章就来讲讲Go的单元测试

单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。简单说,就是将测试用例的运行结果与预期结果进行比较。

Go的单元测试

基础知识

Go有testing测试包,配合go test命令能够进行单元测试。

  1. 测试文件以_test.go结尾
  2. 在包目录内,所有以_test.go为后缀名的源代码文件都是go test测试的一部分,不会被go build编译到最终的可执行文件中。
  3. _test.go文件包含TestXxx函数
  4. 形参类型必须为*test.T
  5. PASS表示测试用例运行成功,FAIL表示失败

个人常用Fatalf,这里就来具体说一下,其他函数见参考的链接。

func (c *T) Logf(format string, args ...interface{})

Log 使用与 Printf 相同的格式化语法对它的参数进行格式化,然后将格式化后的文本记录到错误日志里面。 如果输入的格式化文本最末尾没有出现新行,那么将一个新行添加到格式化后的文本末尾。

1)对于测试来说,Logf 产生的格式化文本只会在测试失败或者设置了 -test.v 标志的情况下被打印出来;

2)对于基准测试来说,为了避免 -test.v 标志的值对测试的性能产生影响,Logf 产生的格式化文本总会被打印出来

func (c *T) FailNow()

将当前测试标识为失败并停止执行该测试,在此之后,测试过程将在下一个测试或者下一个基准测试中继续。


FailNow 必须在运行测试函数或者基准测试函数的 goroutine 中调用,而不能在测试期间创建的 goroutine 中调用。调用 FailNow 不会导致其他 goroutine 停止。

func (c *T) Fatalf(format string, args ...interface{})

调用 Fatalf 相当于在调用 Logf 之后调用 FailNow 。

快速入门

项目结构

learnGo

└── main

   ├── compute.go

   └── compute_test.go

compute.go

package main
import "errors"
func div(a,b int) (int,error) {
  if b != 0{
    return a/b,nil
  } else{
    return 0,errors.New("b is 0")
  }
}

compute_test.go

package main
import "testing"
func TestDiv(t *testing.T)  {
  res,_ := div(4,2)
  want := 2
  if res != want{
    t.Fatalf("期待:%d ,实际结果:%d",want,res)
  }
}

main目录下运行

go test -v

结果如下:

=== RUN   TestDiv
--- PASS: TestDiv (0.00s)
PASS
ok      learnGo/main    0.457s

以上我们就针对main包的compute.go文件进行了单元测试。

进阶

查看更多的选项,可使用

go help test
go help testflag

单个文件的测试

我们在main包中再添加str.go及str_test.go

str.go

package main
func getSub(str string,start,end int) string {
  // 左闭右闭
  if 0<=start&&start<end&&end<=len(str){
    return str[start:end]
  }else{
    return ""
  }
}

str_test.go

package main
import "testing"
func TestGetSub(t *testing.T)  {
  astr := "lady_killer9"
  // 包含开头
  res1 := getSub(astr,0,4)
  want1 := "lady"
  // 包含结尾
  res2 := getSub(astr,4,len(astr))
  want2 := "_killer9"
  // 范围错误
  res3 := getSub(astr,1,len(astr)+1)
  want3 := ""
  if res1 != want1{
    t.Errorf("期望:%s,实际结果:%s",want1,res1)
  }
  if res2 != want2{
    t.Errorf("期望:%s,实际结果:%s",want2,res2)
  }
  if res3 != want3{
    t.Errorf("期望:%s,实际结果:%s",want3,res3)
  }
}

运行 go test -v,得到结果如下

=== RUN   TestDiv
--- PASS: TestDiv (0.00s)
=== RUN   TestGetSub
--- PASS: TestGetSub (0.00s)
PASS
ok      learnGo/main    0.446s

go test会运行所有的单元测试,有时候我们只想测试某个文件

如果只是运行一个测试文件,可添加参数

go test -v 测试文件 源文件

运行go test -v str_test.go str.go, 结果如下:

=== RUN   TestGetSub
--- PASS: TestGetSub (0.00s)
PASS
ok      command-line-arguments  0.619s

单个函数的测试

我们在compute.go中添加

1. func add(a,b int) int {
2.  return a+b
3. }

在compute_test.go中添加

func TestAdd(t *testing.T)  {
  a,b:=3,4
  res := add(a,b)
  want := 7
  if res != want{
    t.Fatalf("期待:%d,实际结果:%d",want,res)
  }
}

由于对div函数未做改动,只想测试add函数,可以使用参数-test.run指定测试函数

go test -v -test.run 测试函数

运行 go test -v -test.run TestAdd 结果如下:

=== RUN   TestAdd
--- PASS: TestAdd (0.00s)
PASS
ok      learnGo/main    0.836s

单元测试覆盖率

测试应该全面,达到100%。

可以使用-cover参数

go test -cover

结果如下:

PASS
coverage: 85.7% of statements
ok      learnGo/main    0.505s

可以看到,测试的并不全面,指定测试文件来查看。

go test -cover compute_test.go compute.go

ok      command-line-arguments  0.314s  coverage: 75.0% of statements

观察发现,我们缺少了b为0的分支,修改TestDiv函数为

func TestDiv(t *testing.T)  {
  res,_ := div(4,2)
  want := 2
  if res != want{
    t.Fatalf("期待:%d,实际结果:%d",want,res)
  }
  res,_ = div(3,0)
  want = 0
  if res != want{
    t.Fatalf("期待:%d,实际结果:%d",want,res)
  }
}

测试后再看覆盖率,结果如下

PASS
coverage: 100.0% of statements
ok      learnGo/main    0.306s

作为开发,基本的单元测试就可以了,还可以去了解基准测试、性能测试、压力测试、黑盒测试等。

参考

Go标准库-testing

更多Go相关内容:Go-Golang学习总结笔记

有问题请下方评论,转载请注明出处,并附有原文链接,谢谢!如有侵权,请及时联系。


相关文章
|
1月前
|
数据采集 机器学习/深度学习 大数据
行为检测代码(一):超详细介绍C3D架构训练+测试步骤
这篇文章详细介绍了C3D架构在行为检测领域的应用,包括训练和测试步骤,使用UCF101数据集进行演示。
43 1
行为检测代码(一):超详细介绍C3D架构训练+测试步骤
|
1月前
|
机器学习/深度学习 人工智能 监控
提升软件质量的关键路径:高效测试策略与实践在软件开发的宇宙中,每一行代码都如同星辰般璀璨,而将这些星辰编织成星系的过程,则依赖于严谨而高效的测试策略。本文将引领读者探索软件测试的奥秘,揭示如何通过精心设计的测试方案,不仅提升软件的性能与稳定性,还能加速产品上市的步伐,最终实现质量与效率的双重飞跃。
在软件工程的浩瀚星海中,测试不仅是发现缺陷的放大镜,更是保障软件质量的坚固防线。本文旨在探讨一种高效且创新的软件测试策略框架,它融合了传统方法的精髓与现代技术的突破,旨在为软件开发团队提供一套系统化、可执行性强的测试指引。我们将从测试规划的起点出发,沿着测试设计、执行、反馈再到持续优化的轨迹,逐步展开论述。每一步都强调实用性与前瞻性相结合,确保测试活动能够紧跟软件开发的步伐,及时适应变化,有效应对各种挑战。
|
2月前
|
Web App开发 JavaScript 前端开发
添加浮动按钮点击滚动到网页底部的纯JavaScript演示代码 IE9、11,Maxthon 1.6.7,Firefox30、31,360极速浏览器7.5.3.308下测试正常
添加浮动按钮点击滚动到网页底部的纯JavaScript演示代码 IE9、11,Maxthon 1.6.7,Firefox30、31,360极速浏览器7.5.3.308下测试正常
|
14天前
|
测试技术 Go
go语言中测试工具
【10月更文挑战第22天】
27 4
|
18天前
|
安全 Go 开发者
代码之美:Go语言并发编程的优雅实现与案例分析
【10月更文挑战第28天】Go语言自2009年发布以来,凭借简洁的语法、高效的性能和原生的并发支持,赢得了众多开发者的青睐。本文通过两个案例,分别展示了如何使用goroutine和channel实现并发下载网页和构建并发Web服务器,深入探讨了Go语言并发编程的优雅实现。
32 2
|
2月前
|
SQL JavaScript 前端开发
基于Python访问Hive的pytest测试代码实现
根据《用Java、Python来开发Hive应用》一文,建立了使用Python、来开发Hive应用的方法,产生的代码如下
70 6
基于Python访问Hive的pytest测试代码实现
|
2月前
|
Java C++
代码文件间重复性测试
本文介绍了如何使用代码相似性检测工具simian来找出代码文件中的重复行,并通过示例指令展示了如何将检测结果输出到指定的文本文件中。
|
1月前
|
JSON 搜索推荐 Go
ZincSearch搜索引擎中文文档及在Go语言中代码实现
ZincSearch官网及开发文档均为英文,对非英语用户不够友好。GoFly全栈开发社区将官方文档翻译成中文,并增加实战经验和代码,便于新手使用。本文档涵盖ZincSearch在Go语言中的实现,包括封装工具库、操作接口、统一组件调用及业务代码示例。官方文档https://zincsearch-docs.zinc.dev;中文文档https://doc.goflys.cn/docview?id=41。
|
2月前
|
测试技术 UED
软件测试的艺术:从代码到品质的探索之旅
在数字时代的浪潮中,软件已成为我们生活和工作不可或缺的一部分。然而,高质量的软件背后隐藏着一门鲜为人知的艺术——软件测试。本文将带你走进这门艺术的世界,从基础理论到实践应用,一起探索如何通过软件测试保障产品质量,提升用户体验,并最终实现从代码到品质的华丽转变。
|
2月前
|
敏捷开发 安全 测试技术
软件测试的艺术:从代码到用户体验的全方位解析
本文将深入探讨软件测试的重要性和实施策略,通过分析不同类型的测试方法和工具,展示如何有效地提升软件质量和用户满意度。我们将从单元测试、集成测试到性能测试等多个角度出发,详细解释每种测试方法的实施步骤和最佳实践。此外,文章还将讨论如何通过持续集成和自动化测试来优化测试流程,以及如何建立有效的测试团队来应对快速变化的市场需求。通过实际案例的分析,本文旨在为读者提供一套系统而实用的软件测试策略,帮助读者在软件开发过程中做出更明智的决策。