徐昊 · TDD 项目实战 70 讲
徐昊
Thoughtworks 中国区 CTO
18159 人已学习
新⼈⾸单¥98
登录后,你可以任选4讲全文学习
课程目录
已完结/共 88 讲
实战项目二|RESTful开发框架:依赖注入容器 (24讲)
实战项目三|RESTful Web Services (44讲)
徐昊 · TDD 项目实战 70 讲
15
15
1.0x
00:00/00:00
登录|注册

07|TDD中的测试(3):集成测试还是单元测试?

你好,我是徐昊。今天我们来继续学习测试驱动开发中的测试。
上节课我们介绍了行为验证,以及为什么它不应该是 TDD 的主要验证方式,而应该尽可能地采用状态验证。至此,我们介绍完了测试驱动开发中测试的基本结构,及其主要的验证方法。
有了这些做基础,我们再来讨论一下测试驱动中测试的性质,以及为什么称呼它为“单元测试”是一种误解。

集成测试还是单元测试?

首先请回忆第一讲中的视频演示,我们从功能出发,分解出来的第一个驱动开发的测试,是针对布尔选项的测试:
//ArgsTest
@Test
public void should_set_boolean_option_to_true_if_flag_present() {
BoolOption options = Args.parse(BooleanOption.class, "-l");
assertTrue(options.logging());
}
static record BooleanOption(@Option("l") boolean logging);
而后来在重构中(参看第三讲),我们抽取了 OptionParser 接口,并将上面的测试改写成了一个范围更小的测试:
//OptionParsersTest.BooleanOptionParser
@Test
public void should_set_value_to_true_if_option_present() {
assertTrue(OptionParsers.bool().parse(asList("-l"), option("l")));
}
这两个测试看起来没有什么不同,测试的功能也是一致的功能。但如果严格区分的话,第一个测试是所谓的集成测试(Integration Test)或功能测试(Functional Test),而第二个测试,则是我们常规意义上的单元测试(Unit Test),也就是对于单一单元的测试。
如上图所示,第一个测试的测试范围包含了 Args 和 OptionParser,可以看作是“集成测试”或“功能测试”。第二个测试的测试范围仅仅覆盖 OptionParser,才会被看作是“单元测试”。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

在TDD中,单元测试和集成测试的区别并不是很明显。文章中提到了通过重构,一个测试可以从单元测试变成集成测试。作者认为TDD中的测试并不应该被称为单元测试,而是应该被称为“单元级别功能测试”。这种测试能够提供快速反馈和低成本的研发测试,同时也能够兼具功能验证和错误定位的功效。文章还提到了TDD社区对于单元测试的强调,以及对于单元测试的批评和疑惑。作者通过讨论TDD中测试的性质,强调了每一个测试的功效和成本,以及测试的独立功能上下文或变化点。最后,文章提到了作者发起的“TDD专栏首发·代码评点”活动,鼓励学生动手实操,提交实战项目进行代码评点与解疑答惑。整体来说,文章强调了TDD中测试的性质和重要性,以及作者对于单元测试命名的看法和建议。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《徐昊 · TDD 项目实战 70 讲》
新⼈⾸单¥98
立即购买
登录 后留言

全部留言(15)

  • 最新
  • 精选
  • 邓志国
    TDD 已死的作者,认为TDD的T就是单元测试。所以认为TDD会生成一堆中间的小组件,所以他觉得这种方式不可持续。从这点来看他可能是对的。而现在我们说的TDD实际上是更大粒度的测试。比如在一个业务系统中,可能是对隔离了网络、DB后的业务逻辑整块进行测试,而不是对里面的每个类进行测试。我现在明白了为什么有人会问一个Entity是否需要测试。当然不,对Entity类的调用,在你对业务的测试中自然就会覆盖了。

    作者回复: 所以他也只是反对不好的tdd而已

    2022-03-23
    17
  • 枫中的刀剑
    我就被误导了。之前总以为一定要按单元测试,设计成严格的解耦,带来的问题就是过多的使用mock技术,导致后来阅读理解测试成本越来越高。现在看完这篇文章很多疑惑一下子就解开了。

    作者回复: nice

    2022-03-25
    2
    9
  • aoe
    05 06 07 课笔记 http://wyyl1.com/post/19/05 状态验证:一波操作后验证返回结果是否和预期一样 行为验证:验证一波操作是否严格按预期的顺序执行,不管结果;对 TDD 用处不大,因为大多数情况下会丧失测试的有效性 ❗️恍然大悟 在测试驱动开发中,从来没有强调必须是“单元测试”。反而在大多数情况下,都是针对不同单元粒度的功能测试。并通过这一系列不同单元粒度的功能测试,驱动软件的开发。 ⭐️ 两位超级大佬说的 Kent Beck:通过构造恰当粒度的黑盒功能测试驱动开发 Martin Folwer:DD 社区所谓的单元测试到底是“能提供快速反馈的低成本的研发测试” Martin Fowler:建议将 TDD 中的测试叫作极限单元测试(Xunit Testing),以区别于行业中的叫法

    作者回复: good

    2022-03-27
    6
  • humor
    老师,请问什么叫超过认知负载呢。比如同一段代码逻辑,我一开始可能不太熟悉,觉得它又臭又长看不太懂,但是我看了几遍熟悉了之后,就会觉得这段代码逻辑又比较容易理解了。那这段代码逻辑是超出认知负载还是未超出认知负载呢

    作者回复: 对一件事的认知不是固定的 可以被提升。一开始是超过你的负载的

    2022-04-16
    2
    3
  • Gojustforfun
    我把Test定义为:不同工作单元的功能测试。其中工作单元是指实现某项/些功能,完成某项/些工作的代码集合(类,包,组件等)。

    作者回复: good

    2022-03-23
    1
  • davix
    如果TDD是功能測試,而我覺得絕大多數功能是單個單元完不成的,那麼TDD產生的UT數就不會多。而測試金字塔理論最底層佔大多數的是UT,還成立嗎?跟TDD是不是矛盾?

    作者回复: 单元级别的功能测试

    2022-04-04
    4
  • 邓志国
    之前看《修改代码的艺术》里面的单元测试,就是指一个类的测试。这种实际上是在测试实现。如果一堆类都有了一个测试,会让我们测试代码和实现绑定死了,从而阻止重构。这点上我觉得TDD的测试更是一种对行为的测试而不是对实现。

    作者回复: 功能测试 行为测试指对sut和doc交互行为的测试

    2022-03-22
    2
  • 程序袁帅
    老马《单元测试》的中文版:https://www.yuque.com/yuanshenjian/agile/unit-test 篇幅很小,作为下午茶吧~
    2022-04-05
    8
  • keys头
    个人理解TDD其实就是一种结果导向的做事方式,或者叫“以终为始”,再配上8x的任务分解法,把大结果分解成小结果,然后稳步得到每一个小结果后,最终目标也就达成了。借用OKR中的概念的话,过程就变成了:确定 Object (目标),分解 Key Result (关键结果),获得关键结果,完成目标。所以,我更愿意把“TDD+任务分解法”叫做 OKRDD(目标分解+关键结果驱动开发)。😝
    2022-03-24
    2
    3
  • 枫中的刀剑
    正如文中所说”毕竟 TDD 中的测试,并不是一种关于测试的技术,而是通过分解功能以驱动软件开发的技术。“。这句才是TDD关注点的核心,而大多数人在谈论TDD的时候都落在单元测试的讨论上去了。 这导致很多还没有接触过TDD的人,都以为重点是单元测试。
    2022-03-25
    2
收起评论
显示
设置
留言
15
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部