一个测试工程师走进一家酒吧……

本文深入探讨了软件测试的重要性,特别是在 Golang 中如何编写有效的测试。介绍了测试的基本概念,如白盒测试、黑盒测试、单元测试、集成测试和回归测试,并通过具体的代码示例展示了如何进行单元测试、子测试和测试分包。文章还提到了一些常用的测试工具,如 testify、sqlmock、mock 和 http/httptest。此外,文章强调了如何写好测试,包括并发测试、正确测试返回值和输入参数,以及如何处理测试覆盖率。最后,文章提醒我们测试覆盖率不等于测试的正确性,不应盲目追求100%覆盖率,而应注重测试的质量和全面性。
摘要由CSDN通过智能技术生成

一个测试工程师走进一家酒吧,要了一杯啤酒;

一个测试工程师走进一家酒吧,要了一杯咖啡;

一个测试工程师走进一家酒吧,要了 0.7 杯啤酒;

一个测试工程师走进一家酒吧,要了-1 杯啤酒;

一个测试工程师走进一家酒吧,要了 2^32 杯啤酒;

一个测试工程师走进一家酒吧,要了一杯洗脚水;

一个测试工程师走进一家酒吧,要了一杯蜥蜴;

一个测试工程师走进一家酒吧,要了一份 asdfQwer@24dg!&*(@;

一个测试工程师走进一家酒吧,什么也没要;

一个测试工程师走进一家酒吧,又走出去又从窗户进来又从后门出去从下水道钻进来;

一个测试工程师走进一家酒吧,又走出去又进来又出去又进来又出去,最后在外面把老板打了一顿;

一个测试工程师走进一家酒吧,要了一杯烫烫烫的锟斤拷;

一个测试工程师走进一家酒吧,要了 NaN 杯 Null;

一个测试工程师冲进一家酒吧,要了 500T 啤酒咖啡洗脚水野猫狼牙棒奶茶;

一个测试工程师把酒吧拆了;

一个测试工程师化装成老板走进一家酒吧,要了 500 杯啤酒并且不付钱;

一万个测试工程师在酒吧门外呼啸而过;

一个测试工程师走进一家酒吧,要了一杯啤酒';DROP TABLE 酒吧;

测试工程师们满意地离开了酒吧。

然后一名顾客点了一份炒饭,酒吧炸了。

上面是网上流行的一个关于测试的笑话,其主要核心思想是——你永远无法把所有问题都充分测试。

在软件工程中,测试是极其重要的一环,比重通常可以与编码相同,甚至大大超过。那么在 Golang 里,怎么样把测试写好,写正确?本文将对这个问题做一些简单的介绍。 当前文章将主要分两个部分:

  • Golang 测试的一些基本写法和工具
  • 如何写“正确”的测试,这个部分虽然代码是用 golang 编写,但是其核心思想不限语言

由于篇幅问题,本文将不涉及性能测试,之后会另起一篇来谈。

测试路上不迷茫:关注微信公众号【程序员小濠】(主要分享软件测试的学习资源,帮助想转行、进阶、小白成为高级测试工程师…软件测试交流群:175317069) 

为什么要写测试

我们举个不太恰当的例子,测试也是代码,我们假定写代码时出现 bug 的概率是 p(0<p<1),那么我们同时写测试的话,两边同时出现 bug 的概率就是(我们认为两个事件相互独立)

P(代码出现 bug) * P(测试出现 Bug) = p^2 < p

例如 p 是 1%的话,那么同时写出现 bug 的概率就只有 0.01%了。

测试同样也是代码,有可能也写出 bug,那么怎么保证测试的正确性呢?给测试也写测试?给测试的测试继续写测试?

我们定义 t(0)为原始的代码,任意的 i,i > 0,t(i+1)为对于 t(i)的测试,t(i+1)正确为 t(i)正确的必要条件,那么对所有的 i,i>0,t(i)正确都是 t(0)正确的必要条件。。。

测试的种类

测试的种类有非常多,我们这里只挑几个对一般开发者来说比较重要的测试,做简略的说明。

白盒测试、黑盒测试

首先是从测试方法上可以分为白盒测试和黑盒测试(当然还存在所谓的灰盒测试,这里不讨论)

  • 白盒测试 (White-box testing):白盒测试又称透明盒测试、结构测试等,软件测试的主要方法之一,也称结构测试、逻辑驱动测试或基于程序本身的测试。测试应用程序的内部结构或运作,而不是测试应用程序的功能。在白盒测试时,以编程语言的角度来设计测试案例。测试者输入数据验证数据流在程序中的流动路径,并确定适当的输出,类似测试电路中的节点。
  • 黑盒测试 (Black-box testing):黑盒测试,软件测试的主要方法之一,也可以称为功能测试、数据驱动测试或基于规格说明的测试。测试者不了解程序的内部情况,不需具备应用程序的代码、内部结构和编程语言的专门知识。只知道程序的输入、输出和系统的功能,这是从用户的角度针对软件界面、功能及外部结构进行测试,而不考虑程序内部逻辑结构。

我们写的单元测试一般属于白盒测试,因为我们对测试对象的内部逻辑有着充分了解。

单元测试、集成测试

从测试的维度上,又可以分为单元测试和集成测试:

  • 在计算机编程中,单元测试又称为模块测试,是针对程序模块来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最小单元就是方法,包括基类、抽象类、或者派生类中的方法。
  • 整合测试又称组装测试,即对程序模块采用一次性或增值方式组装起来,对系统的接口进行正确性检验的测试工作。整合测试一般在单元测试之后、系统测试之前进行。实践表明,有时模块虽然可以单独工作,但是并不能保证组装起来也可以同时工作。

单元测试可以是黑盒测试,集成测试亦可以是白盒测试

回归测试

  • 回归测试是软件测试的一种,旨在检验软件原有功能在修改后是否保持完整。

回归测试主要是希望维持软件的不变性,我们举一个例子来说明。例如我们发现软件在运行的过程中出现了问题,在 gitlab 上开启了一个 issue。之后我们并且定位到了问题,我们可以先写一个测试(测试的名称可以带上 issue 的 ID)来复现问题(该版本代码运行此测试结果失败)。之后我们修复问题后,再次运行测试,测试的结果应当成功。那么我们之后每次运行测试的时候,通过运行这个测试,可以保证同样的问题不会复现。

一个基本的测试

我们先来看一个 Golang 的代码:

// add.go
package add

func Add(a, b int) int {
   return a + b
}
复制代码

一个测试用例可以写成:

// add_test.go
package add

import (
   "testing"
)

func TestAdd(t *testing.T) {
   res := Add(1, 2)
   if res != 3 {
      t.Errorf("the result is %d instead of 3", res)
   }
}
复制代码

在命令行我们使用 go test

go test
复制代码

这个时候 go 会执行该目录下所有的以_test.go 为后缀中的测试,测试成功的话会有如下输出:

% go test
PASS
ok      code.byted.org/ek/demo_test/t01_basic/correct       0.015s
复制代码

假设这个时候我们把 Add 函数修改成错误的实现

 // add.go
package add

func Add(a, b int) int {
   return a - b
}
复制代码

再次执行测试命令

% go test
--- FAIL: TestAddWrong (0.00s)
    add_test.go:11: the result is -1 instead of 3
FAIL
exit status 1
FAIL    code.byted.org/ek/demo_test/t01_basic/wrong 0.006s
复制代码

会发现测试失败。

只执行一个测试文件

那么如果我们想只测试这一个文件,输入

go test add_test.go
复制代码

会发现命令行输出

% go test add_test.go
# command-line-arguments [command-line-arguments.test]
./add_test.go:9:9: undefined: Add
FAIL    command-line-arguments [build failed]
FAIL
复制代码

这是因为我们没有附带测试对象的代码,修改测试后可以获得正确的输出:

% go test add_test.go add.go
ok  
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值