何时进行单元测试和手动测试?

38

尽管单元测试在需要 API 较强的大型项目上看起来很有效(例如开发 .Net 框架 API 等),但在小型项目上可能会显得有些过度。

自动化 TDD 方法什么时候是最佳选择,何时使用手动测试技术、记录错误、分类、修复等方式更好。

另一个问题——当我在微软担任测试员时,我们被强调要让开发人员和测试人员分别负责,并且这两个团队之间的紧张关系可以帮助创造出优秀的产品。但是,TDD 是否会打破这一想法,并且是否会导致开发人员无法彻底找到自己的错误?虽然这是自动化的,但似乎有许多编写测试的方法,而且对于一组给定的测试来说,“证明”质量是否可接受是值得怀疑的。


单元测试可以提供代码文档的一种形式,如果除了代码作者之外的其他人需要进行更改以修复错误或添加新功能/增强功能,则可能非常有用。开发人员应该测试他们的代码,但在我看来,这些测试不应该是唯一的测试。 - JB King
15个回答

71
TDD的效果与项目规模无关。即使在最小的编程练习中,我也会遵循TDD的三大法则进行实践。测试不需要花费太多时间来编写,并且它们可以节省大量的调试时间。同时,它们还允许我在重构代码时不用担心任何问题。
TDD是一种纪律,类似于会计师实行的复式记账纪律。它可以防止小错误。会计师会将每笔交易输入两次,一次作为贷方,一次作为借方。如果没有犯简单错误,那么资产负债表总和就为零。这个零是一个简单的抽查,可以防止高管入狱。
同样地,程序员会提前编写单元测试作为一个简单的抽查。实际上,他们会将每一位代码都写两次:一次作为测试,一次作为生产代码。如果测试通过,那么这两个代码片段就是一致的。这两种做法都不能防止更大更复杂的错误,但它们仍然非常有价值。
TDD实践实际上并不是一种测试技术,而是一种开发实践。TDD中的“测试”一词更多地是巧合。因此,TDD并不能替代良好的测试实践和优秀的QA测试人员。事实上,让有经验的测试人员独立编写QA测试计划(通常在程序员编写代码和单元测试之前)是一个非常好的主意。

我希望这些独立的QA测试也能使用像FitNesse, Selenium, 或者Watir这样的工具进行自动化。测试应该易于被业务人员理解,易于执行,并且绝对明确无误。通常每天可以多次运行测试。

每个系统也需要手动测试。然而,手动测试不应该是例行公事。可以脚本化的测试应该自动化。只有在需要人类判断时才应该将人类放入循环中。因此,人类应该进行exploratory testing,而不是盲目地遵循测试计划。

因此,关于何时进行单元测试与手动测试的问题的简短答案是没有"对比"。你应该首先为你编写的绝大部分代码编写自动化单元测试。你应该让测试人员编写自动化QA验收测试。同时你也应该实践战略性的探索性手动测试。


很高兴在这里见到您,亲爱的Bob叔叔。为您独特的示例点赞,比如这里的双入账。谢谢。 - Snesh

7

单元测试并不意味着取代功能/组件测试。单元测试的重点非常窄,因此它们不会涉及数据库、外部服务等。集成测试会这样做,但您可以让它们聚焦在特定点上。总之,在特定问题上的答案是它们不能替换那些手动测试。

更新1:请注意,如果开发人员正在创建自动化的功能测试,则仍然需要审查其是否具有适当的覆盖范围,并根据需要进行补充。一些开发人员使用他们的“单元”测试框架创建自动化的功能测试,因为无论单元测试如何,他们仍然必须进行冒烟测试,而这确实有助于自动化 :)

更新2:对于小项目来说,单元测试并不过度,自动化冒烟测试或使用TDD也不过度。过度的是让团队在小项目上第一次尝试任何其中一项。这些工作都有一个相关的学习曲线(特别是单元测试或TDD),并且并不总是第一次正确完成。您还需要某个已经做了一段时间的人参与其中,以帮助避免陷阱并克服开始时不明显的一些编码挑战。问题是团队通常不具备这些技能。


4

测试驱动开发(TDD)是可行的情况下最佳方法。 TDD测试是自动化的,通过代码覆盖率可以量化,并且是确保代码质量的可靠方法。

与TDD相比,手动测试需要大量时间并容易出现人为错误。

并不是说TDD只由开发人员进行测试。开发人员应该负责编写测试框架的一部分。 QA应该负责更大的部分。开发人员按照他们想要测试的方式测试API。 QA以我从未想到的方式测试API,并执行看似疯狂但实际上客户会执行的操作。


3
我认为单元测试是程序员回答以下问题的辅助工具:
这段代码是否做了我想要它做的事情?
这是他们需要经常问自己的问题。程序员喜欢自动化他们可以经常做的任何事情。
分开的测试团队需要回答不同的问题:
这个系统是否做了我(和最终用户)期望它做的事情?或者它会让我感到惊讶吗?
有一整类与程序员或设计师对正确性的理解不同有关的错误,单元测试永远无法发现。

这是我们在安全关键软件中的工作方式。程序员证明他们的代码在所有状态/分支中都是安全的。测试人员(系统级别)独立测试他们对通常是高级功能要求的解释。很容易编写完美的代码,但实际上并不符合客户的需求。 - MattP

3
根据各种项目的研究(1),单元测试可以发现15%至50%(平均30%)的缺陷。这并不使它们成为您工具库中最糟糕的错误查找器,但也不是万能的解决方法。没有银弹,任何良好的QA策略都包括多种技术。
一个自动化测试运行的频率更高,因此它将更早地发现缺陷并大大减少这些缺陷的总成本 - 这就是测试自动化的真正价值。
明智地投资您的资源,并首先选择低垂的果实。我发现对于小的代码单元 - 隔离的函数和类,自动化测试最容易编写和维护。最好手动测试终端用户功能 - 一个好的测试人员会发现许多超出所需测试的奇怪问题。不要让它们相互对立,您需要两者。

开发者 vs. 测试人员 开发者在测试自己的代码方面往往表现不佳:原因有心理、技术和经济等方面 - 测试人员通常比开发者便宜。但开发者可以尽自己的一份力,让测试变得更容易。TDD使测试成为程序构建的固有部分,而不仅仅是一个事后想法,这才是TDD的真正价值。


关于测试的另一个有趣的点:100%的覆盖率是没有意义的。统计学上,错误遵循80:20规则——大多数错误都在代码的小部分中发现。一些研究表明,这甚至更加明显——测试应该集中在错误出现的地方。


(1) 编程生产力琼斯1986年等,引自《代码大全》第二版。但正如其他人所说的,单元测试只是测试的一部分,集成、回归和系统测试也可以-至少部分地-自动化。

我对结果的解释是:“许多双眼睛”具有最佳的缺陷检测能力,但前提是您必须有一些正式的流程使他们真正去看。


Studies link 是一个失效的链接。 - Adam Parkin
@AdamParkin:用谷歌搜索常见标题替换了它。让我们看看这个能持续多久(无法快速找到引用实际数据来源的可靠来源)。 - peterchen

2
每个应用程序都会进行测试。
有些应用程序的测试形式是检查我的代码是否编译,以及代码是否能够运行。
有些应用程序通过单元测试进行测试。有些开发人员对单元测试、TDD和代码覆盖率非常执着。就像其他事情一样,过度做某件事往往是不好的。
有些应用程序很幸运能够通过QA团队进行测试。有些QA团队自动化测试,有些编写测试用例并手动测试。
Michael Feathers写了《与遗留代码有效地工作》,他认为没有包含测试的代码就是遗留代码。在你经历了《大泥球》之前,我认为任何开发人员都不能真正理解良好的应用程序架构和一套精心编写的单元测试的好处。
让不同的人进行测试是一个好主意。越多的人可以查看应用程序,就越可能涵盖所有场景,包括您没有预期的场景。
最近TDD受到了负面评价。当我想到TDD时,我想到的是一些教条主义的开发者在编写实现之前会仔细地编写测试。虽然这是确实存在的,但被忽视的是通过编写测试(先于实现或紧随其后),开发者会以消费者的身份来体验该方法/类。设计缺陷和不足立即显现。
我认为项目的规模并不重要,重要的是项目的寿命。项目存活得越久,其他开发者参与的可能性就越大。单元测试就是应用程序期望的文档--一种手册。

1

我相信将QA /测试人员的专业知识(定义测试/验收标准)与TDD概念相结合是可能的,即使用开发人员拥有的API(而不是GUI或HTTP /消息接口)来驱动测试应用程序。

仍然需要独立的QA人员,但是现代测试工具(如FitNesse,Selenium和Twist)使得我们不再需要庞大的手动测试团队。


1

单元测试只能做到这个程度(所有其他类型的测试也是如此)。我把测试看作是一种“筛子”过程。每种不同类型的测试都像是你放在开发过程出口下面的筛子。流出来的东西(希望)大部分是你软件产品的特性,但它也包含了错误。这些错误有很多不同的形状和大小。

有些错误很容易找到,因为它们很大或者会被任何一种筛子捕捉到。另一方面,有些错误很光滑、闪亮,或者没有很多钩子,所以它们很容易从一种筛子中滑过去。不同类型的筛子可能有不同形状或大小的孔,因此它将能够捕捉不同类型的错误。你拥有的筛子越多,你就能捕捉到更多的错误。

显然,你拥有的筛子越多,通过的特性就越慢,因此你需要尝试找到一个平衡点,既不要花费太多时间进行测试,也不能让你无法发布任何软件。


1
自动化单元测试最好的一点(在我看来)是,当您更改(改进,重构)现有代码时,很容易测试您没有破坏它。手动再次测试所有内容将会很繁琐。

1
单元测试似乎对于需要工业级API的大型项目非常有效,但对于较小的项目可能有些过度。确实,移动API的单元测试很脆弱,但是单元测试在没有API的项目(如应用程序)上也很有效。单元测试旨在测试项目所使用的单元。它允许确保每个单元按预期工作。这是修改 - 重构 - 代码时的真正安全保障。
就项目规模而言,编写小型项目的单元测试可能过度。在这里,我将小型项目定义为一个小程序,可以手动测试,但非常容易和快速,在几秒钟内即可完成。此外,小型项目可能会增长,在这种情况下,拥有单元测试可能是有利的。
“开发人员和测试人员是不同的人,这两个团队之间的紧张关系有助于最终创建出优秀的产品。” 这种观点是有价值的。
无论采用何种开发流程,单元测试都不应该取代任何其他测试阶段,而是通过在开发阶段进行测试来补充它们,以便开发人员可以获得非常早期的反馈,而不必等待官方构建和官方测试。通过单元测试,开发团队可以交付可在下游工作的代码,而不是无错误的代码,但是可以由测试团队进行测试的代码。
总之,当手动测试真的很容易时,或者编写单元测试太复杂时,我会进行手动测试,并且不追求100%的覆盖率。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接