IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> Golang-单元测试 -> 正文阅读

[开发测试]Golang-单元测试

单元测试

针对使用传统方式测试代码块的不足:
1)测试代码块需要在main函数中去调用,需要修改main函数,若项目正在运行,就可能去停止项目,不方便
2)不利于管理,当需要测试多个函数或多个模块时,都需要在main函数,不利于我们管理和清晰思路
3)引出单元测试。testing测试框架,很好解决上述问题。

1. 基本介绍

Go语言自带有一个轻量级的测试框架testing和自带的 go test命令实现单元测试和性能测试。testing框架和其它语言中的测试框架类似,可以基于这个框架写针对相应函数的测试用例,也可以基于该框架写相应的压力测试用例。通过单元测试,可以解决:
1)确保每个函数的是可运行,并且运行结果是正确
2)确保代码的性能是好的
3)单元测试能及时的发现程序设计或实现的逻辑错误,使得问题及时暴露,便于问题的定位和解决;而性能测试的重点在于发现程序设计上的问题,确保程序在高并发的情况下还能保持稳定。

2.单元测试入门案例

Golang中提供了testing包,该包提供对Go包的自动化测试的支持。通过go test命令能够自动执行如下形式的任何函数:

func TestXxx(*testing.T)

  1. 其中 Xxx 可以是任何字母数字字符串(但第一个字母不能是 [a-z],且必须大写),用于识别测试程序。
    2.要编写一个新的测试套件,需要创建一个名称以 _test.go 结尾的文件,该文件包含 TestXxx 函数,如上所述。 将该文件放在与被测试的包相同的包中。该文件将被排除在正常的程序包之外,但在运 行 “go test” 命令时将被包含。

测试原理图:
在这里插入图片描述

入门案例:
使用到testing包中的func (*T) Logffunc (*T) Fatalf

func (*T) Logf
func (c *T) Logf(format string, args …interface{})
Log 使用与 Printf 相同的格式化语法对它的参数进行格式化,然后将格式化后的文本记录到错误日志里面。
1)对于测试来说,Logf 产生的格式化文本只会在测试失败或者设置了 -test.v 标志的情况下被打印出来;

func (*T) Fatalf
func (c *T) Fatalf(format string, args …interface{})
调用 Fatalf 相当于在调用 Logf 之后调用 FailNow 。

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

案例代码:
被测试函数所在文件cal.go

package cal

func addUpper(num int) int {
	res := 0
	for i := 1; i <= num; i++ {
		res += i
	}
	return res
}

func GetSub(n1, n2 int) int {
	res := n2 - n1//计划是n1-n2 故意写错为n2-n1
	return res
}

测试函数cal_test.go

package cal

import "testing"

// 编写测试案案例,测试addUpper是否正确
func TestAddupper(t *testing.T) {
	// 调用
	res := addUpper(10)
	if res != 55 {
		t.Fatalf("addUpper(10) 执行错误,期望值=%v,实际值=%v\n", 55, res)
	}
	// 如果正确,输出日志
	t.Logf("addUpper(10) 执行正确...")
}

func TestGetSub(t *testing.T) {
	res := GetSub(10, 5)
	if res != 5 {
		t.Fatalf("GetSub(10,5) 执行错误,期望值=%v,实际值=%v\n", 5, res)
	}
	t.Logf("GetSub(10,5) 执行正确")

}

运行测试指令:
(1)cmd>go test (如果运行正确,无日志,错误时输出日志)
(2)cmd> go test -v (运行正确或错误都输出日志)
(3)PASS表示测试运行成功,FAIL表示测试失败
(4)测试单个文件,需要带上被测试的原文件:go test -v cal_test.go cal.go
(5)测试单个方法go test -v -test.run TestAddUpper

Output:
E:\goproject\src\go_code\chapter14\testdemo01>go test -v
=== RUN TestAddupper
cal_test.go:13: addUpper(10) 执行正确…
— PASS: TestAddupper (0.00s)
=== RUN TestGetSub
cal_test.go:19: GetSub(10,5) 执行错误,期望值=5,实际值=-5
— FAIL: TestGetSub (0.00s)
FAIL
exit status 1
FAIL go_code/chapter14/testdemo01 0.489s
说明cal.go中GetSub()函数有问题

OutPut
E:\goproject\src\go_code\chapter14\testdemo01>go test
— FAIL: TestGetSub (0.00s)
cal_test.go:19: GetSub(10,5) 执行错误,期望值=5,实际值=-5
FAIL
exit status 1
FAIL go_code/chapter14/testdemo01 0.247s
使用go test命令执行,则出现错误才会显示t.Logf()

案例2:
检测josn序列化和反序列化是否正确。
1)使用ioutil.WriteFile()函数将json字符串写入文件

func WriteFile(filename string, data []byte, perm os.FileMode) error
函数向filename指定的文件中写入数据。如果文件不存在将按给出的权限创建文件,否则在写入数据之前清空文件。因此使用时需谨慎。

2)使用ioutil.ReadFile()函数读取文件中的json信息

func ReadFile(filename string) ([]byte, error)
ReadFile 从filename指定的文件中读取数据并返回文件的内容。成功的调用返回的err为nil而非EOF。因为本函数定义为读取整个文件,它不会将读取返回的EOF视为应报告的错误。

操作代码:
被测文件monster.go

package monster

import (
	"encoding/json"
	"io/ioutil"
	"log"
)

type Monster struct {
	Name  string `json:"name"`
	Age   int    `json:"age,omitempty"`
	Skill string `json:"skill,omitempty"`
}

func (m *Monster) Store() error {
	data, err := json.Marshal(m)
	if err != nil {
		log.Fatal(err)
	}

	// 保存到文件
	filePath := "E:\\goproject\\src\\go_code\\chapter14\\monster.ser"
	// 将json信息写入文件
	ioutil.WriteFile(filePath, data, 0666)
	return err // nil
}

func (m *Monster) Restore() error {
	// 从文件中获得json信息
	filePath := "E:\\goproject\\src\\go_code\\chapter14\\monster.ser"
	data, err := ioutil.ReadFile(filePath)
	if err != nil {
		log.Fatal(err)
	}
	err = json.Unmarshal(data, m)
	if err != nil {
		log.Fatal(err)
	}
	return err
}

测试文件 monster_test.go

package monster

import (
	"testing"
)

var monster = Monster{
	Name:  "红孩儿",
	Age:   1500,
	Skill: "火尖枪",
}

// 测试用例,测试Store方法

func TestStore(t *testing.T) {

	if monster.Store() == nil {
		t.Logf("marshal successfully\n")
	} else {
		t.Logf("marshal fail,err=%v\n", monster.Store())
	}
}

// 测试用例,测试Restore方法
func TestRestore(t *testing.T) {
	monster1 := &Monster{}
	if monster1.Restore() != nil {
		t.Logf("unmarshal fail\n")
	} else {
		if *monster1 == monster {
			t.Logf("Unmarshal successfully\n")
		} else {
			if monster1.Name != monster.Name {
				t.Logf("Unmarshal fail,期望%v, 实际是%v\n", monster.Name, monster1.Name)
			}
			if monster1.Age != monster.Age {
				t.Logf("Unmarshal fail,期望%v, 实际是%v\n", monster.Age, monster1.Age)
			}
			if monster1.Skill != monster.Skill {
				t.Logf("Unmarshal fail,期望%v, 实际是%v\n", monster.Skill, monster1.Skill)
			}

		}

	}

}
  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-12-11 16:01:27  更:2021-12-11 16:02:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/18 6:45:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码