【问题标题】:When to unit-test vs manual test何时进行单元测试与手动测试
【发布时间】:2010-10-10 17:29:02
【问题描述】:

虽然单元测试对于 API 需要具有工业实力的大型项目(例如开发 .Net 框架 API 等)似乎很有效,但对于较小的项目来说,它似乎有点矫枉过正。

什么时候自动化 TDD 方法是最好的方法,什么时候最好只使用手动测试技术、记录错误、分类、修复它们等等。

另一个问题——当我在微软担任测试人员时,有人向我们强调,让开发人员和测试人员成为不同的人是有价值的,这两个群体之间的紧张关系有助于在结束。 TDD 能否打破这个想法并创造一个开发人员可能不是严格发现自己错误的合适人选的情况?它可能是自动化的,但似乎有很多方法可以编写测试,并且一组给定的测试是否会“证明”质量是可以接受的,这是值得怀疑的。

【问题讨论】:

  • 单元测试可以提供一种代码文档形式,如果代码作者以外的其他人必须进行更改以修复错误或添加新功能/增强功能,这可能非常有用。开发人员应该测试他们的代码,但这些测试不应该是唯一的,IMO。

标签: unit-testing testing tdd


【解决方案1】:

只要可行,TDD 就是最好的方法。 TDD 测试是自动的、可通过代码覆盖率量化的以及确保代码质量的可靠方法。

手动测试需要大量时间(与 TDD 相比)并且会出现人为错误。

没有什么说 TDD 意味着只有开发人员测试。开发人员应该负责编写一定比例的测试框架。 QA 应该负责更大的部分。开发人员以他们想要的方式测试 API。 QA 以我从未想过的方式测试 API,并且做的事情虽然看起来很疯狂,但实际上是由客户完成的。

【讨论】:

    【解决方案2】:

    单元测试并不是要取代功能/组件测试。单元测试非常专注,因此它们不会影响数据库、外部服务等。集成测试可以做到这一点,但你可以让它们真正专注。最重要的是,在具体问题上,答案是它们不会取代那些手动测试。 现在,自动化功能测试+自动化组件测试当然可以替代人工测试。这将在很大程度上取决于项目和方法,具体取决于谁将实际执行这些操作。

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

    更新 2: 单元测试对于小型项目来说并不过分,自动化冒烟测试或使用 TDD 也不是。让团队第一次在这个小项目上做任何这样的事情是矫枉过正的。做任何这些都有相关的学习曲线(特别是单元测试或 TDD),而且一开始并不总是会正确完成。您还希望有人参与其中一段时间​​,以帮助避免陷阱并克服一些在开始时并不明显的编码挑战。问题是团队拥有这些技能并不常见。

    【讨论】:

      【解决方案3】:

      我会说单元测试是程序员回答问题的辅助工具:

      这段代码是否符合我的想法 有吗?

      这是一个他们需要经常问自己的问题。程序员喜欢在力所能及的范围内自动化他们经常做的任何事情。

      单独的测试团队需要回答一个不同的问题:-

      这个系统是否符合我(和最终用户)的期望 去做?还是让我大吃一惊?

      有一大类错误与程序员或设计师有关,他们对单元测试永远不会发现的正确内容有不同的想法。

      【讨论】:

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

      单元测试只能走到这一步(就像所有其他类型的测试一样)。我将测试视为一种“筛选”过程。每种不同类型的测试都像一个筛子,您放置在开发过程的出口下方。出来的东西(希望)主要是您的软件产品的功能,但它也包含错误。这些虫子有许多不同的形状和大小。

      有些虫子很容易找到,因为它们很大,或者基本上会被任何类型的筛子捕获。另一方面,有些虫子光滑而有光泽,或者侧面没有很多钩子,所以它们很容易从一种筛子中滑出。不同类型的筛子可能有不同形状或大小的孔,因此它能够捕获不同类型的虫子。筛子越多,抓到的虫子就越多。

      很明显,您使用的筛子越多,功能通过的速度就越慢,因此您需要尝试找到一个不花太多时间测试您的快乐的媒介永远不要发布任何软件。

      【讨论】:

        【解决方案5】:

        自动化单元测试的最佳点 (IMO) 是,当您更改(改进、重构)现有代码时,很容易测试您没有破坏它。一遍又一遍地手动测试所有内容会很乏味。

        【讨论】:

          【解决方案6】:

          每个应用程序都经过测试。

          一些应用程序以我的代码是否编译以及代码是否显示为功能的形式进行测试。

          某些应用程序通过单元测试进行测试。一些开发人员对单元测试、TDD 和代码覆盖率很感兴趣。像所有事情一样,太多往往不是坏事。

          幸运的是,一些应用程序能够通过 QA 团队进行测试。一些 QA 团队自动执行测试,其他团队编写测试用例并手动测试。

          Michael Feathers,他写道:Working Effectively with Legacy Code,他写道,未包含在测试中的代码是遗留代码。在您体验过Big Ball of Mud 之前,我认为没有任何开发人员真正了解良好的应用程序架构和一套编写良好的单元测试的好处。

          让不同的人进行测试是个好主意。可以查看应用程序的人越多,就越有可能涵盖所有场景,包括您不打算发生的场景。

          TDD 最近的名声很差。当我想到 TDD 时,我会想到教条式的开发人员在编写实现之前会一丝不苟地编写测试。虽然这是真的,但被忽略的是通过编写测试,(首先或不久之后)开发人员从消费者的角度体验方法/类。设计缺陷和缺点立即显现出来。

          我认为项目的规模是无关紧要的。重要的是项目的生命周期。一个项目的生命周期越长,除编写它的开发人员之外的开发人员就越有可能在它上面工作。单元测试是应用程序预期的文档——某种手册。

          【讨论】:

            【解决方案7】:

            单元测试对于 API 需要具有工业实力的大型项目似乎很有效,但对于较小的项目来说,这似乎是矫枉过正。

            移动 API 的单元测试确实很脆弱,但单元测试在应用程序等无 API 项目上也很有效。单元测试旨在测试项目所使用的单元。它允许确保每个单元按预期工作。在修改 - 重构 - 代码时,这是一个真正的安全网。

            就项目的规模而言,确实为小型项目编写单元测试可能是矫枉过正。在这里,我将小项目定义为一个小程序,可以手动测试,但非常容易和快速,不超过几秒钟。一个小项目也可以增长,在这种情况下,手头有单元测试可能是有利的。

            让开发人员和测试人员成为不同的人是有价值的,这两个群体之间的紧张关系最终有助于创造出出色的产品。

            无论开发过程是什么,单元测试并不是要取代任何其他阶段的测试,而是在开发阶段用测试来补充它们,这样开发者就可以得到非常早的反馈,而不必等待正式版本和官方测试。通过单元测试,开发团队可以向下游交付可以工作的代码,而不是无错误的代码,而是可以由测试团队测试的代码。

            总而言之,当它真的很容易,或者编写单元测试太复杂时,我会手动测试,而且我的目标不是 100% 的覆盖率。

            【讨论】:

              【解决方案8】:

              TDD 的有效性与项目规模无关。即使是最小的编程练习,我也会练习the three laws of TDD。测试不需要太多时间来编写,它们节省了大量的调试时间。它们还允许我重构代码而不用担心破坏任何东西。

              TDD 是一门类似于会计师实行的复式记账法的学科。它可以防止小错误。会计师将每笔交易输入两次;一次作为贷方,一次作为借方。如果没有犯简单的错误,那么资产负债表的总和将为零。这个零是一个简单的抽查,可以防止高管入狱。

              出于同样的原因,程序员在编写代码之前编写单元测试作为简单的抽查。实际上,他们将每一位代码编写了两次;一次作为测试,一次作为生产代码。如果测试通过,则这两位代码是一致的。这两种做法都不能防止更大和更复杂的错误,但两种做法都很有价值。

              TDD 的实践并不是真正的测试技术,它是一种开发实践。 TDD 中的“测试”一词或多或少是一个巧合。因此,TDD 不能替代良好的测试实践和良好的 QA 测试人员。事实上,让经验丰富的测试人员独立(并且通常在编写代码(及其单元测试)的程序员之前)编写 QA 测试计划是一个非常好的主意。

              我更喜欢(确实是我的热情)这些独立的 QA 测试也可以使用 FitNesseSeleniumWatir 等工具自动化。测试应该易于业务人员阅读、易于执行且完全明确。您应该能够在接到通知后立即运行它们,通常每天运行多次。

              每个系统也需要手动测试。但是,手动测试不应该死记硬背。可以编写脚本的测试应该是自动化的。您只想在需要人为判断时将人置于循环中。因此人类应该做exploratory testing,而不是盲目地遵循测试计划。

              因此,对于何时进行单元测试与手动测试的问题,简短的回答是没有“对比”。您应该首先为您编写的绝大多数代码编写自动化单元测试。您应该有测试人员编写的自动化 QA 验收测试。您还应该练习战略性探索性手动测试。

              【讨论】:

              • 很高兴在这里见到您亲爱的鲍勃叔叔 ...+1 为您提供独特的示例...例如此处的双重记账。谢谢。
              【解决方案9】:

              您的问题似乎更多地是关于自动化测试与手动测试。单元测试是自动化测试的一种形式,但却是一种非常具体的形式。

              不过,您关于拥有单独的测试人员和开发人员的评论是正确的。但这并不意味着开发人员不应该进行某种形式的验证。

              单元测试是开发人员快速获得有关他们所做工作的反馈的一种方式。他们编写测试以快速运行小单元代码并验证其正确性。从某种意义上说,它并不是真正的测试,就像编译器的语法检查不是测试一样,您似乎使用了测试这个词。单元测试是一种开发技术。使用这种技术编写的代码可能比没有使用这种技术编写的代码质量更高,但仍需要通过质量控制。

              关于测试部门的自动化测试与手动测试的问题更容易回答。每当项目变得足够大以证明编写自动化测试的投资是合理的时,您都应该使用自动化测试。当您有很多小的一次性测试时,您应该手动进行。

              【讨论】:

                【解决方案10】:

                根据各种项目的研究(1),单元测试发现15..50%的缺陷(平均30%)。这不会使它们成为您武器库中最糟糕的错误发现者,但也不是灵丹妙药。 没有灵丹妙药,任何好的 QA 策略都包含多种技术。


                自动化的测试运行得更频繁,因此它会更早地发现缺陷并极大地降低这些缺陷的总成本——这就是测试自动化的真正价值。

                明智地投资您的资源,并首先摘下低垂的果实。
                我发现自动化测试最容易编写和维护小代码单元——隔离的函数和类。最终用户功能更容易手动测试 - 一个好的测试人员会发现许多超出所需测试的奇怪之处。不要让它们相互对抗,你需要两者。


                开发人员与测试人员 众所周知,开发人员不擅长测试自己的代码:原因是心理、技术和最重要的经济因素 - 测试人员通常比开发人员更便宜。但开发人员可以尽自己的一份力量,让测试变得更容易。 TDD 使测试成为程序构建的内在组成部分,而不仅仅是事后的想法,这才是 TDD 的真正价值。


                关于测试的另一个有趣的点是:100% 的覆盖率没有意义。从统计上看,错误遵循 80:20 规则——大多数错误都存在于一小段代码中。 Some studies 建议这更加清晰 - 测试应该集中在错误出现的地方。


                (1) Programming Productivity Jones 1986 u.a.,引自 Code Complete, 2nd。编。但正如其他人所说,单元测试只是测试的一部分,集成、回归和系统测试也可以——至少部分地——自动化。

                我对结果的解释:“多只眼睛”的缺陷检测效果最好,但前提是你有一些正式的过程可以让它们看起来像真的。

                【讨论】:

                • 学习链接是死链接。
                • @AdamParkin:替换为谷歌搜索常见的标题。让我们看看这个持续多久(无法快速找到引用实际数据来源的可靠来源)
                【解决方案11】:

                只是为了澄清许多人似乎错过的东西:

                TDD,在某种意义上 “编写失败的测试,编写代码使测试通过,重构,重复” 在您编写单元测试时通常是最有效和最有用的。

                您只围绕您正在处理的代码的类/函数/单元编写单元测试,使用模拟或存根来抽象出系统的其余部分。

                “自动化”测试通常是指更高级别的集成/验收/功能测试 - 您可以围绕这一级别的测试进行 TDD,它通常是大量 ui 驱动代码的唯一选择,但是您应该知道,这种测试更脆弱,更难编写测试优先,并且无法替代单元测试。

                【讨论】:

                  【解决方案12】:

                  在 QA 和开发这两个方面,我认为应该始终有人手动测试您的代码。即使您使用的是 TDD,作为开发人员,您也可能无法通过单元测试涵盖很多内容,或者可能不会考虑测试。这尤其包括可用性和美学。美学包括正确的拼写、语法和输出格式。

                  现实生活中的例子1:

                  一位开发人员正在创建一份报告,我们在 Intranet 上显示给经理。有很多公式,所有的公式都是开发人员在代码提交给 QA 之前测试的。我们验证了这些公式确实产生了正确的输出。我们几乎立即要求开发部门纠正一个事实,即数字在紫色背景上以粉红色显示。

                  现实生活中的例子 2:

                  我在业余时间使用 TDD 编写代码。我喜欢认为我对它进行了彻底的测试。有一天,当我打开一个消息对话框时,我的妻子走过,读了它,并立即问:“那条消息到底是什么意思?”我认为该消息相当清楚,但当我重新阅读它时,我意识到它正在谈论树控件中的父节点和子节点,并且可能对普通用户没有意义。我改写了这条信息。在这种情况下,这是一个可用性问题,我自己的测试没有发现。

                  【讨论】:

                    【解决方案13】:

                    我相信可以将 QA/测试人员的专业知识(定义测试/验收标准)与使用开发人员拥有的 API(相对于 GUI 或 HTTP/消息传递接口)的 TDD 概念来驱动正在测试的应用程序。

                    拥有独立的 QA 人员仍然很重要,但我们不再需要庞大的手动测试团队来使用 FitNesse、Selenium 和 Twist 等现代测试工具。

                    【讨论】:

                      【解决方案14】:

                      TDD 让作为开发人员的我相信我对代码所做的更改会产生预期的结果,并且只会产生预期的结果,因此将 TDD 比喻为“安全网”是有用的;在没有它的情况下更改系统中的任何代码,您可能不知道您还破坏了什么。

                      开发人员和测试人员之间的工程紧张关系确实是个坏消息;开发人员培养了一种“好吧,测试人员得到报酬是为了发现错误”的心态(导致懒惰),而测试人员——感觉好像如果他们没有发现任何错误,他们就没有被看到去做他们的工作——抛出尽可能多地解决琐碎的问题。这是对每个人时间的严重浪费。

                      根据我的拙见,最好的软件开发是测试人员同时也是开发人员,并且单元测试和代码作为结对编程练习的一部分一起编写。这立即使两个人站在问题的同一边,朝着同一个目标共同努力,而不是让他们彼此对立。

                      【讨论】:

                        【解决方案15】:

                        单元测试与功能测试不同。而就自动化而言,通常应该考虑当测试周期将重复超过 2 或 3 次时......它是回归测试的首选。如果项目很小或者不会经常更改或更新,那么手动测试是一个更好且成本效益更低的选择。在这种情况下,自动化将证明脚本编写和维护成本更高。

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 2012-01-08
                          • 1970-01-01
                          • 2019-11-02
                          • 1970-01-01
                          • 1970-01-01
                          • 2013-01-21
                          • 1970-01-01
                          相关资源
                          最近更新 更多