
单元测试是指对软件的单个单元或组件进行测试,目的是验证每个代码单元是否按预期执行。
比如一个函数、一个方法或一个接口等。

经常写 bug 的同学都知道,发现 bug 容易,解决 bug 难。
因为解决一个 bug 时,可能会同时引入其他 bug,导致局面失控。
单元测试不仅能保证当前代码的正确性,还能确保不会影响已有的代码。
我们为什么总是在不断写 if else?
其实是因为害怕。
我们到底在害怕什么?
我们害怕一动代码,整个“屎山”就崩了。
如果有足够覆盖率的单元测试,就可以放心重构,不用担心系统崩塌,重构时也没有心理负担。
有人觉得单元测试不好写,改动频繁,没什么用。
其实多数情况下,是因为代码设计不够好。
有时候操作很猛,但一看圈复杂度高达 25,函数设计不合理,只关注功能实现而忽略了可测试性,这样就很难编写单元测试。
在编写单元测试时,我们会跳出当前功能函数,从输入和输出的角度思考:这个函数是否实现了高内聚低耦合?它依赖的其他函数是否合理?功能是否足够单一?仅通过输出能否判断函数是否正常工作?
这种方式会促使我们反思代码设计,同时加深对整个系统的理解。
有人说不需要写注释,因为某位大师说过“代码本身就是注释”。
但现实是,一个函数几百行却没有任何注释,即使大师来了也看不懂。
其实,比没有注释更糟糕的是过时的注释。
如果一个单元职责足够单一、可测试性好,那么它的测试用例就是最好的说明书,而且不会过时。因为一旦过时,测试用例就无法通过,系统会强制你更新它。
把需求转化为测试用例,什么样的需求或功能就对应什么样的测试用例。
比如:计算房间的推荐分数并进行排序。
输入:房间分数涉及的各项指标。
输出:按指定顺序排列的房间列表。
很多时候,bug都是由边界值引起的。
比如边界条件、并发等问题。
设计测试用例时,要把边界条件也考虑进去,验证输出是否符合预期。
程序由数据和控制流程组成。
测试时尽量覆盖每一个逻辑分支,避免遗漏。
patchConf := gomonkey.ApplyFunc(config.GetBusinessConfig, func() *config.BusinessConfig {
return &config.BusinessConfig{
GameNotifyConf: config.GameNotifyConfig{
DayLimit: 20,
},
}
})
defer patchConf.Reset()func TestApplyMethodFunc(t *testing.T) {
slice := fake.NewSlice()
var s *fake.Slice
Convey("TestApplyMethodFunc", t, func() {
Convey("for succ", func() {
err := slice.Add(1)
So(err, ShouldEqual, nil)
patches := ApplyMethodFunc(s, "Add", func(_ int) error {
return nil
})
defer patches.Reset()
err = slice.Add(1)
So(err, ShouldEqual, nil)
err = slice.
Remove(1)
So(err, ShouldEqual, nil)
So(len(slice), ShouldEqual, 0)
})
})
}func TestApplyPrivateMethod(t *testing.T) {
Convey("TestApplyPrivateMethod", t, func() {
Convey("可以给不同包里的私有值方法打桩", func() {
s := fake.PrivateMethodStruct{}
patches := ApplyPrivateMethod(s, "haveEaten", func(_ fake.PrivateMethodStruct) bool {
return false
})
defer patches.Reset()
result := s.
AreYouHungry()
So(result, ShouldEqual, "I am hungry")
})
})
}单元测试像一面镜子倒逼代码设计走向简洁——毕竟难测试的逻辑,往往藏着耦合的“暗礁”。
当单元测试的“地基”扎实了,高覆盖率、CI持续绿码会成为常态,系统稳定性与用户满意度也会沿着测试链路自然生长。与其在“屎山”里焦虑“不敢动”,不如现在就为代码穿上“测试铠甲”——毕竟,写测试的1小时,远胜过线上debug的3个通宵(真的)
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。