Go -- 测试 and 项目实战
没有后端基础,学起来真是费劲,所以打算速刷一下,代码跟着敲一遍,有个印象,大项目肯定也做不了了,先把该学的学了,有空就跟点单体项目,还有该看的书....
目录
🍌单元测试
🌼assert
🌼覆盖率
🦊tips
🦊依赖
🦊文件处理
🍌Mock测试
🍌基准测试
🍉项目实战
🦂ER图
🦂分层结构
🦂组件工具
💪Repository
💪Service
💪Controller
💪Router
💤运行
🍌单元测试
规则
(1)测试文件以 _test.go 结尾
源代码与测试代码👇
(2)测试函数命名规范:func TestXxx(*testing.T) Test紧挨着第一个字母大写👇
(3)初始化逻辑放到TestMain()里
🌼assert
导入开源网站的assert包,来进行判等,不等等测试操作👇
单元测试的样例👇
judge.go
package judgefunc JudgePassLine(score int16) bool {if score >= 60 {return true}return false
}
judge_test.go
package judgeimport ("github.com/stretchr/testify/assert""testing"
)func TestJudgePassLineTrue(t *testing.T) {isPass := JudgePassLine(70)assert.Equal(t, true, isPass)
}
Run一下👇
👇

👆解释
testing.T是 Go 语言测试框架中的一个结构体类型,它提供了一组方法和属性用于管理和报告测试的结果。当你编写和运行测试函数时,测试框架会自动创建一个testing.T类型的实例,并将其传递给测试函数
🌼覆盖率
当我们写了单元测试后👇
覆盖率越高,代码的质量越有保证,那如何查看覆盖率呢👇
PS:发现个Goland小技巧,ctrl + z可以返回上一步代码,误删了也不要紧
要查看覆盖率,首先要切到对应目录下,视频中是👇

但我只会先cd到对应目录,结果一样👇

覆盖率意味着👇

judge.go,函数中一共3行有效代码,但是judge_test.go传入的70,只会运行前2行,所以覆盖率是 2 / 3
当我们需要100%覆盖率,只需要增加一个测试分支👇
func TestJudgePassLineFail(t *testing.T) {isPass := JudgePassLine(50)assert.Equal(t, true, isPass)
}

👆通过不断地,对各个分支的测试,保证了测试的完备性, 减少了BUG的产生
🦊tips
🦊依赖
DB:数据库database
Cache:Redis类似的组件
File:本地文件
👆三项属于项目中的强依赖
在单元测试中,一般有2个目标:(1)幂等 (2)稳定
(1)幂等:多次重复一个case的测试,结果一样
(2)稳定:单元测试之间是相互隔离的,即任何时间 / 函数下,都能够运行
而需要保证幂等 / 稳定,需要Mock机制,下面先讲文件处理
🦊文件处理
log
line11
line22
line33
line44
line55
ProcessFirstLine.go
package firstLineimport ("bufio""os""strings"
)// ReadFirstLine 从文件中读取第一行内容
func ReadFirstLine() string {open, err := os.Open("log") // 打开名为 "log" 的文件defer open.Close() // 延迟关闭文件, 避免资源泄露if err != nil {return "" // 发生错误时返回空字符串}scanner := bufio.NewScanner(open) // 创建一个扫描器for scanner.Scan() { // 循环遍历文件的每一行return scanner.Text() // 返回第一行内容}return "" // 文件为空时返回空字符串
}// ProcessFirstLine 处理第一行内容,将 "11" 替换为 "00"
func ProcessFirstLine() string {line := ReadFirstLine() // 调用 ReadFirstLine 函数获取第一行内容destLine := strings.ReplaceAll(line, "11", "00") // 将 "11" 替换为 "00"return destLine // 返回替换后的结果
}
ProcessFirstLine_test.go
package firstLineimport ("github.com/stretchr/testify/assert""testing"
)// TestProcessFirstLine 是对 ProcessFirstLine 函数的单元测试
func TestProcessFirstLine(t *testing.T) {firstLine := ProcessFirstLine() // 调用 ProcessFirstLine 函数assert.Equal(t, "line00", firstLine) // 使用断言验证结果是否符合预期
}
equal还是报错,但是点击这里还是可以PASS👇

解释
(1)
bufio:高效读取数据的包
bufio.NewReader():创建一个新的Reader对象,用于读取数据。它接收一个io.Reader类型的参数,并使用默认大小的缓冲区bufio.NewScanner():创建一个新的Scanner对象,用于对输入流进行扫描。Scanner可用于逐行读取文本等Reader类型:它提供了各种方法来从输入流中读取数据,如ReadString()用于读取字符串,ReadBytes()用于读取字节切片等Scanner类型:它提供了各种方法来解析输入流中的数据,如Scan()用于逐行读取文本,ScanBytes()用于逐个字节读取等Scanner.Text():返回当前扫描的文本内容Scanner.Scan():将扫描器移动到下一行,并返回是否还有更多行可供扫描(2)
os是一个提供与操作系统相关功能的包
os.Args:一个字符串切片,包含命令行参数os.Exit(code int):终止当前程序的执行,并返回给定的错误码os.Getwd():返回当前的工作目录的路径名os.Chdir(dir string):将当前的工作目录更改为指定的目录os.Mkdir(name string, perm FileMode) error:创建一个新目录os.Open(name string) (*File, error):打开一个文件用于读取os.Create(name string) (*File, error):创建一个文件用于写入os.Remove(name string) error:删除指定的文件或目录os.Rename(oldname, newname string) error:重命名(移动)文件或目录os.Stdout、os.Stdin、os.Stderr:标准输出、标准输入和标准错误输出的文件对象
但是,如果源文件被人篡改,那么测试文件,在特定场景下,也就无法运行,那如何Mock呢?👇
🍌Mock测试
开源Mock测试包 -- bouk/monkey: Monkey patching in Go (github.com)
打桩,即用函数A替换函数B👇
不得不吐槽一下,内部课贴的代码只贴部分,默认剩下部分你都会了,没学过也不能无中生有吧...真的觉得,每一点代码都力求自己得到对应输出,有点浪费时间了,先速通吧...
🍌基准测试
看了一遍...
🍉项目实战
描述
用例
👆用户浏览页面,主要展示2方面内容,一是Topic话题,一是PostList回帖的列表
🦂ER图
Entity Relationship Diagram
ER图由以下三个主要组成部分构成:实体,属性,关系。
🦂分层结构
数据层:数据Model,外部数据的增删改查
逻辑层:业务Entity
视图层:视图view,处理和外部的交互逻辑
🦂组件工具
(1)Gin高性能 go web 框架
gin-gonic/gin: Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin. (github.com)
(2)Go mod
go mod init
go get gopkg.in/gin-gonic/gin.v1@v1.3.0 --> 执行后,go.mod就有gin的依赖了
💪Repository
index
两个索引👇
初始化话题数据索引👇
package main //入口import ("bufio" //缓冲读取"encoding/json" //处理JSON数据"os" //操作系统交互
)// 初始化主题索引映射
func initTopicIndexMap(filePath string) error {open, err := os.Open(filePath + "topic") //打开文件filePathif err != nil { //打开错误return err}scanner := bufio.NewScanner(open) //逐行扫描的工具topicTmpMap := make(map[int64]*Topic) //值是指向Topic结构体的指针for scanner.Scan() {text := scanner.Text() //保存每行内容var topic Topicif err := json.Unmarshal([]byte(text), &topic); err != nil {return err //json.Unmarshal将text解析为Topic结构体}topicTmpMap[topic.Id] = &topic //保存解析的结构体保}topicIndexMap = topicTmpMap //映射赋值给全局变量return nil
}
查询
👇
package mainimport ("bufio" //缓冲读取"encoding/json" //处理JSON数据"os" //操作系统交互"sync"
)// 声明一个全局变量 topicIndexMap,用于存储主题索引映射
var topicIndexMap map[int64]*Topic// Topic 定义 Topic 结构体,包含了主题的属性
type Topic struct {Id int64 `json:"id"`Title string `json:"title"`Content string `json:"content"`CreateTime int64 `json:"create_time"`
}// TopicDao 定义 TopicDao 结构体
type TopicDao struct {
}var (topicDao *TopicDaotopicOnce sync.Once
)// NewTopicDaoInstance 函数返回一个 TopicDao 实例
func NewTopicDaoInstance() *TopicDao {topicOnce.Do(func() {topicDao = &TopicDao{}})return topicDao
}// QueryTopicById 方法根据 id 查询并返回对应的 Topic 实例
func (*TopicDao) QueryTopicById(id int64) *Topic {return topicIndexMap[id]
}// 初始化主题索引映射
func initTopicIndexMap(filePath string) error {open, err := os.Open(filePath + "topic") //打开文件filePathif err != nil { //打开错误return err}scanner := bufio.NewScanner(open) //逐行扫描的工具topicTmpMap := make(map[int64]*Topic) //值是指向Topic结构体的指针for scanner.Scan() {text := scanner.Text() //保存每行内容var topic Topicif err := json.Unmarshal([]byte(text), &topic); err != nil {return err //json.Unmarshal将text解析为Topic结构体}topicTmpMap[topic.Id] = &topic //保存解析的结构体保}topicIndexMap = topicTmpMap //映射赋值给全局变量return nil
}
💪Service
定义两个实体👇
流程👇
流程代码👇
//Do 方法执行查询页面信息的流程,返回 PageInfo 实例和错误信息
func (f *QueryPageInfoFlow) Do() (*PageInfo, error) {if err := f.checkParam(); err != nil { //参数校验return nil, err //校验失败}if err := f.prepareInfo(); err != nil { //准备数据return nil, err}if err := f.packPageInfo(); err != nil { //组装实体return nil, err}return f.pageInfo, nil //返回 PageInfo 实例和 nil,操作成功
}
💪Controller
....看了一遍....
💪Router
💤运行
end....
相关文章:
Go -- 测试 and 项目实战
没有后端基础,学起来真是费劲,所以打算速刷一下,代码跟着敲一遍,有个印象,大项目肯定也做不了了,先把该学的学了,有空就跟点单体项目,还有该看的书.... 目录 🍌单元测试…...
GitHub基本使用
GitHub搜索 直接搜索 直接搜索关键字 明确搜索仓库标题 语法:in:name [关键词]展示:比如我们想在GitHub仓库中标题中搜索带有SpringBoot关键词的,我们可以样搜: in:name SpringBoot 明确搜索描述 语法:in:description [关键词]展…...
微信小程序生成带参数的二维码base64转png显示
getQRCode() {var that this;wx.request({url: http://localhost:8080/getQRCode?ID 13,header: {content-type: application/json},method: POST,responseType: arraybuffer,//将原本按文本解析修改为arraybuffersuccess(res) {that.setData({getQRCode: wx.arrayBufferToB…...
量子计算机:下一代计算技术的奇点
介绍 量子计算机是一种基于量子力学原理的全新计算技术,它利用量子比特的特性进行计算,具有破解当前经典计算机难以解决问题的潜力。在过去几十年里,量子计算机一直是计算机科学领域的一个热门话题。本篇博客将深入探讨量子计算机的基本原理…...
【ChatGPT】ChatGPT是如何训练得到的?
前言 ChatGPT是一种基于语言模型的聊天机器人,它使用了GPT(Generative Pre-trained Transformer)的深度学习架构来生成与用户的对话。GPT是一种使用Transformer编码器和解码器的预训练模型,它已被广泛用于生成自然语言文本的各种…...
Docker设置代理、Linux系统设置代理
使用方式 新建或修改~/.docker/config.json文件,设置可用的代理地址。 {"proxies": {"default": {"httpProxy": "http://192.168.0.32:1080","httpsProxy": "http://192.168.0.32:1080","noPro…...
C# 进程
C# 进程 进程的命名空间是: using System.Diagnostics;1.获取当前计算机正在运行所有的进程 Process[] processes Process.GetProcesses(); for (int i 0; i < processes.Length; i) {Console.WriteLine(processes[i]); } Console.ReadKey();2.通过进程打开…...
SQL注入之sqlmap
SQL注入之sqlmap 6.1 SQL注入之sqlmap安装 sqlmap简介: sqlmap是一个自动化的SQL注入工具,其主要功能是扫描,发现并利用给定的URL的SQL注入漏洞,目前支持的数据库是MS-SQL,MYSQL,ORACLE和POSTGRESQL。SQLMAP采用四种独特的SQL注…...
Flutter 命名路由
我们可以通过创建一个新的Route,使用Navigator来导航到一个新的页面,但是如果在应用中很多地方都需要导航到同一个页面(比如在开发中,首页、推荐、分类页都可能会跳到详情页),那么就会存在很多重复的代码。…...
Stephen Wolfram:神经网络
Neural Nets 神经网络 OK, so how do our typical models for tasks like image recognition actually work? The most popular—and successful—current approach uses neural nets. Invented—in a form remarkably close to their use today—in the 1940s, neural nets …...
RBF神经网络原理和matlab实现
1.案例背景 1.1 RBF神经网络概述 径向基函数(Radical Basis Function,RBF)是多维空间插值的传统技术,由Powell于1985年提出。1988年, Broomhead和 Lowe根据生物神经元具有局部响应这一特点,将 RBF引入神经网络设计中,产生了RBF神经网络。1989 年,Jackson论证了…...
Nacos 抽取公共配置
文章目录 创建一个公共配置文件其他配置文件引用springboot配置文件 创建一个公共配置文件 其他配置文件引用 ${变量} springboot配置文件 spring:cloud:nacos:discovery:server-addr: current.ip:8848namespace: word_register_proconfig:server-addr: current.ip:8848auto-r…...
Promise、Async/Await 详解
一、什么是Promise Promise是抽象异步处理对象以及对其进行各种操作的组件。Promise本身是同步的立即执行函数解决异步回调的问题, 当调用 resolve 或 reject 回调函数进行处理的时候, 是异步操作, 会先执行.then/catch等,当主栈完成后&#…...
PoseiSwap:基于 Nautilus Chain ,构建全新价值体系
在 DeFi Summer 后,以太坊自身的弊端不断凸显,而以 Layer2 的方式为其扩容成为了行业很长一段时间的叙事方向之一。虽然以太坊已经顺利的从 PoW 的 1.0 迈向了 PoS 的 2.0 时代,但以太坊创始人 Vitalik Buterin 表示, Layer2 未来…...
uC-OS2 V2.93 STM32L476 移植:串口打印篇
前言 前几篇已经 通过 STM32CubeMX 搭建了 NUCLEO-L476RG 的 STM32L476RG 的 裸机工程,下载了 uC-OS2 V2.93 的源码,并把 uC-OS2 的源文件加入 Keil MDK5 工程,通过适配 Systick 系统定时器与 PendSV 实现任务调度,初步让 uC-OS2 …...
代码随想录算法训练营第四十六天| 139.单词拆分 背包问题总结
代码随想录算法训练营第四十六天| 139.单词拆分 背包问题总结 一、力扣139.单词拆分 题目链接: 思路:确定dp数组,dp[i]为true表示从0到i切分的字串都在字典中出现过。 确定递推公式,dp[i] 为true要求 s[j, i] 在字典中出现&…...
【机器学习】西瓜书习题3.3Python编程实现对数几率回归
参考代码 结合自己的理解,添加注释。 代码 导入相关的库 import numpy as np import pandas as pd import matplotlib from matplotlib import pyplot as plt from sklearn import linear_model导入数据,进行数据处理和特征工程 # 1.数据处理&#x…...
Blazor前后端框架Known-V1.2.9
V1.2.9 Known是基于C#和Blazor开发的前后端分离快速开发框架,开箱即用,跨平台,一处代码,多处运行。 Gitee: https://gitee.com/known/KnownGithub:https://github.com/known/Known 概述 基于C#和Blazor…...
【3D捏脸功能实现】
文章目录 一、技术方案介绍二、技术核心三、底层技术实现选型进行模型建模编写逻辑代码 四、功能落地五、总结 一、技术方案介绍 3D捏脸功能是一种利用3D技术实现用户自定义头像的功能。通常实现这种功能需要以下技术: 3D建模技术。通过3D建模技术可以创建一个可以…...
Kafka的零拷贝
传统的IO模型 如果要把磁盘中的某个文件发送到远程服务器需要经历以下几个步骤 (1) 从磁盘中读取文件的内容,然后拷贝到内核缓冲区 (2) CPU把内核缓冲区的数据赋值到用户空间的缓冲区 (3) 在用户程序中调用write方法,把用户缓冲区的数据拷贝到内核下面…...
react为啥不像vue3一样做diff优化(双端diff和最长递增子序列)
React 不是不能做 LIS / 双端 Diff, 而是 React 的架构目标 不追求 DOM 最优,追求调度最优 所以它故意不做 Vue 那套极致 Diff 优化。 一、先给结论(面试直接说) React 不做极致 Diff 优化,是因为它的架构方向是&…...
智慧农业 水稻害虫检测数据集 基于深度学习结合 深度学习模型(YOLOv11) 和 图形用户界面(GUI) 两部分来实现。 PyQt5
智慧化农业-水稻害虫目标检测数据集,3156张,yolo和voc两种标注方式 10类,标注数量: Asiatic Rice Borer: 亚洲稻螟 (716) Brown Plant Hopper: 褐飞虱 (577) Paddy Stem Maggot: 稻茎虫 (104) Rice Gall Midge: 稻瘿蚊 (223) Rice…...
如何在树莓派上用TinyProxy搭建轻量级HTTP代理(附性能优化技巧)
树莓派上部署TinyProxy的工程实践与深度调优指南 当你在咖啡厅用树莓派搭建的微型服务器调试物联网设备时,突然发现所有外网请求都需要经过代理——这就是TinyProxy在嵌入式场景下的典型应用。不同于x86服务器的部署,在ARM架构的树莓派上运行代理服务需要…...
如何用代码思维提升90%图表效率?揭秘Mermaid的可视化革命
如何用代码思维提升90%图表效率?揭秘Mermaid的可视化革命 【免费下载链接】mermaid-live-editor Edit, preview and share mermaid charts/diagrams. New implementation of the live editor. 项目地址: https://gitcode.com/GitHub_Trending/me/mermaid-live-edi…...
实战应用:基于快马开发企业内软件合规性与安全拦截演示工具
今天想和大家分享一个在企业IT支持场景中非常实用的工具开发经验——基于InsCode(快马)平台开发的软件合规性检查演示工具。这个工具特别适合用来做内部培训或用户教育,帮助大家理解系统弹出的"智能应用控制已阻止可能不安全的应用"这类安全警告背后的逻辑…...
推荐8款提升论文效率的AI工具(含爱毕业aibiye)和简易使用教程
在学术研究领域,AI技术的应用显著提升了论文写作的效率与质量。以下推荐8款功能强大的智能工具,涵盖文献解析、内容生成、文本优化等关键环节,助力研究者高效完成从资料收集到论文润色的全流程工作。这些创新解决方案能够有效简化研究过程&am…...
3分钟找回丢失文件!FSearch让Linux搜索体验飞起来
3分钟找回丢失文件!FSearch让Linux搜索体验飞起来 【免费下载链接】fsearch A fast file search utility for Unix-like systems based on GTK3 项目地址: https://gitcode.com/gh_mirrors/fs/fsearch 你是否曾在Linux系统中花费数分钟甚至数小时寻找一个文件…...
Pixel Aurora Engine效果展示:像素极光系统生成的赛博忍者角色系列
Pixel Aurora Engine效果展示:像素极光系统生成的赛博忍者角色系列 1. 像素极光引擎简介 Pixel Aurora(像素极光)是一款基于AI扩散模型的高端绘图工作站,采用独特的复古像素游戏风格界面设计。这款工具将现代AI技术与经典8-bit美…...
Qwen3-14B应用案例:智能客服与内容生成,企业落地实操
Qwen3-14B应用案例:智能客服与内容生成,企业落地实操 1. 为什么选择Qwen3-14B作为企业AI解决方案 在当今企业数字化转型浪潮中,AI技术正从实验室走向实际业务场景。Qwen3-14B作为140亿参数的大型语言模型,在能力与资源消耗之间取…...
PP-DocLayoutV3参数详解:text/title/table/figure等11类版面区域置信度解析
PP-DocLayoutV3参数详解:text/title/table/figure等11类版面区域置信度解析 1. 引言:为什么版面分析需要“置信度”? 想象一下,你拿到一份扫描的合同,想用OCR(文字识别)把它变成可编辑的电子版…...














👇


