深入掌握 Golang 单元测试与性能测试:从零开始打造高质量代码!

news2024/11/24 15:07:51

在软件开发中,测试是保证代码质量、减少错误的重要环节。Golang 自带了强大的测试工具,不仅支持单元测试,还支持性能测试,让开发者可以轻松进行代码的测试和优化。本文将详细介绍如何在 Go 中进行单元测试和性能测试,帮助快速掌握这些技术。

文章目录

    • 一、什么是单元测试?
      • 1.1 单元测试的基本结构
      • 1.2 如何编写一个简单的单元测试
      • 1.3 运行单元测试
    • 二、表驱动测试
      • 2.1 表驱动测试示例
    • 三、测试覆盖率
    • 四、如何进行性能测试
      • 4.1 基本的性能测试结构
      • 4.2 运行性能测试
    • 五、常用的测试技巧与注意事项
      • 5.1 使用 `t.Helper()` 简化错误信息
      • 5.2 并发测试
      • 5.3 跳过长时间运行的测试
    • 六、总结

在这里插入图片描述

一、什么是单元测试?

单元测试是对代码中的最小可测试单元(如函数、方法)进行验证的测试方法。通过编写测试用例,我们可以确保函数在不同输入情况下能正确输出预期结果,避免代码中的逻辑错误。

1.1 单元测试的基本结构

在 Go 中,单元测试通常放在与被测试代码相同的包中,测试文件以 _test.go 结尾。例如,若我们要测试 math.go 中的函数,则测试文件应命名为 math_test.go

每个测试函数的名称必须以 Test 开头,并接收一个参数 t *testing.T,用于控制测试的执行流程并记录测试失败信息。基本结构如下:

func Test函数名(t *testing.T) {
    // 测试代码
}

1.2 如何编写一个简单的单元测试

假设我们有一个函数 Add 用于两个整数相加:

// math.go
package math

func Add(a, b int) int {
    return a + b
}

我们可以为其编写如下测试代码:

// math_test.go
package math

import "testing"

func TestAdd(t *testing.T) {
    result := Add(2, 3)
    expected := 5
    if result != expected {
        t.Errorf("Add(2, 3) = %d; want %d", result, expected)
    }
}

在这个测试函数中,我们调用 Add(2, 3),并将结果与期望值 5 进行比较。如果不匹配,测试将失败,并输出错误信息。

1.3 运行单元测试

要运行 Go 的单元测试,可以使用以下命令:

go test

这将运行当前包中的所有测试函数。如果测试通过,控制台将显示 ok;如果失败,会显示具体的错误信息。

还可以使用 -v 选项查看每个测试的详细输出:

go test -v

二、表驱动测试

在 Go 中,表驱动测试是一种常见的编写测试用例的方式,特别适合处理多组输入和输出情况。我们可以通过表格的方式定义不同的输入参数和期望结果,然后遍历这个表来执行测试。

2.1 表驱动测试示例

让我们为 Add 函数编写表驱动测试:

func TestAdd(t *testing.T) {
    tests := []struct {
        a, b     int
        expected int
    }{
        {2, 3, 5},
        {1, 1, 2},
        {0, 0, 0},
        {-1, 1, 0},
    }

    for _, tt := range tests {
        result := Add(tt.a, tt.b)
        if result != tt.expected {
            t.Errorf("Add(%d, %d) = %d; want %d", tt.a, tt.b, result, tt.expected)
        }
    }
}

这里,我们定义了一个包含不同测试数据的结构体切片 tests,然后使用 for 循环依次执行每组测试。

三、测试覆盖率

测试覆盖率表示代码被测试的程度。通过 go test -cover 命令可以查看代码的覆盖率。

go test -cover

还可以生成详细的覆盖率报告:

go test -coverprofile=coverage.out
go tool cover -html=coverage.out

这将生成一个 HTML 文件,展示每行代码的覆盖情况,帮助我们发现未被测试的代码。

四、如何进行性能测试

性能测试(也叫基准测试)用于评估代码的性能,帮助开发者优化代码。Go 提供了 testing.B 结构来编写基准测试,通常用于测量某段代码的执行时间。

4.1 基本的性能测试结构

性能测试函数的名称以 Benchmark 开头,接收 b *testing.B 参数。Go 会根据测试函数的复杂度自动调整运行次数,并输出每次操作的平均时间。

func BenchmarkAdd(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Add(2, 3)
    }
}

4.2 运行性能测试

要运行性能测试,可以使用以下命令:

go test -bench=.

这将执行所有基准测试并输出结果,b.N 表示测试的迭代次数,运行结果会显示每次操作的平均耗时。

五、常用的测试技巧与注意事项

5.1 使用 t.Helper() 简化错误信息

当我们在辅助函数中调用测试函数时,使用 t.Helper() 可以使测试输出的错误信息更加简洁,直接指向调用辅助函数的地方,而不是在辅助函数中显示错误。

func assertEqual(t *testing.T, result, expected int) {
    t.Helper()
    if result != expected {
        t.Errorf("result = %d; want %d", result, expected)
    }
}

5.2 并发测试

在 Go 中,经常需要测试并发代码的性能或正确性。我们可以利用 testing.T 提供的并发支持功能来编写并发测试:

func TestConcurrentAdd(t *testing.T) {
    go Add(2, 3)
    go Add(4, 5)
}

5.3 跳过长时间运行的测试

对于一些可能需要较长时间运行的测试,我们可以通过 t.Skip() 跳过这些测试,例如仅在生产环境中运行某些耗时的操作:

func TestLongRunning(t *testing.T) {
    if testing.Short() {
        t.Skip("Skipping long-running test")
    }
    // 长时间运行的代码
}

六、总结

本文详细介绍了 Go 语言中单元测试与性能测试的基本方法和技巧。单元测试帮助我们确保代码的正确性,而性能测试则能优化代码的运行效率。通过编写良好的测试,我们可以提升程序的健壮性,减少运行时错误,并优化性能。

希望本文对你有所帮助,让大家可以更好地掌握 Go 语言的测试机制。测试是开发中的重要一环,掌握这些技能将为你的编程之路打下坚实的基础。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2194735.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Codeforces Round 969 (Div. 1) B. Iris and the Tree

题目 题解&#xff1a; #include <bits/stdc.h> using namespace std; #define int long long #define pb push_back #define fi first #define se second #define lson p << 1 #define rson p << 1 | 1 #define ll long long #define pii pair<int, int&…

(JAVA)开始熟悉 “二叉树” 的数据结构

1. 二叉树入门 ​ 符号表的增删查改操作&#xff0c;随着元素个数N的增多&#xff0c;其耗时也是线性增多的。时间复杂度都是O(n)&#xff0c;为了提高运算效率&#xff0c;下面将学习 树 这种数据结构 1.1 树的基本定义 ​ 树是我们计算机中非常重要的一种数据结构&#xf…

C语言刷题--数数一个数的二进制里有几个‘1’

先来看一下左移、右移 左移 右移 题目解答 1是一个特殊的数&#xff0c;二进制是000000000000000000000001(32位机器) 假如要判断的数是0&#xff08;二进制里面没有1&#xff09; 000000000000000000000000 & 000000000000000000000001 结果为0&#xff1b; 假如要…

基于FPGA的多路视频缓存

对于多路视频传输的场合&#xff0c;需要正确设置同步。 uifdma_dbuf0 的写通道输出帧同步计数器直接接入 uifdma_dbuf0&#xff0c;uifdma_dbuf1, uifdma_dbuf2, uifdma_dbuf3 的写通道同步计数输入。uifdma_dbuf0 的读通道&#xff0c;延迟 1 帧于 uifdma_dbuf0 的写通道帧计…

初入网络学习第一篇

引言 不磨磨唧唧&#xff0c;跟着学就好了&#xff0c;这个是我个人整理的学习内容梳理&#xff0c;学完百分百有收获。 1、使用的网络平台:eNSP 下载方法以及内容参考这篇文章 华为 eNSP 模拟器安装教程&#xff08;内含下载地址&#xff09;_ensp下载-CSDN博客https://b…

javaScript操作元素(9个案例+代码+效果)

目录 1.innerHTML 案例:使用innerHTML修改文本内容 1.代码 2.效果 2.innerText 案例:使用innerText修改文本 1.代码 2.效果 3.textContent 案例:使用textContent修改文本 1.代码 2.效果 4.通过style属性操作样式 案例:改变小球颜色 1.代码 2.效果 5.通过className属性操作样式 …

【Iceberg分析】Spark集成Iceberg采集输出

Spark集成Iceberg采集输出 文章目录 Spark集成Iceberg采集输出Iceberg提供了两类指标和提供了两类指标输出器ScanReportCommitReport LoggingMetricsReporterRESTMetricsReporter验证示例相关环境配置结果说明 Iceberg提供了两类指标和提供了两类指标输出器 ScanReport 包含在…

基于SpringBoot+Uniapp的家庭记账本微信小程序系统设计与实现

项目运行截图 展示效果图 展示效果图 展示效果图 展示效果图 展示效果图 5. 技术框架 5.1 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更…

Three.js基础内容(二)

目录 一、模型 1.1、组对象Group和层级模型(树结构) 1.2、递归遍历模型树结构、查询具体模型节点(楼房案例) 1.3、本地(局部)坐标和世界坐标 1.4、改变模型相对局部坐标原点位置 1.5、移除对象.remove() 1.6、模型隐藏与显示 二、纹理 2.1、创建纹理贴图(TextureLoade…

005集—— 用户交互之CAD窗口选择图元实体(CAD—C#二次开发入门)

如下图&#xff1a;根据提示选择若干图形要素&#xff0c;空格或右键结束选择&#xff0c;返回图元的objectid&#xff0c;以便进一步操作图元实体。 代码如下&#xff1a; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.Aut…

嘉兴儿童自闭症寄宿学校独特教育模式探秘

自闭症&#xff08;孤独症&#xff09;儿童的教育问题一直是社会关注的焦点。如何为这些特殊的孩子提供一个安全、稳定且充满爱的成长环境&#xff0c;成为了许多家庭的期盼。在众多自闭症儿童教育机构中&#xff0c;广州的星贝育园自闭症儿童寄宿制学校以其独特的教育模式和全…

Keycloak 获取token 用户信息

进入Clients菜单&#xff0c;选择Client ID找到Access settings 》Direct access grants 将Direct access grants勾选Postmans URL输入地址&#xff1a;{IP}:{prot}/realms/{ realms }/protocol/openid-connect/token 例&#xff1a;http://10.18.11.3:31873/realms/master/pro…

Centos7 NTP客户端

目录 1. NTP客户端1.1 安装1.2 启动1.3 同步状态异常1.4 更改/etc/chrony.conf配置文件1.5 同步状态正常 1. NTP客户端 1.1 安装 如果chrony没有安装&#xff0c;可以使用以下命令安装 sudo yum install chrony1.2 启动 启动并设置开机自启 sudo systemctl start chronyd …

【Matlab学习日记】② 常用滤波以及噪声分析方法(上)

关注星标公众号&#xff0c;不错过精彩内容 作者 | 量子君 微信公众号 | 极客工作室 【Matlab学习日记】专栏目录 第一章 ① Sinmulink自动代码生成教程 第二章 ② 常用滤波以及噪声分析方法&#xff08;上&#xff09; 文章目录 前言一、使用滤波的目的二、常见的几种噪声和表…

棋牌灯控计时计费系统软件免费试用版怎么下载 佳易王计时收银管理系统操作教程

一、前言 【试用版软件下载&#xff0c;可以点击本文章最下方官网卡片】 棋牌灯控计时计费系统软件免费试用版怎么下载 佳易王计时收银管理系统操作教程 棋牌计时计费软件的应用也提升了顾客的服务体验&#xff0c;顾客可以清晰的看到自己的消费时间和费用。增加了消费的透明…

免费高可用软件

高可用软件是指那些能够提供高可用性、高可靠性的软件&#xff0c;它们在各种应用场景下都能确保系统的稳定运行。以下是四款免费的高可用软件&#xff0c;它们在不同领域都表现出色&#xff0c;能够满足各种高可用性需求。 一、PanguHA PanguHA是一款专为Windows平台设计的双…

数据分析之Spark框架介绍

文章目录 概述一、发展历程与背景二、核心特点三、生态系统与组件四、应用场景五、与其他大数据技术的比较 核心概念1. 弹性分布式数据集&#xff08;RDD, Resilient Distributed Dataset&#xff09;2. 转换&#xff08;Transformations&#xff09;和动作&#xff08;Actions…

python jpg 简单研究 1

起因&#xff0c; 目的: 就是想看看 jpg 里面有什么。 其实&#xff0c;我最开始的想法是&#xff0c;自己来写一个文件格式&#xff0c;只能我自己才能打开。 然后看了 jpg 相关的内容&#xff0c;发现太复杂&#xff0c;只能罢了。 1. jpg 的魔法头数字&#xff08;File Ma…

蝶形激光器驱动(温控精度0.002°C 激光电流分辨率5uA)

蝶形半导体激光器驱动电流的稳定性直接决定了其输出波长的稳定性,进而影响检测精度.为了满足气体浓度检测中对激光器输出波长稳定可调的要求,设计了数字与模拟电路混合的恒流驱动电路.STM32为主控芯片数控模块完成扫描AD/DA转换;模拟电路主要由负反馈运算放大、高精度CMOS管和反…

《向量数据库指南》揭秘:Mlivus Cloud如何借Fivetran Partner SDK实现数据飞跃

哈哈,各位向量数据库领域的同仁们,今天咱们来聊聊 Fivetran 的 Partner SDK 如何助力技术供应商构建自定义连接器和目标,特别是与 Mlivus Cloud 的集成,这可是个热门话题啊! Fivetran 的 Partner SDK,简直就是为技术供应商量身打造的“神器”。有了它,你就可以轻松地为…