为什么集成测试比单元测试更重要

简介: 单元测试很棒。在假定一些数据的环境下,能顺利通过测试的系统就可算是一个好系统。 不过,现在可以直连外部资源的集成测试才让程序更有价值。谁知道那些内容商(供应商,vendor)会做出什么傻事来! 很多人一直尝试着让测试达到100%的代码覆盖率,这是很棒的想法,但我倒觉得它有些基本概念上的问题。

单元测试很棒。在假定一些数据的环境下,能顺利通过测试的系统就可算是一个好系统。

不过,现在可以直连外部资源的集成测试才让程序更有价值。谁知道那些内容商(供应商,vendor)会做出什么傻事来!



很多人一直尝试着让测试达到100%的代码覆盖率,这是很棒的想法,但我倒觉得它有些基本概念上的问题。LosTechiesRyan Svihla 提出了"反模式(anti-pattern", 有个有趣的观点: “多数应用都需要与外部资源交互”。他们有许多不错的论点,比如:

  大多数的单元测试都需一个运行着的数据库、网页或应用服务器。

确实如此。

全是同数据和外部系统相关的

我下面将要证明多数Bug并不来源于程序本身,而是由从外部输入的数据所引起的。


为什么? 因为通常Bug出现在实际的工作环境中,我们的程序总会处理不好那些外部系统输入的原始数据,或者程序输出到外部系统中的数据。而"单元测试"或TDD中所强调的是提供一组假定的数据,检验程序是否能够按照预期的方式运行。也就说整个测试是在一个假定环境下进行的。这就是为什么接口总是如此轻易就成功运行了。在这之上还可以达到自动化,预测试性,以及可重复的测试。但是仍有很多系统无法解决现实的问题。

因为这样的测试方式所能解决的仅是软件开发要面对的问题中的一部分。如何才能发现真正的问题?最终还是要让你的软件与它的外部资源连接起来运行才能发现。

举个略为抽象的例子:

 1) 一些来自外部系统的数据.

 2) 应用程序开始处理这些数据.

 3) 应用程序将处理后的数据发送到外部资源中 (一般是与第1步不同的数据)

 4) 外部数据拿到第3步的数据,在处理后再发送到应用程序.

 5) 再次接收到数据,并加以处理.

如此反复。


我们常用mocks/stubs或者类似的程序来产生第1步的数据来进行第2步的测试,而测试第5步时所使用的数据也是使用类似的方式产生的。其中第1步和第4步是不可靠,也是不可预计的,因为你根本不知道外部系统会给你什么数据。

第1步和第4步是程序在上线环境下要面对的,所以它们才是最需要关注的。

外部系统都很挑剔(External systems are finicky mean things)

对于一些e-Commerce系统,或者财务系统,各式的接口,各式的数据在各个系统间流转。


我们来谈一些高层次的问题:

1)理想情况下,当外部系统更改了要发送的数据,无论是是格式(format)或模式(schema),你希望会提前知道。这有些一厢情愿了。最近我曾与一个电子商务系统,外部数据系统的税务信息增加了一栏,同时需要应用程序调整内部逻辑。就是外部数据系统已经开始发送数据了,我们才知道的。


2)理想情况下,当外部系统声称支持新的API,你应该改变应用程序的内部逻辑,并且发送新数据。最后,你会发现,他们支持新的API,要么在他们的UAT(User Acceptance Test)环境而不在上线(PRODUCTION)的环境,或者只在上线环境中而不在UAT环境中。


3)你的程序已使用关于国内资产的采购信息很顺畅了,外部系统和程序的配合也很好。然后开始加入一些国际资产信息时,你可能并不能及时地发现数据已完全变了。

这些都是我曾遇到的场景。我要说就是你在单元测试中根据无法了解到未来面对的环境,只有实际运行时才有办法。更悲哀的是那些在凌晨3点把你叫起来的问题通常都这样产生的。

如何完善测试规格(How to setup your Specs)

我做设计也是从规格文档开始的。规格(specification)其实就是另一种测试(well-crafted tests)。我会区分规格中的单元和集成,并写不同的代码。

所谓“单元”的测试规格是测试内部的业务逻辑,看看有没有把东西都串起来了。就是在测试时提供一些场景,确保程序执行正确的逻辑,输出期望的结果。

而集成(Integration)的测试规格则和外部资源有关。直接提供一组外部资源数据,以及要返回的数据。这些是集成测试中实际关心的东西。和外部资源的交互才能真正确定程序是否可以正常工作。

[只译出主要概念,详细内容请阅读原文!翻译的初衷是因为发现接口的定义和维护常常做得不充分,工程师自主的口头交流常常带来很高的风险。这篇文章可以带来一点思考,重新审视工作中的关于接口是不是得到了充分的重视! ]

转载请注明出处:http://blog.csdn.net/horkychen
目录
相关文章
|
1月前
|
Java 测试技术 开发者
Java单元测试与集成测试:确保代码质量的最佳实践
【4月更文挑战第2天】在软件开发中,单元测试验证单个代码单元(如Java类或方法)的功能,确保其正确性;而集成测试则关注多个组件协作时的交互。JUnit是常见的Java单元测试框架,集成测试则检验组件间接口的兼容性。Spring框架提供了集成测试的支持。遵循良好编码习惯,编写可测试代码,设计全面的测试用例,是保证代码质量和稳定性的关键。
|
19小时前
|
Java 测试技术 持续交付
自动化测试实践:从单元测试到集成测试
【6月更文挑战第28天】-单元测试:聚焦代码最小单元,确保每个函数或模块按预期工作。使用测试框架(如JUnit, unittest),编写覆盖所有功能和边界的测试用例,持续集成确保每次变更后自动测试。 - 集成测试:关注模块间交互,检查协同工作。选择集成策略,编写集成测试用例,模拟真实环境执行测试,整合到CI/CD流程以持续验证软件稳定性。 自动化测试提升软件质量,降低成本,加速开发周期,是现代软件开发不可或缺的部分。
|
1月前
|
资源调度 JavaScript 测试技术
Vue的集成测试:使用VueTestUtils进行单元测试的技术博文
【4月更文挑战第24天】本文介绍了如何使用VueTestUtils进行Vue.js项目的集成测试。首先,需安装VueTestUtils和vue-template-compiler。接着,展示了如何编写测试用例,包括使用`mount`和`shallowMount`方法挂载组件,以及通过`wrapper`操作和断言组件行为。文章还讨论了单元测试与集成测试的区别,并提到了模拟依赖、交互、组件状态管理和断言的策略。最后,强调了测试的可读性和可维护性对代码质量的重要性。通过VueTestUtils,开发者能更高效地进行Vue组件的测试。
|
1月前
|
缓存 自动驾驶 测试技术
如何进行有效的Apollo测试:单元测试和集成测试指南
如何进行有效的Apollo测试:单元测试和集成测试指南
96 13
|
1月前
|
测试技术 Python
Python 的自动化测试:什么是单元测试和集成测试?在 Python 中如何进行自动化测试?
【4月更文挑战第17天】本文介绍了软件测试中的单元测试和集成测试。单元测试针对单个函数或方法,确保其功能正确;集成测试则检验多个单元交互是否正常。Python 自带的 unittest 模块提供自动化测试框架,示例代码展示了如何创建测试类及测试方法,通过断言验证字符串方法的行为。
23 1
|
1月前
|
测试技术 数据库 开发者
Django自动化测试入门:单元测试与集成测试
【4月更文挑战第15天】本文介绍了Django的自动化测试,包括单元测试和集成测试。单元测试专注于单个视图、模型等组件的正确性,而集成测试则测试组件间的交互。Django测试框架提供`TestCase`和`Client`进行单元和集成测试。通过编写测试,开发者能确保代码质量、稳定性和应用的正确协同工作。运行测试使用`python manage.py test`命令,建议将其纳入日常开发流程。
|
1月前
|
监控 JavaScript 前端开发
【TypeScript技术专栏】TypeScript的单元测试与集成测试
【4月更文挑战第30天】本文讨论了在TypeScript项目中实施单元测试和集成测试的重要性。单元测试专注于验证单个函数、类或模块的行为,而集成测试关注不同组件的协作。选用合适的测试框架(如Jest、Mocha),配置测试环境,编写测试用例,并利用模拟和存根进行隔离是关键。集成测试则涉及组件间的交互,需定义测试范围,设置测试数据并解决可能出现的集成问题。将这些测试整合到CI/CD流程中,能确保代码质量和快速响应变化。
|
1月前
|
Java 测试技术
Java 中的单元测试和集成测试策略
【4月更文挑战第19天】本文探讨了Java开发中的单元测试和集成测试。单元测试专注于单一类或方法的功能验证,使用测试框架如JUnit,强调独立性、高覆盖率和及时更新测试用例。集成测试则验证模块间交互,通过逐步集成或模拟对象来检测系统整体功能。两者相辅相成,确保软件质量和降低修复成本。
|
1月前
|
jenkins 测试技术 持续交付
单元测试和集成测试
单元测试和集成测试
33 1
|
1月前
|
缓存 测试技术 持续交付
工程化测试:Apollo的单元测试与集成测试指南
工程化测试:Apollo的单元测试与集成测试指南