【问题标题】:Are you really using unit tests? [closed]你真的在使用单元测试吗? [关闭]
【发布时间】:2010-09-22 03:26:42
【问题描述】:

我参与过很多新旧项目,它们的共同点是几乎没有一个项目使用过单元测试。我更喜欢使用它,但通常客户还没有准备好为此付费,并假设代码可以正常工作。

那么,您是在项目中使用单元测试,还是依赖您的编码技能?

【问题讨论】:

标签: unit-testing testing


【解决方案1】:

我发现新开发人员从单元测试中受益更多,而不是那些必须从可能导致失败的陷阱的严厉打击学校中学习的老开发人员。单元测试不会导致好的设计——它只会导致更可测试的设计。你需要测试你的代码,但是单元测试被宣扬的方式是危险的。 “它会迫使你更好地设计你的代码”,“你如何测试它是否正确?”。

我更喜欢编写良好的结构化代码,当您阅读它时,它会自动告诉您它试图完成什么以及它是如何完成的。函数/类应该小而简洁。他们应该只承担一项责任。单元测试不能防止逻辑错误。

单元测试比其他任何东西都提供更多的误报,尤其是在第一次编写项目时。好的设计胜过测试——测试应该只是验证阶段。我从来没有买过测试先于其他所有概念。以我的经验,这种思路倾向于以可扩展代码为代价来支持可测试性(对于一次性项目或一次性实用程序可能没问题,但具有讽刺意味的是,单元测试对这些来说并不重要)。

【讨论】:

    【解决方案2】:

    我从经验中知道,当我在没有单元测试的情况下编写代码时,我会遇到一些需要解决的问题,但是当我编写单元测试时,我很少听到问题。此外,从编写单元测试的时间开始,我开始编写更好的代码。我研究方法并思考它们可能失败的方式,并从一开始就构建它们以不失败或至少以更好的方式失败。

    单元测试对于编写更好的代码至关重要,但它也会让您成为更好的开发人员,因为您可以在开始测试之前发现可能出错的地方并修复它们。

    【讨论】:

      【解决方案3】:

      我会说实话。我最近才开始编写单元测试,当我回过头来修改我过去糟糕的旧 DLL 时,我会蹲下来编写单元测试以使其接近 100% 的代码覆盖率。我说“接近”是因为由于代码的结构方式,它没有考虑到模拟或单元测试(这在抽象类或抽象类中经常发生) P/Invoke 到本机代码)。虽然我知道 100% 的代码覆盖率与 100% 的所有代码执行路径不同,但我发现进行测试是一种很好的方式来判断我何时做的事情会破坏很多的东西。

      老实说,这可能是许多开发人员(包括我自己)花了这么长时间才开始采用单元测试的原因之一(我们暂时不要进入 TDD)。

      我并不是说这些都是正当的理由,但它们或多或少地经过了我的思考,我敢打赌它们也经过了你的一些思考:

      • 首先,有这样的想法:“哦,我已经编写了一堆零测试的代码,而且我已经被那座山压垮了,我可能没有时间在其上添加更多测试代码。”

      • 其次,没有人喜欢谈论经典的代码-运行-调试循环实际上在您“足够好”时工作的事实

        • 编写不会改变旧代码行为的新代码
        • 从事相对较小的软件项目或一次性实用程序
        • 项目的唯一开发人员(您可以在一定程度上记住大部分内容)
      • 第三,当您维护现有代码时,单元测试更容易理解,而且如果您一直在编写新代码,那么好处不会立即显现出来。当你的工作是生产一个实用程序并且不再接触它时,开发人员在单元测试中几乎看不到任何价值,因为他们可能不会在维护程序员时或在公司工作(谁希望在那里是一个单元测试)来了。

      • 第四,单元测试是一项相当新的创新。 (哦,嘘......我知道这个想法一直存在,尤其是在关键任务和 DoD 应用程序中,但是对于像我这样的“Joe the Plumber Developer”类型?单元测试不是在我这十年早期的整个 CS 本科生涯中都提到过;在 2008 年,我听说这是 101 级以上所有项目的要求。Visual Studio 直到今年才获得内置测试框架,甚至只有专业版。)我的无知是幸福的吗?当然,而且我认为很多因为这是他们的日常工作(这很好)而编写代码的人根本不知道。如果他们是,那么他们知道他们必须保持最新状态,但是当涉及到学习一种新方法时(尤其是涉及编写更多代码并在需要新功能时花费更多前期时间的方法昨天) 表示它将被推回。这是长尾,在十年左右的时间里,我们关于单元测试的讨论将看起来像我们关于面向对象编程在 1990 年代开启新的开发时代的喃喃自语一样古怪。哎呀,如果我已经开始了单元测试,那肯定快结束了,因为我通常是个白痴。

      • 第五,对某些代码区域进行单元测试真的很困难,这让我吓了一跳。想到了多线程事件队列、图形渲染和 GUI。许多开发人员意识到这一点并认为“哎呀,单元测试对于库代码来说会很棒,但我最后一次只写一个类库是什么时候。”需要一段时间才能过来。为此,没有单元测试并不一定意味着前面有糟糕的代码。

      • 最后,有时来自单元测试倡导者的宣传水平可能令人生畏和令人反感。说真的,我认为我是个白痴,因为我无法理解如何模拟某个界面以及为什么要模拟。自私地,如果只是因为每个人都不会闭嘴,我想讨厌单元测试。没有灵丹妙药。

      所以,为这篇漫无边际的帖子道歉。总结:

      • 好久没做单元测试了。现在我愿意。单元测试是一个很好的工具,尤其是在维护期间。

      • 对于现有项目,您至少可以进入并编写一个记录当前输入及其输出的测试。当您将来更改那一大堆模糊的代码时,您将能够查看您是否更改了那个小快照。这也是改变公司发展文化的绝佳方式。

      让火焰开始吧! =)

      【讨论】:

      • 很有用,但我觉得你说快结束我不同意
      • 当您在应用程序中使用 MongoDB 数据库时,我觉得单元测试会更有用,尤其是在测试实体的 CRUD 操作时,因为 MongoDB 将其留给应用程序开发人员来确保外键引用完整性被维持。与 RDMS 数据库不同,MongoDB 和许多其他 NoSQL 数据库将有效数据关联的执行留给应用程序开发人员。
      【解决方案4】:

      我的公司为航空航天工业的多家公司生产系统组件。 FAA 要求质量级别 A 安全关键飞行软件的修改条件/决策覆盖范围 (DO-178-B) 因此,为了验证我们(再次来自 DO-178-B):

      通常需要分析所有代码以及从测试和结果到所有需求的可追溯性(取决于软件级别)。

      此过程通常还涉及:

      基于需求的测试工具

      代码覆盖率分析工具

      在此过程中执行的测试的其他名称可以是:

      单元测试

      集成测试

      黑盒和验收测试

      单元测试总是会发现代码错误。

      【讨论】:

        【解决方案5】:

        在参与了几个正在生产但需要主要新功能的项目之后,作为技术负责人启动项目,我的底线之一是必须进行单元测试。

        尝试重写未经单元测试编写的代码的成本太高了。代码的结构总是很糟糕(一个数千行的网络服务都在一个代码中?)并且在不引入错误的情况下对其进行更改(即使它结构良好)是一个非常痛苦的过程。

        当项目进入灭火模式时尤其如此(没有单元测试也会导致项目进入那种状态)——客户变得脾气暴躁,他们对项目失去了信心,没有什么比被这个可怜的家伙试图在没有引入一大堆回归错误的情况下进行下一个修复,甚至没有进行单元测试。

        通过预先解释测试的价值,可以很容易地避免或至少减轻这些情况。当然,在某些情况下,单元测试并不那么重要,但它们确实是个例外。

        所以是的 - 我坚持进行单元测试,并且花了很多时间来修复其他依赖他们的编码技能的开发人员造成的混乱。

        【讨论】:

          【解决方案6】:

          如果进行单元测试,您的客户可能会总体上节省资金。如果在开发阶段的后期而不是在单元测试期间发现,单元测试防止的一些错误更容易造成负担。以后省了这么多头疼的事,现在我用了我想我再也回不去了。

          【讨论】:

            【解决方案7】:

            另一个非常有用的提醒,说明为什么要在本文中出现的任何地方进行单元测试:Top 12 Reasons to Write Unit Tests 我需要将它刻在我的视网膜上。

            我可以亲自证明从一开始就考虑如何测试某事物的价值,通过每次迭代开发测试。我自己需要更系统。我现在正在打印该列表。

            【讨论】:

              【解决方案8】:

              关于依赖我的编码技能,我发现当我使用 TDD 时我的编码技能实际上得到了提高,并且当我打破测试时依赖我的单元测试来纠正我。您可以学习如何使用许多语言功能,因为您可以通过调整来测试假设。

              【讨论】:

                【解决方案9】:

                我喜欢 Bob Martin 的类比:想象你是一名外科医生。对于一个想要支付手术费用但告诉你不要提前洗碗的病人,你会说什么?

                当客户聘请我编写代码时,他们将我聘为专业人士,即具有专业技能和纪律的人。我的工作是让他们“代码按应有的方式工作”,我知道最好的方法是使用 TDD。

                【讨论】:

                  【解决方案10】:

                  我是单元测试的忠实拥护者,主要是因为它完全让人上瘾 - JUnit 中的“代码-测试-看到可怕的红色条-修复-测试-看到可爱的绿色条”循环严重刺激了内啡肽。

                  【讨论】:

                    【解决方案11】:

                    我尽可能使用单元测试和 tdd。然而,根据我对每个单元测试倡导者的经验,有三个或更多的开发人员并不真正相信编写单元测试值得付出努力,并且会减慢开发速度。但是这些人往往保持安静,所以你不太可能在这里看到很多人。

                    【讨论】:

                      【解决方案12】:

                      我编写的大多数函数都有测试。就像上面许多人所说的那样,单元测试是软件工程的重要组成部分。所以,回答你的问题,是的,我真的会编写和运行测试。

                      此外,使用continuous integration,回归测试将自动进行并不断报告。

                      【讨论】:

                        【解决方案13】:

                        我做单元测试。我目前正在构建一个约束验证引擎,我的客户希望它是防弹的。好吧,没有单元测试,我会死于压力......

                        所以是的,我用它!

                        【讨论】:

                          【解决方案14】:

                          单元测试是开发的重要组成部分,并且(我发现)实际上会减少完成项目的时间,同时提高整体质量,尤其是在 TDD 风格中完成时。

                          【讨论】:

                            【解决方案15】:

                            我同意 Ken 的观点,即单元测试是软件开发的一部分。

                            关于成本问题,确实比写代码加单元测试比只写代码要长。但是,当您编写代码及其测试时 - 称为 TDD - Test-Driven Development,您会以“工作的干净代码”结束。当你只写代码时,你必须让它工作,这可能是漫长而痛苦的。

                            另一个好处是您知道自己在哪里,因为已编写的代码已经过单元测试。

                            为了回答您的问题,是的,我会尽可能在我的项目中使用单元测试。我为所有新代码编写单元测试,并为遗留代码努力。

                            【讨论】:

                              【解决方案16】:

                              编写和运行单元测试是健康编码过程的一部分,它不是客户应该选择付费或不付费的附加内容。

                              测试策略和其他任何问题一样都是一个编码问题:使用什么数据结构、变量命名约定、注释标准等。

                              【讨论】:

                              • 您对“健康”一词的选择让人联想到急诊室:“您想要防腐剂,需要额外付费吗?” +1
                              • 希望编码环境更像医学研究,而不是创伤科。
                              【解决方案17】:

                              单元测试不能是事后的想法,它是并且必须是影响你设计的东西。我什至可以说,即使您从不编写或调用单个单元测试,它在领先的紧密组件驱动软件方面所带来的好处在 95% 的时间里都是值得的。

                              【讨论】:

                                【解决方案18】:

                                使用单元测试一种编码技巧。

                                我发现它几乎不会增加编码时间的开销。最重要的是,生成的代码往往更容易理解和重构,维护时间也大大减少。

                                在这里全面讨论好处:Is Unit Testing worth the effort?

                                【讨论】:

                                • 讨论中提到的 TDD 是一个关键点(对我来说)。不必先编写代码,然后单独编写测试,而是将测试作为开发过程的一部分编写
                                • 好点。问题是当我和别人一起工作时,他们往往不知道什么是测试,他们只是把测试想成“打开浏览器并测试运行功能。它对我有用吗?很好”。顺便说一句,StackOverflow 没有经过特别测试(参见关于 MVC 的视频表格 PDC)。 ;-)
                                • 当您在应用程序中使用 MongoDB 数据库时,我觉得单元测试会更有用,尤其是在测试实体的 CRUD 操作时,因为 MongoDB 将其留给应用程序开发人员来确保外键引用完整性被维持。与 RDMS 数据库不同,MongoDB 和许多其他 NoSQL 数据库将有效数据关联的执行留给应用程序开发人员。
                                【解决方案19】:

                                我经常对复杂的数学算法使用单元测试,例如 LineIntersectsLine 等函数,您可以在其中定义一些重要的示例进行测试。之后,更容易控制此功能。您可以简单地重写/优化它并测试它是否仍然有效,或者如果遇到错误,您可以添加新测试然后尝试纠正这些错误。

                                【讨论】:

                                  猜你喜欢
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2010-10-05
                                  • 2010-09-05
                                  • 2022-01-22
                                  • 1970-01-01
                                  • 2011-11-23
                                  • 2010-11-05
                                  相关资源
                                  最近更新 更多