程序员的测试课
郑晔
开源项目 Moco 作者
18911 人已学习
新⼈⾸单¥59
登录后,你可以任选2讲全文学习
课程目录
已完结/共 23 讲
加餐 (1讲)
结束语 (1讲)
程序员的测试课
15
15
1.0x
00:00/00:00
登录|注册

06 | 测试不好做,为什么会和设计有关系?

你好,我是郑晔!
在前面几讲里,我们讲了测试的一些基础,要有测试思维、要学会使用自动化测试框架、要按照好测试的样子去写测试……但是,懂了这些就能把测试写好吗?
答案显然是否定的。因为这些东西很多人都知道,但真正到了实际的项目中面对自己的代码,还是不会写测试。主要的问题就是不好测,这也是测试劝退了很多程序员的一个重要原因。
不好测实际上是一个结果。那造成这个结果的原因是什么呢?答案就是我们今天要讨论的话题:软件设计。

可测试性

为什么说不好测是由于软件设计不好造成的呢?其实,更准确的说法是绝大多数人写软件就没怎么考虑过设计。
软件设计是什么?软件设计就是在构建模型和规范。
然而,大多数人写软件的关注点是实现。我们学习写程序的过程,一定是从实现一个功能开始的。这一点在最开始是没有问题的,因为需求的复杂度不高。不过需求一旦累积到一定规模,复杂度就会开始大幅度升高,不懂软件设计的人就开始陷入泥潭。
即便一个人认识到软件设计的重要性,学习了软件设计,但在做设计的时候还是常常会对可测试性考虑不足。可测试性是一个软件 / 模块对测试的支持程度,也就是当我执行了一个动作之后,我得花多大力气知道我做得到底对不对。
我们所说的代码不好测,其实就是可测试性不好。当我们添加了一个新功能时,如果必须把整个系统启动起来,然后给系统发消息,再到数据库里写 SQL 把查数据去做对比,这是非常麻烦的一件事。为了一个简单的功能兜这么大一圈,这无论如何都是可测试性很糟糕的表现。然而,这却是很多团队测试的真实状况。因为系统每个模块的可测试性不好,所以,最终只能把整个系统都集成起来进行系统测试。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

软件测试的困难与设计息息相关。大多数程序员在编写软件时往往忽视软件设计,导致代码难以测试。可测试性是软件对测试的支持程度,而不好测的代码往往意味着设计不佳。编写可测试的代码需要遵循软件设计原则,如SOLID原则,使代码符合单一职责原则、依赖倒置原则等,从而实现可组合的代码。避免使用static方法、全局状态和Singleton模式也是编写可测试代码的关键。此外,面对第三方代码集成时,隔离第三方代码和业务代码是关键,以确保第三方代码不成为测试的障碍。因此,软件测试的困难与设计息息相关,编写可测试的代码需要遵循软件设计原则,并且在集成第三方代码时需要进行有效的隔离。 在实际工作中,除了要编写业务代码,还会遇到第三方集成的情况。对于调用程序库的情况,可以定义接口,然后给出调用第三方程序库的实现,以此实现代码隔离。如果代码由框架调用,回调代码只做薄薄的一层,负责从框架代码转发到业务代码。提升软件的可测试性,关键是改善软件的设计,编写可测试的代码。编写可测试的代码是影响一个系统好不好测的重要因素,可测试性好的软件,各个模块都可以独立测试,而可测试性不好的软件,只能做整体的测试,其复杂度和过程中花费的时间都是不可同日而语的。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《程序员的测试课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(18)

  • 最新
  • 精选
  • byemoto
    对于不是以面向对象范式为核心的编程语言 (比如go), 需要做出一些针对性的调整吗? 在go语言中写出function主导的过程式代码还是比较普遍的.

    作者回复: 单元测试的粒度一般都是一个函数。对于像 C 语言这种,要像做一个好的设计,需要付出一些更多的努力。 但如果你把 Go 归入到结构化编程,多半是低估了 Go 语言本身的能力,它只是表现面向对象的方式不同于常规的面向对象语言而已。

    2021-08-18
    4
  • sylan215
    软件设计本身就是一个很重要的事情,但是大家都知道重要,落实的时候并不完全都按照设计原则来进行实现,加上所有项目都在赶工期,大家就真的完全关注实现了,先提测再说,成了首要目的。 这次通过老师说的可测试性要求,让软件设计的重要性再次提升,其实软件设计做好了,不仅仅有利于可测试,开发之间的 CR 也会进行的更顺畅(目前很多开发同学不愿意看别人代码,也和设计风格千变万化有关,喔,对了,其实大部分都没有设计)。 目前我们准备试推行技术评审,会考虑把可测试性要求也加到技术评审的环节,多谢老师提醒。

    作者回复: 做得好的都很简单,做不好的,千奇百怪。

    2021-08-18
    4
  • إ并向你招手إ祥子
    目前团队在使用sonar 作为代码质量的管理工具,其中有一条规则,没有属性依赖的方法应该是static 方法,但这种static方法实际上并没有为测试增加障碍,反而是更容易写测试的,不需要任何外部依赖,也不用做测试准备,连实例化都不用,直接调用对输入输出进行检查即可

    作者回复: 这种情况和我说的属于基础库是类似的,大部分人其实是很少有机会写这样的代码,这也是我建议从整体上规避写static的原因。

    2021-08-17
    4
  • lanlyhs
    赞,老师为单元测试的痛点指出了明路。 我们的系统现在全是 static 方法.... 只能在外围做一些接口测试 ,非常痛苦。

    作者回复: 听上去就很痛苦

    2021-08-16
    4
  • Geek_3b1096
    目前代码库很多Singleton getInstance()

    作者回复: 难以测试,需要改。

    2021-08-30
    2
  • Geek_452877
    我还是比较赞同“测试不好写(或难以)写,是设计不好导致的”,测试要好写,函数的耦合性就要低,函数的功能就必须单一。但一个现实的问题是:总有人(模块)要去负责组合这些功能,例如我用静态方法给外部模块提供一个较友好的接口。这不是很好么? 例如,外部不操心整个过程,只关心最后的结果!比如一个makcall 的静态函数

    作者回复: 能用静态方法的,不能用普通方法吗?为啥一定要执着于静态方法呢

    2021-10-06
    1
  • 飞翔
    老师 工具类 是不是应该用static?

    作者回复: 理论上是可以的,但真正值得写成工具类的并不多

    2022-10-24归属地:陕西
  • aoe
    又学到了:用中间层隔离实现细节!老师的中间层用的非常6啊
    2021-11-09
    4
  • Luke
    我是做测试的,以前看书籍的时候,多次接触到可测试性的概念;总是不能理解,原来软件的可测试性是落实在软件设计和具体的编码实践上的。
    2021-09-14
    1
  • 利刃方开
    老师好,这句话“如果我们的代码由框架调用,那么回调代码只做薄薄的一层,负责从框架代码转发到业务代码”,有什么学习资源推荐下么?不是太理解如何去这么做
    2023-05-25归属地:安徽
    1
收起评论
显示
设置
留言
18
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部