青少年编程与数学 02-004 Go语言Web编程 20课题、单元测试
青少年编程与数学 02-004 Go语言Web编程 20课题、单元测试
- 一、单元测试(Unit Testing)
- 二、集成测试(Integration Testing)
- 三、区别
- 四、Go Web单元测试
- 使用`testing`包
- 使用`testify`框架
- 使用`GoConvey`框架
- 五、应用示例
- 步骤 1: 创建HTTP服务器
- 步骤 2: 创建测试文件
- 步骤 3: 运行测试
- 解释
课题摘要:本文讨论了单元测试和集成测试的概念、特点、区别以及在Go Web应用中的实践。单元测试关注于验证代码的最小可测试单元,如函数或方法,而集成测试则验证不同软件模块或组件在组合后能否正确协同工作。两者的主要区别在于测试范围、环境、数据、复杂性、执行速度、依赖性、目的、自动化程度和成本。文章提供了使用Go标准库
testing包、testify框架和GoConvey框架进行单元测试的步骤和示例代码。最后,通过一个Go Web应用单元测试的示例,展示了如何编写和运行单元测试来验证HTTP服务器的路由处理函数。这些内容有助于提高代码的可维护性、可读性和可靠性。
一、单元测试(Unit Testing)
单元测试(Unit Testing)是软件开发过程中的一种测试方法,它关注于验证代码的最小可测试单元(通常是函数或方法)的正确性。单元测试的目的是隔离代码的一部分并验证其行为,确保每个小部分按预期工作。以下是单元测试的一些关键点:
-
测试单元:
- 单元测试通常针对单个函数或方法,测试它们在各种输入条件下的行为。
-
隔离性:
- 单元测试应该在隔离的环境中运行,不依赖于外部系统、数据库或网络资源。
-
自动化:
- 单元测试通常是自动化的,可以通过测试框架(如JUnit、pytest、NUnit等)自动执行。
-
可重复性:
- 无论何时何地运行,单元测试都应该产生相同的结果。
-
快速执行:
- 单元测试应该快速执行,以便频繁地运行它们,特别是在代码变更后。
-
覆盖率:
- 单元测试应该覆盖代码的大部分逻辑路径,以确保代码的稳定性和可靠性。
-
测试用例:
- 每个单元测试都是一个测试用例,它验证特定的功能或代码路径。
-
断言:
- 单元测试使用断言(Assertions)来验证代码的实际输出与预期输出是否一致。
-
测试数据:
- 单元测试使用模拟数据或测试桩(Stubs)来模拟外部依赖,以保持测试的独立性。
-
测试驱动开发(TDD):
- 单元测试是测试驱动开发(Test-Driven Development, TDD)实践的核心,TDD要求先编写测试,然后编写通过这些测试的代码。
-
持续集成(CI):
- 单元测试是持续集成流程的一部分,每次代码提交后都会自动运行单元测试,以确保新代码不会破坏现有功能。
-
代码质量:
- 单元测试有助于提高代码质量,通过早期发现缺陷,减少后期修复的成本。
单元测试是软件开发中的一个重要实践,它有助于提高代码的可维护性、可读性和可靠性。通过编写和维护单元测试,开发者可以更有信心地进行代码重构和扩展。
二、集成测试(Integration Testing)
集成测试(Integration Testing)是软件测试的一种类型,主要目的是验证不同软件模块或组件在组合在一起时能否正确地协同工作。集成测试通常在单元测试之后进行,确保各个独立的部分在集成后能够按照预期的功能和性能要求运行。
以下是集成测试的一些关键特点:
-
测试组合:
- 集成测试检查两个或多个已经单独测试过的模块(单元)在组合后是否能够正常工作。
-
接口测试:
- 重点测试模块间的接口,确保它们能够正确地传递数据和控制信号。
-
协同工作:
- 验证不同模块的集成点(即接口)是否能够正确地协同工作,没有冲突和错误。
-
逐步集成:
- 可以采用不同的集成策略,如自顶向下集成、自底向上集成或大爆炸集成。
-
复杂性:
- 集成测试比单元测试复杂,因为它涉及到多个模块的交互和依赖关系。
-
环境模拟:
- 集成测试通常需要模拟或实际使用外部资源,如数据库、文件系统或网络服务。
-
错误检测:
- 集成测试能够检测到模块间接口不匹配、数据传递错误、控制流问题等。
-
性能验证:
- 除了功能正确性,集成测试还可以验证系统在集成后的性能是否符合预期。
-
风险管理:
- 通过早期发现集成问题,集成测试有助于降低项目风险和后期修复的成本。
-
自动化:
- 集成测试可以自动化,尤其是在持续集成(CI)流程中,可以自动执行集成测试来确保新代码不会破坏现有的集成。
-
测试用例设计:
- 集成测试用例需要精心设计,以覆盖所有重要的集成场景和边界条件。
-
测试数据:
- 集成测试可能需要特定的测试数据,这些数据能够模拟实际的运行环境和工作负载。
集成测试是确保软件系统各部分协同工作的重要步骤,它有助于在早期发现和解决集成中的问题,提高软件的质量和可靠性。
三、区别
单元测试和集成测试是软件开发过程中两种不同类型的测试,它们在目的、范围和执行方式上有所区别:
-
测试范围:
- 单元测试:关注于单个代码单元(通常是函数或方法)的功能。它测试代码的最基本组成部分,确保每个小部分按预期工作。
- 集成测试:关注于多个代码单元或模块之间的交互。它测试不同部分组合在一起时是否能够协同工作,确保整体功能符合预期。
-
测试环境:
- 单元测试:通常在隔离环境中执行,不依赖于外部系统、数据库或网络资源。它们使用模拟对象(mocks)、桩(stubs)和假对象(fakes)来模拟外部依赖。
- 集成测试:在更接近真实环境的条件下执行,可能需要访问数据库、文件系统或网络服务。它们测试组件在实际环境中的集成情况。
-
测试数据:
- 单元测试:使用人工编写的测试数据,这些数据专为测试特定的代码逻辑而设计。
- 集成测试:可能使用更接近生产环境的数据,包括数据库中的测试数据集。
-
测试复杂性:
- 单元测试:相对简单,因为它们只测试代码的一个部分。
- 集成测试:更复杂,因为它们需要管理多个组件之间的交互和依赖关系。
-
执行速度:
- 单元测试:执行速度快,因为它们不需要设置复杂的环境或等待外部资源的响应。
- 集成测试:执行速度慢,因为它们可能需要等待数据库查询、网络请求等操作。
-
测试依赖性:
- 单元测试:不依赖于其他代码或资源,可以独立执行。
- 集成测试:依赖于其他代码和资源,可能需要按特定顺序执行。
-
测试目的:
- 单元测试:目的是验证代码的逻辑正确性,确保代码单元在各种输入条件下都能正确执行。
- 集成测试:目的是验证不同组件或模块的集成点是否正确,确保它们能够协同工作。
-
测试覆盖率:
- 单元测试:通常具有较高的代码覆盖率,因为它们测试代码的每个分支和路径。
- 集成测试:可能覆盖率较低,因为它们测试的是组件之间的交互,而不是单个代码路径。
-
测试自动化:
- 单元测试:通常是自动化的,可以作为持续集成/持续部署(CI/CD)流程的一部分。
- 集成测试:也可以自动化,但可能需要更多的设置和维护。
-
测试成本:
- 单元测试:编写和维护成本相对较低,因为它们只关注代码的一小部分。
- 集成测试:编写和维护成本较高,因为它们涉及多个组件和环境的配置。
总的来说,单元测试和集成测试是互补的,它们共同构成了软件测试策略的一部分,确保软件的质量和可靠性。
四、Go Web单元测试
在Go Web应用中实现单元测试,你可以使用Go标准库中的testing包,以及一些第三方测试框架如testify和GoConvey。以下是使用这些工具的基本步骤:
使用testing包
-
创建测试文件:
- 测试文件通常以
_test.go结尾,位于与被测试代码相同的包中。 - 例如,如果你有一个
calculator.go文件,你应该创建一个calculator_test.go文件。
- 测试文件通常以
-
编写测试函数:
- 测试函数必须以
Test为前缀,并接受一个*testing.T类型的参数。 - 使用
t.Errorf来记录错误,或者t.Fatalf在测试失败时立即停止测试。
package calculatorimport "testing"func TestAdd(t *testing.T) {result := Add(1, 2)expected := 3if result != expected {t.Errorf("Expected %d, but got %d", expected, result)} } - 测试函数必须以
-
运行测试:
- 在命令行中,使用
go test命令来运行测试。
- 在命令行中,使用
使用testify框架
-
安装
testify:- 使用
go get命令安装testify。
go get github.com/stretchr/testify - 使用
-
编写测试用例:
testify提供了丰富的断言函数,使得测试代码更加简洁。
package calculatorimport ("testing""github.com/stretchr/testify/assert" )func TestAdd(t *testing.T) {result := Add(1, 2)assert.Equal(t, 3, result, "Should be equal") }
使用GoConvey框架
-
安装
GoConvey:- 使用
go get命令安装GoConvey。
go get github.com/smartystreets/goconvey - 使用
-
编写测试用例:
GoConvey提供了一个Web界面,可以实时显示测试结果。
package calculatorimport ("testing". "github.com/smartystreets/goconvey/convey" )func TestAddition(t *testing.T) {Convey("Adding two numbers", t, func() {So(Add(1, 2), ShouldEqual, 3)}) } -
运行
GoConvey:- 在项目目录下运行
goconvey命令,然后在浏览器中访问http://localhost:8080来查看测试结果。
- 在项目目录下运行
以上是Go Web应用中实现单元测试的基本方法。通过这些工具,你可以编写可维护和可读的测试代码,确保你的代码在开发过程中的正确性和稳定性。
五、应用示例
下面是一个简单的Go Web应用单元测试的示例。我们将创建一个简单的HTTP服务器,其中包含一个处理GET请求的路由,然后编写单元测试来验证这个路由的行为。
步骤 1: 创建HTTP服务器
首先,创建一个名为main.go的文件,它将包含我们的HTTP服务器和要测试的路由:
package mainimport ("fmt""net/http"
)// helloHandler 是我们的请求处理函数
func helloHandler(w http.ResponseWriter, r *http.Request) {fmt.Fprintln(w, "Hello, world!")
}func main() {http.HandleFunc("/", helloHandler)http.ListenAndServe(":8080", nil)
}
步骤 2: 创建测试文件
接下来,创建一个名为main_test.go的文件,它将包含对helloHandler函数的单元测试:
package mainimport ("net/http""net/http/httptest""testing"
)// TestHelloHandler 测试 helloHandler 函数
func TestHelloHandler(t *testing.T) {// 创建一个记录器来捕获响应w := httptest.NewRecorder()// 创建一个请求req, err := http.NewRequest("GET", "/", nil)if err != nil {t.Fatal("Error creating request: ", err)}// 调用处理函数helloHandler(w, req)// 检查响应状态码if w.Code != http.StatusOK {t.Errorf("Expected status code %d, got %d", http.StatusOK, w.Code)}// 检查响应体expected := "Hello, world!\n"if w.Body.String() != expected {t.Errorf("Expected response body '%s', got '%s'", expected, w.Body.String())}
}
步骤 3: 运行测试
在命令行中,运行以下命令来执行测试:
go test
这个命令会自动找到所有以_test.go结尾的文件,并执行其中的测试函数。
解释
在main_test.go文件中,我们使用了httptest包来模拟HTTP请求和响应。httptest.NewRecorder创建了一个ResponseRecorder,它是一个可以记录HTTP响应的http.ResponseWriter。我们创建了一个GET请求到根路径/,然后调用我们的helloHandler函数来处理这个请求。之后,我们检查了响应的状态码是否为200(http.StatusOK),以及响应体是否为预期的字符串"Hello, world!"。
这个简单的示例展示了如何在Go中编写单元测试来验证Web服务器的路由处理函数。通过这种方式,你可以确保你的Web应用在开发过程中的每个部分都按预期工作。
相关文章:
青少年编程与数学 02-004 Go语言Web编程 20课题、单元测试
青少年编程与数学 02-004 Go语言Web编程 20课题、单元测试 一、单元测试(Unit Testing)二、集成测试(Integration Testing)三、区别四、Go Web单元测试使用testing包使用testify框架使用GoConvey框架 五、应用示例步骤 1: 创建HTT…...
概率论 期末 笔记
第一章 随机事件及其概率 利用“四大公式”求事件概率 全概率公式与贝叶斯公式 伯努利概型求概率 习题 推导 一维随机变量及其分布 离散型随机变量(R.V)求分布律 利用常见离散型分布求概率 连续型R.V相关计算 利用常见连续型分布的计算 均匀分布 正态…...
Typesense:开源的高速搜索引擎
在当今数据驱动的世界中,高效、快速且智能的搜索能力是任何应用程序和网站成功的关键因素之一。无论是电商平台、内容管理系统还是社交媒体,用户都希望能够迅速找到所需信息。Typesense,作为一款优秀的开源搜索引擎,旨在通过其卓越…...
【vue】圆环呼吸灯闪烁效果(模拟扭蛋机出口处灯光)
效果图先发: 页面部分: <div ref"round" class"round"><div class"light" ref"light"/><div class"box"></div></div>js部分(控制圆环生成); setRound…...
飞牛 fnos 使用docker部署 Watchtower 自动更新 Docker 容器
Watchtower 简介 Watchtower 是一款开源的 Docker 容器管理工具,主要功能为自动更新运行中的 Docker 容器,支持自动拉取镜像并更新容器、配置邮件通知以及定时执行容器更新任务。 用 compose 搭建 Watchtower 的步骤 新建文件夹:在任意位置…...
《信管通低代码信息管理系统开发平台》Linux环境安装说明
1 简介 信管通低代码信息管理系统应用平台提供多环境软件产品开发服务,包括单机、局域网和互联网。我们专注于适用国产硬件和操作系统应用软件开发应用。为事业单位和企业提供行业软件定制开发,满足其独特需求。无论是简单的应用还是复杂的系统ÿ…...
基于物联网的车辆定位和防盗报警系统(论文+源码)
1 系统概述 本文的主要内容是设计一个基于物联网的车辆定位和防盗报警系统,主要是利用STC89C52单片机来作为整体的核心控制元件,主要的核心控制模块主要由GSM通信模块,GPS定位模块,热释电红外检测模块,报警模块以及其他…...
京东零售数据可视化平台产品实践与思考
导读 本次分享题目为京东零售数据可视化平台产品实践与思考。 主要包括以下四个部分: 1. 平台产品能力介绍 2. 业务赋能案例分享 3. 平台建设挑战与展望 作者:梁臣 京东 数据产品架构师 01平台产品能力介绍 1. 产品矩阵 数据可视化产品是一种利用…...
Vue中使用a标签下载静态资源文件(比如excel、pdf等),纯前端操作
第一步,public文件夹下新建static文件夹存放静态资源 我存放了一个 .docx文件,当然,你可以存放pdf/word 等文件都可以。 第二步,模拟a标签下载 //html部分<el-button type"primary" plain click"download&quo…...
ensp 基于EASY IP的公司出口链路配置
Easy IP Easy IP技术是NAPT的一种简化情况。Easy IP无须建立公网IP地址资源池,因为Easy IP只会用到一个公网IP地址,该IP地址就是路由器R连接公网的出口IP地址。Easy IP也会建立并维护一张动态地址及端口映射表,并且Easy IP会将这张表中的公网…...
方正畅享全媒体采编系统reportCenter.do接口SQL注入漏洞复现 [附POC]
文章目录 方正畅享全媒体采编系统reportCenter.do接口SQL注入漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现方正畅享全媒体采编系统reportCenter.do接口SQL注入漏洞复现 [附POC] 0x01 前言 免责声明:请勿利…...
零知识证明:区块链隐私保护的变革力量
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,…...
解决:el-select可输入时失焦会失去输入框中值
1、展示部分 <template><el-select v-model"addForm.companyName" filterable placeholder"请输入/选择公司名称" :loading"loading":filter-method"(value) > dataFilter(value)" change"selectCompany">&…...
ollama-webui - Ollama的ChatGPT 风格的 Web 界面
更多AI开源软件: 发现分享好用的AI工具、AI开源软件、AI模型、AI变现 - :发现分享好用的AI工具、AI开源软件、AI模型。收录了AI搜索引擎,AI绘画工具、AI对话聊天、AI音频工具、AI图片工具、AI视频工具、AI内容检测、AI法律助手、AI高考、AI志…...
「下载」智慧产业园区-数字孪生建设解决方案:重构产业全景图,打造虚实结合的园区数字化底座
数字孪生技术作为一种创新的管理工具,正逐步展现出其在智慧园区建设中的重要意义。以下将从几个方面详细阐述数字孪生在智慧园区建设中的关键作用。 一、提升园区运营管理的智能化水平 数字孪生技术通过构建园区的虚拟镜像,实现了对园区物理世界的全面…...
使用Grafana中按钮插件实现收发HTTP请求
最近项目中需要监控分布式集群的各项指标信息,需要用到PrometheusGrafana的技术栈实现对分布式集群的各个节点状态进行可视化显示,但是要求前端需要提供一个易用的接口让用户可以触发一些操作,例如负载高时进行负载均衡或弹性伸缩。网上找到的…...
【附源码】Electron Windows桌面壁纸开发中的 CommonJS 和 ES Module 引入问题以及 Webpack 如何处理这种兼容
背景 在尝试让 ChatGPT 自动开发一个桌面壁纸更改的功能时,发现引入了一个 wallpaper 库,这个库的入口文件是 index.js,但是 package.json 文件下的 type:"module",这样造成了无论你使用 import from 还是 require&…...
Elasticsearch介绍及安装部署
Elasticsearch介绍 Elasticsearch 是一个分布式搜索引擎,底层基于 Lucene 实现。Elasticsearch 屏蔽了 Lucene 的底层细节,提供了分布式特性,同时对外提供了 Restful API。Elasticsearch 以其易用性迅速赢得了许多用户,被用在网站…...
物理层知识要点
文章目录 物理层接口的四大特性通信基础编码和调制(1)数字数据编码为数字信号(2)模拟数据编码为数字信号(3)常见调制方式(3)信道的极限容量 多路复用技术数据传输方式物理层下的传输…...
SpringBoot 自动装配原理及源码解析
目录 一、引言 二、什么是 Spring Boot 的自动装配 三、自动装配的核心注解解析 3.1 SpringBootApplication 注解 (1)SpringBootConfiguration: (2)EnableAutoConfiguration: (3…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
