公司想定了新的开发规则(为了收归测试人手,减少测试人力的投入,降本增效),推行单元测试(根据不同项目等级,覆盖率到 50-70%)
但是目前我们使用了 go 全局变量的框架,没有使用依赖注入,没有使用接口和抽象,导致非常难写单测
做了一下同事间的调研,大部分同事都不愿意写单测,理由大概是
领导让我看一下这个事情怎么做,我尝试了一下,得出了三种方案。
使用 sqlmock/连接内灰数据库来适配当前框架,可以做到没有外部调用系统的服务 mock 测试,但是遇到要调用外部服务的情况,无法 mock ,只能临时注释掉(因为没有使用依赖注入)。但是连接数据库不能算 mock ,用 sqlmock 要写的测试代码又太多,反对者比较多
改造当前框架,拆分抽象层和实现层,使用依赖注入。这样单测想怎么写就怎么写就好了,但是增加大家平时要写更多代码,也有不少反对者
听从同事建议,反馈领导,不推行单测,自行自测。(全靠自觉性,感觉领导层都不会同意
对此大家有什么比较好的建议吗?
另外最近在学英语,有什么英语读物推荐也可以分享一下(摸鱼/晨间日常)
1
demolock 12 天前 ![]() 第一步当然是把代码喂给 AI ,让 AI 自动吐出每个功能的单元测试代码。
试运行的话先找一个项目组开刀,并把项目时间延长一倍,拿到上级圣旨才好办事。 |
![]() |
2
peteretep 12 天前 ![]() 舍本逐末
写单测的人力成本比养一个测试人员高多了 领导层水平不太行啊,见风就是雨 |
![]() |
3
opengps 12 天前
单元测试本来就是个很大的工作量,需要适配项目选择是否需要自动测试。通常来说一个不停迭代的项目更适合去做单元测试,重点防备改坏了某些地方来自动测试做检查
|
![]() |
4
GallifreyCAR OP @demolock 吐不出的,目前的架子,只有那种完全查库的 service 方法的才可能完全 mock ,写出单元测试。我们公司虽然不大,但是业务也非常繁重的。十几个系统交织在一起互相调用情况非常常见。
|
![]() |
5
op351 12 天前
原来的测试人员是通过什么方法测试的?
|
6
Biggoldfish 12 天前
你们的代码最开始没有 unit test (别说 integration/regression test 了) 是怎么可以合并并上线的?在 PR merge gate 里就应该检测覆盖率
|
7
udisyue 12 天前 ![]() @Biggoldfish 谁要求上线一定要有单测了?传统软件行业我不好说,但互联网企业我敢说,国内有一个算一个,没有这么干的。包括覆盖率。如果你要求有单测和覆盖率,那程序员只能两手一摊,告诉你这功能要加两个礼拜的工期
|
8
wzy44944 12 天前
复杂系统的单测从 0 到 1 ,一般都需要重构下,可以先单模块小范围重构,看看效果,然后再逐步推广
|
![]() |
9
matrix1010 12 天前 ![]() 收归测试人手其实只是借口,推行单元测试的最终目的是干掉开发。AI 代码的质量非常依赖单元测试,如果系统都没办法进行单元测试,那肯定也没法让 AI 同时编写代码和测试,并确保测试通过
|
![]() |
10
ipwx 12 天前
go mock 巨麻烦,不如用测试库单测。每次用不同的 table prefix ,单测完成删除。
|
![]() |
11
follower 12 天前 ![]() |
![]() |
12
15855pm 12 天前
本人测试,干过后端,写过单测,单测只对提测阶段质量有益,最终的产品质量还是需要测试人员来保证的。在降本增效的大背景下,测试人员不足就不要想着在其他地方找补回质量了,成本、效率、质量不可能三角摆在这里。
|
13
jjwjiang 12 天前 ![]() 从技术上说,你们代码本身就没有规范,没有抽象 UT 从何而谈
从流程上说,UT 并不能降低测试成本 显然你的领导两点都没整明白,个人觉得你去掺和就是当背锅侠 |
![]() |
14
matrix1010 12 天前 ![]() 我的建议是强力推行,并且同时开始推行 AI 编写代码(agent 模式,claude code, codex 或者 jules 这些)。同时持续对比有单元测试情况下和没有单元测试情况下 ai 生成代码的质量。最终达成以下目标:op 成为 ai coding 和单元测试专家且工资翻倍,公司开发人员减少 2/3 ,降低公司成本以及减少开发沟通内耗
|
15
Erroad 12 天前
@Biggoldfish #6 一股外企的气息。国内没见过认真搞这些的
|
16
ladypxy 12 天前
用 AI 啊,AI 最擅长的就是写这玩意
|
17
Georgedoe 12 天前 via Android
@Biggoldfish 不同项目等级不同,这么死脑筋的嘛? nasa 的航天软件测试要求更严苛你咋不对标他们
|
20
Lee2019 12 天前
我们都要求好几次了,pipeline 的 gate 我都加过又删掉好几次了
哪次也推不动,实在不行就写假的 ut 呗 |
21
dddd1919 12 天前 ![]() 首先单测的目标是啥?如果就以覆盖度为目标,写的那种方法调用的单测或者丢给 AI 生成的单测代码基本对项目质量起不到什么大作用,要能自顶向下的模拟真实测试覆盖功能测试才真的有意义。
如果要搭建一套完善的测试,起手也相当麻烦,最好前期先把基础工作搞好比如测试框架选型和铺底数据构造以及 mock 工具以及规范单测原则等等等。另外也可以从一些点出发开始写单测,比如后续发现的开发 bug 必须要用单测做回归覆盖 |
![]() |
22
v2hh 12 天前
我之前公司也是,要求单元测试覆盖率 80%,就这一句话就是标准。
|
![]() |
23
qbmiller 12 天前
找个人写白盒测试,不走单元测试呢
|
24
arischow 12 天前
我日常开发的项目最差的测试覆盖都有 70%,还是跑了 15 年的项目
|
![]() |
26
baby0w0 12 天前 ![]() 只有不经常变动的需求才适合写单元测试。
|
![]() |
27
passion336699 12 天前
我们这也搞,每次开周会汇报进度,后端都会说,本周单元测试 0 。。。
|
![]() |
28
zpvip 12 天前 ![]() 想不到 Rails 团队的日常居然在别的团队就是一地鸡毛. Rails 团队的共识是发 Pull Request 一定要带测试, 而且 CRUD 测试也就是 Integration Test 中的 Request spec 根本不用自己写, 也用不 AI, 命令行就自动生成了. 然后再用 AI 补点其它测试, 比如说 Model 中自定义方法的 Unit tests 和 System specs, 重点 Test the behavior, not the implementation.
对, 我就是 V 站 2025 年尬吹 Rails 第一人. |
![]() |
29
GallifreyCAR OP @op351 点点点,手动测试,功能测试
![]() |
![]() |
30
GallifreyCAR OP @Biggoldfish 合并代码,只要代码 review 就行了。如果是大项目,大家一起 review ,小迭代是 leader 审批。
|
32
way2create 12 天前
建议直接把测试全裁了 让开发兼测试 管开发怎么测 降本增效了 这估计是你们领导要的
|
![]() |
33
GallifreyCAR OP @jjwjiang 大佬还是你看得清楚啊。下面一堆说用 AI 的,但是没有抽象,神仙来了都写不了 UT 别说 AI 了。
第二点,其实我感觉就是上面要干掉测试组的一些名头。从今年开始逐步减少测试介入,p0 下项目推行开发自测.... |
34
ccover 12 天前
|
35
zerovoid 12 天前
技术部需要使用“阳奉阴违”之计,所有开发排期都拉长报呗,
领导想降本增效吗,实际结果就是成本反而增加,效率也下降了, 到时领导自然会撤销这个规则。 |
![]() |
36
GallifreyCAR OP @qbmiller #23 现在 p0 项目,测试会介入写测试用例,开发来测试。p0 以下的用例,测试不介入,不给测试用例,开发自测。具体质量,完全看开发自测效果了。
其实以前无论项目大小是测试写测试用例,测试帮忙测试。但是今年开始测试不招人了... |
![]() |
37
wymisgod 12 天前
|
![]() |
38
HelloWorld23333 12 天前
不能增加人员的话,就开掉 1 个测试或者 1 个开发。招一个写 go 的新人(女)专门做白盒测试(写代码测试)。
|
![]() |
39
GallifreyCAR OP @baby0w0 大家反对的点也在这里,特别是使用 sqlmock ,改了数据库方法,还得改测试的 sql 的语言,像我们这种每周不断迭代功能的业务功能上,根本经不起折腾
|
40
udisyue 12 天前
@GallifreyCAR 单元测试只能保证你的代码段没问题,业务流程、需求偏离这些一点都不可能覆盖到。微软没测试,首先你老板要不要看看 windows 现在系统更新是个什么鬼样子,让他搜搜 win10 更新那些鬼故事
|
![]() |
41
darksword21 PRO 首先不论是什么方法这个肯定是需要一定是时间改造项目,领导接受不了那就放弃
测试的话数据库可以不用 mock ,直接跑个测试用的每个 unit test 自己准备表和数据,跑完删表 和外部的调用就没办法了,只能改成依赖注入然后 mock |
42
pvnk1u 12 天前
你觉得在一样的工作时间内,能在保证代码质量和规范的前提下让开发写足够数量和质量的单元测试吗?
|
![]() |
43
Martens 12 天前
go 的话使用 Monkey Patching 很简单做单元测试啊,直接把对应的函数打桩就好了,很久之前一个项目也是用全局变量面向过程一把梭
|
![]() |
44
op351 12 天前
@GallifreyCAR 如果测试并不对代码进行测试,只是进行黑盒测试 我觉得单元测试并不能替代
原因: 1.单元测试只是对代码分支的覆盖性测试,只对最小单元的代码逻辑负责,不对实际功能负责。 2.我以前经历过的项目中,单元测试会被领导层以覆盖率为唯一指标进行追踪,导致开发人员编写大量的测试用例来覆盖所有分支,对正常开发进度严重干扰。 3.单元测试的高覆盖率不等于软件整体功能的高可用性,这也是我之前那个项目中出现的问题,单元测试覆盖率很好看,但是功能测试中仍然出现大量 bug 。 所以单元测试和功能测试不是替代关系,功能测试这种点点点的测试是必须的,要优化也是把功能测试的实际测试部分 RPA (自动)化,减少部分人力投入。 至于测试用例部分,未来可以考虑通过 AI 自动生成,但现阶段我觉得可行性需要再研究。 但测试自动化这块其实应用上已经相对成熟了,可以考虑做导入。 |
45
pandaPapa 12 天前
我刚才工作的时候, 必须要写单元测试. 后来前后端分离 就没人写了
|
![]() |
46
bloomy8 12 天前 ![]() 根本问题是要加排期
|
![]() |
47
irisdev 12 天前
推单测没问题,想用单测完全替代测试有点难吧
|
![]() |
48
dlmy 12 天前
单元测试只有国内互联网公司做的好一点,其他公司很难执行下去。
在互联网公司,项目的特点是时间紧,任务重,项目先上,等后面不忙了,再补单元测试跟文档。 就这样,一直都是紧急需求,已经有好几年的单元测试跟文档没补了。 |
![]() |
49
jimrok 12 天前
你们的什么业务需要单元测试?不是核心业务搞单元测试成本你们盖的住不?就算都是 AI 写代码,后续还要有专人维护单元测试,需求稍微变动一下,单元测试就要重新更新。能支付这种成本的一般都是金融行业或者核心产品,代码修改如果没有单元测试验证,很难直接上生产。因为金融行业一旦出现 bug ,就是金钱的损失,不敢没有单元测试。
|
![]() |
50
queue 12 天前
啥?你们想不增加研发人力或者成本的情况下,想通过单测降低测试成本?
想屁吃呢 |
![]() |
51
winterbells 12 天前
我们的单元测试就是掩耳盗铃,只能说是在提交测试的时候代码能通过,后面就没人跑了
|
![]() |
52
jimrok 12 天前 ![]() @peteretep 也不是这样,一些复杂系统,单元测试比人靠谱多了,例如报税的系统,单元测试测的又快又准,你让一个人测,上百个功能点,不同的场景,让人去做,非常不靠谱。但要达到这样的效果,一个好的架构师是很必要的,首先要能高效的执行单元测试,整个代码的设计就必须满足可测的设计。模块的分离是不是够清晰,外部依赖的设计是不是容易构建,这些都影响单元测试的可实现。
|
53
huaweii 12 天前 via Android
首先搞清楚一件最基本的事情:单测全覆盖全通过,也不代表用户测试能通过
|
54
fredweili 12 天前
领导规定一个测试覆盖率,不愿做的,分不到钱啊,就这么简单
测试和文档 AI 能帮助的太多了,基本就是改改的事 |
![]() |
56
jimrok 12 天前 ![]() 你要实现单元测试,先把系统改造成单元测试友好的系统,一个手电筒的系统,灯泡可以单独测试,控制开关可以单独验证信号输出,电池可以单独测试电量输出的稳定性。但很多系统就是一座屎山,为了测一个功能,至少要拉起七八个模块,还不知道怎么能让每个模块正确初始化,每个场景都很难模拟,写单元测试的人就会直接崩溃掉。
|
![]() |
57
gefranks 12 天前
前几年吃到 COVID-19 红利的公司, 2020 年中的时候开始运动式的搞单元测试轰轰烈烈的, 也是上面那个要求.
几年后我因为某件事情问一个开发经理, 你们的单元测试呢, 不是有单元测试么? 那位直接说, 那是假的, 不作数的. 不要只看一开始创建 UT 的成本投入, 后期维护的成本可大着呢。 |
![]() |
58
ipwx 12 天前
@snowlyg http 相对容易,gorm 单测才是巨坑。我用 gorm + postgresql ,能改 table_prefix ,不能改 index 的(因为写在注解里面)。毕竟众所周之,pg 的 index 名称是库级别唯一,而不是 table 级别唯一,就很搞。
|
![]() |
59
XueXianqi 12 天前
|
![]() |
60
wccc 12 天前
go 写单元测试真的太难了.. 这一点真的不如 java
|
61
ellipsis 12 天前
我组内单测覆盖率 90%上下,抱怨单测写不了的都是战五渣程序员和自己写的屎山代码。
|
![]() |
62
wxw752 12 天前
我看你们第二种方案,怎么感觉要把 go 改成 spring 的形状了😂
|
![]() |
63
Tuee 12 天前
裁测试,下一步就是裁开发,业务收缩,公司倒闭。。。
|
![]() |
64
Vegetable 12 天前
一个项目一开始没有考虑写测试,后边再硬写就会这样的。
建议写集成测试,这样会容易一点。单测也确实是一种陷阱,单元测试在业务为主的开发里边作用没那么大,集成测试能覆盖很大一部分。 |
![]() |
65
carpeDiemJll 12 天前
不增加人力的前提下,让写用例,都是耍流氓; 写用例的时间要远远大于开发时间
|
![]() |
66
snowlyg 12 天前
@ipwx 是的,我把 gorm 相关测试的功能集成到 httptest 了,每个测试都用 uuid 开一个新库,测试结束销毁。还要走 迁移和 seed 。 就是公司电脑性能太垃圾了,每次测试都要跑半天,开发的时间都在等测试。
|
![]() |
69
COW 12 天前
早点准备跑路吧
|
![]() |
70
NX2023 12 天前
全局变量也是可以的,虽然麻烦些
先说关于依赖的处理,如果数据库是 MySQL 的话比较方便,可以使用 github.com/dolthub/go-mysql-server 在本地内存起一个,然后改配置文件,连接这个内存实例,这个库可以当做是 Go 实现的 MySQL 可以配套运行一些脚本建表与造一些数据,这样测起来方便 但是这个库运行某些 SQL 会有问题(绝大部分时候正常),这时候就上 https://github.com/testcontainers/testcontainers-go 用容器起数据库,包括 PostgreSQL 也只能这样 Redis 可以用 https://github.com/alicebob/miniredis 其他依赖直接 gomonkey 打桩 具体来说,可以先实现一个通用的造环境函数准备好数据库之类,每个测试开始调用一下(或者 test Main ,这个方法很多) 之后造 HTTP 请求调 handler ,之后用 testify 检查返回与数据库更改是否符合要求(比方说更新后再查一下是否已更新) |
![]() |
71
baby0w0 12 天前
@GallifreyCAR 业务功能写单元测试没什么大的用处,我一直觉得除非你研发的是底层框架类库才有必要写单元测试
|
72
momo2789 12 天前
加钱+不写绩效不及格 or 延长一倍开发时间+不写绩效不及格
|
![]() |
73
erenming 12 天前
一般就核心模块要求单测覆盖率呗,整个项目单测成本太高了
|
74
momo2789 12 天前
另外不写测试或者 Statements 测试没有 95%的,在我这里只值 8000RMB/月
|
76
layxy 12 天前
之前我们也推单元测试代码覆盖率,然后一个功能 3 天,写单元测试再要 3 天工时,后面就基本不咋让写单元测试了,尤其是有很多 rpc 调用场景,需要 mock 一堆服务,然后改了一点业务代码,可能需要几十倍的工作量改测试代码
|
![]() |
78
GallifreyCAR OP @NX2023 数据库我是用这个库实现的 github.com/DATA-DOG/go-sqlmock ,外部调用服务的情况,我目前还没想到同步好的方式,但是 gomonkey 是个很好思考方向。
|
![]() |
79
everhythm 12 天前
@GallifreyCAR #4 业务交叉情况,得让测试先准备完备的测试数据,才能自动/手动跑覆盖,达到测试目的。按方案 1 改改,外部服务数据都是可以 mock 的呀。
然后单测和方案 1 的全流程测试是两回事,单测也考虑依赖完备的测试数据,不然光写“单测”意义不大。 举个例子,假设原有项目是商城上下架商品,现在增加 1 个商品优惠券功能。那测试得先准备 1 个商品测试数据,再基于此做优惠券测试。 |
![]() |
80
yibin001 12 天前
|
![]() |
81
NX2023 12 天前
@GallifreyCAR #78 个人感觉 go-sqlmock 这种写法不太能接受,所以我没按照这种方式(
|
![]() |
84
NX2023 12 天前
@GallifreyCAR #78 关键是直接起一个实例来读写很方便,用 go-sqlmock 的 ExpectExec 不如执行完 SELECT 一下看是否符合修改后的预期
|
![]() |
85
morty0 12 天前
单元测试做单独的排期, 覆盖率列入绩效考核, 而不是说开发周期加上单元测试
|
![]() |
87
qiyuey 12 天前
你们老板这是花了一碗粉的钱,想吃两碗粉
|
89
kzfile 12 天前
单元测试工作量确实很大,但能直接关联代码覆盖率。
如果一段代码不方便做单元测试,大概率不是好代码,以应付单元测试和覆盖测试的心态写代码,能迫使开发人员写出方便复用的代码段 |
![]() |
94
maichael 12 天前
站在你的角度上的建议:
1. 通过增加单元测试覆盖率要求来减少测试人手这一大目标注定会失败。 2. 既然注定失败,那么你可执行的方案有两种: 2.1. 想通过写单元测试来提高代码质量,完全遵循 TDD (可选),并且编写有逻辑,有思考的“白盒测试” 2.2. 放弃通过写单元测试提高代码质量的想法,面向测试覆盖率编程,编写一大堆毫无逻辑,不用思考,全面覆盖的测试。 3. 可以通过 AI 去先提高代码的可测性/找到一种绕过当前测试困难的方法 4. 先有一个测试案例,然后告诉 AI 参考该案例来编写测试就行 |
95
jasondennis12139 12 天前
wiremock 不是可以 mock 接口吗,调用外部服务的话。
|
![]() |
97
dajj 12 天前
不如让测试 + ai 学做 api 测试
|