组件测试、单元测试的目的
超越单元测试
史蒂文·桑德森(Steven Sanderson ) 写道: “单元测试的好处与被测代码的非显而易见性相关。” 我大致同意这种观点作为一般准则。 在简单的“获取”和“设置”方法的单元测试中,我看不到什么价值。 通过代码审查比通过单元测试更容易评估某些方法。
只要不走太远, 代码覆盖率的概念就非常有用。 代码覆盖率似乎可以在一段时间内提供较高的回报,但是当获得额外的代码覆盖率会付出更大的代价且可能不值得时,收益就会递减。 同样重要的是要认识到,即使是通常非常昂贵的100%代码覆盖率,通常也意味着只执行了所有代码行,而不检查代码中所有可能的路径。
所有代码的单元可测试性均不相同
选择性单元测试–成本和收益一文清楚地阐明了不同类型代码的单元测试在难度(成本)和优点(收益)方面的差异。 在单元测试的优点/好处高而成本/工作量低的情况下,单元测试的价值显而易见。 相反,有些类型的代码几乎无法从单元测试中受益。
还有其他有效的测试类型
我已经看到多个不同的开发人员团队完美地构建和单元测试了各自的代码库,然后遭受了尝试将其经过完全单元测试的代码与其他组的经过单元测试的代码进行集成的痛苦。 当参与的小组根据自己的假设编写了全面的单元测试 ,而不考虑功能和集成测试时,就会发生这种情况。 总是需要一定数量的最小单元测试,但是在某些情况下,不太重要的单元测试不能代替更好或更全面的集成测试。 在查看代码覆盖率时,我更喜欢从所有类型的测试中查看代码覆盖率,而不仅仅是通过单元测试提供的代码覆盖率。
Cedric Beust在他富有洞察力的专栏《从单元测试小组思考中 脱颖而出》 ( 创建TestNG并撰写了《下一代Java测试》 )写道:
我也质疑单元测试正在以其他种类的测试(功能,集成等)为代价而受到的关注。 事实是功能测试为您的用户服务,而单元测试则为您(开发人员)服务。 单元测试只是一种便利,它使您可以更快地查找错误。 归根结底,编写测试的原因是为了确保您的用户能够在您的应用程序中高效工作,而不是确保您可以更快地进行调试。
我也喜欢Igal Tabachnik 在单元测试失败的帖子中所说的:“成功的单元测试之路始于了解什么是单元测试,但最重要的是,什么不是。”
单元测试并非最终目的
不仅存在其他有价值的测试类型,而且还有其他有价值的软件开发策略和方法可用于生产满足或超出客户期望的高质量软件。 单元测试是这种总体方法的重要组成部分,但不应减少或掩盖其他方法,例如设计和代码检查,适当的协作,代码分析器等。
牺牲其他可测试性
正如我认为的单元测试那样有价值,我可能发现令Java感到最沮丧的是,为了单元测试,必须在生产代码中折衷所需的语言设计功能。 可以肯定的是,在许多情况下,单元测试鼓励在生产代码中采用更好的做法 。 例如,单元测试鼓励使用较小的方法,该功能通常被认为是代码可维护性和可读性的强项。 但是,有时候我想将类定为final
或者将方法定为final
或private
,这可能与单元可测试性正交。
让我不得不放弃长期的设计考虑因素和好处才能使测试成为可能。 我希望我提供的软件具有高质量,并享有可读性和可维护性。 在某些情况下,以可测试性的名义很难放弃其中的一些。 幸运的是,单元测试通常要求更好的设计。 但是,当我必须在优雅的设计和生产代码与被黑的测试代码之间进行选择以测试优雅的设计或被黑客入侵的设计和生产代码以容纳优雅的测试代码之间进行选择时,请记住单元测试本身并非最终提供了适当的参考框架打电话。
好消息是,现代的单元测试框架正在稳步减少生产代码中必须折衷以支持单元测试的期望特征的类型。 诸如PowerMock之类的单元测试框架使用字节码操作来克服大多数此类问题。
集体思考
无论我们称其为Lemming效应,还是同伴的压力或团队思考 ,毫无疑问,我们在软件开发社区中倾向于追逐时尚和闪亮事物 。 多年来,单元测试一直是软件开发的一部分,但是在过去的十年中,对单元测试的日益重视使软件开发受益。 单元测试在软件开发中具有悠久的历史,并且自从证明自己不是时尚已经很久了。 但是,有时我会感到有些开发人员(尤其是那些没有意识到单元测试已经进行了多长时间的开发人员)认为我们其他人不了解这是新事物。 他们热衷于将其推广为“新事物”,实际上使单元测试的行为比单元测试的目标更为重要。
在软件开发中,常常是福音传教士和特定产品,语言,框架或技术的捍卫者,无法允许就与其最喜欢的物品进行讨论的任何弱点或缺点的暗示。 任何暗示他们的首选产品可能都不是最好的建议,因为切成薄片的面包会遭到嘲笑和嘲笑。 这种荒谬和不切实际的立场减少了关于与给定方法相关的优势,劣势,机会,风险和成本的建设性论述。 在单元测试的情况下,这可能会由于以下事实而变得更加复杂:许多开发人员多年来对这种做法持怀疑态度,并且对变更进行了强有力的宣传,该变更在很大程度上已经成功了,但现在不知道该如何包含本身。
结论
该职位假定资源和时间表有限。 对于那些没有面对有限的资源和较短的时间表的奢侈的人来说,可能有足够的时间来编写和维护所有类型的代码的所有测试,而不管它们多么琐碎并且仍然可以及时交付最终产品。 但是,我们许多人处于必须评估软件开发各个方面的成本和收益的情况下。 在这种情况下,重要的是要始终专注于真正的长期目标,并使用有效的单元测试来实现此目标,同时不允许单元测试本身成为最终目标。 与软件开发中的大多数事情一样,单元测试的级别和类型应基于对获得的价值与花费的成本的经验判断。 单元测试是达到目的的一种手段。 这本身不是目的。
参考和其他相关资源
- JCG合作伙伴 Dustin Marx在Inspired by Actual Events博客上 提出了单元测试的目的 。
- 脱离单元测试小组的思想 (2011年8月30日)
- 选择性单元测试–成本和收益 (2009年11月4日)
- 单元测试值得吗? (2009年1月)
- 播客38 (2009年1月31日)
- 您可能正在看所有错误的单元测试 (2009年2月11日)
- 如何量化单元测试的价值 (2011年9月7日)
- 单元测试的神话与实践 (2012年1月5日)
- 邪恶的单元测试。 (2012年1月27日)
- 单元测试失败的地方 (2011年6月24日)
- 单元测试的谎言:这就是为什么我喜欢它们 (2011年10月21日)
- 您的单元测试对您不利 (2009年2月17日)
- 编写单元测试的十个理由 (2010年5月31日)
翻译自: https://www.javacodegeeks.com/2012/03/unit-testing-is-means-to-end.html
组件测试、单元测试的目的