【问题标题】:Scenarios where automated testing is unhelpful自动化测试无用的场景
【发布时间】:2009-01-24 16:23:29
【问题描述】:

在哪些情况下单元测试和 TDD 之类的东西比它们的价值更麻烦?

我想出的一些事情是:

  • 当生成测试数据很棘手时:有时,能够提出有效的、非平凡的测试数据本身就是一个挑战。
  • 验证代码正确性的唯一实用方法是运行它。
  • 当您测试设计的视觉元素时。

还有哪些其他情况?

【问题讨论】:

    标签: testing tdd


    【解决方案1】:

    我相信你的前两点是无效的。

    • 创建测试数据可能是一个挑战(事实上,它通常是编写单元测试的主要部分),但这只是你必须接受的事情,而不是放弃单元测试的理由.这不是不可能的,否则你怎么知道你的应用是否正常运行?
    • 单元测试运行代码以验证其正确性 - 我没有发现问题。

    应用程序的方面肯定是无法进行单元测试的 - 视觉布局(屏幕或打印)就是这样一个方面,一般来说可用性也是如此 - 无法真正正式指定的东西。

    单元测试可能不适用的情况是,当您面临的现有应用程序在开发时没有考虑可测试性甚至模块化(Big Ball of Mud 反模式)。但即便如此,如果您知道您必须在相当长的时间内维护和扩展这个野兽,那么找到一种方法来自动测试应用程序的至少某些部分几乎总是可行且有用的。没有人说你必须先编写一个测试套件来实现 100% 的代码覆盖率,然后再做任何其他事情。

    【讨论】:

      【解决方案2】:

      我不确定它是否没有帮助。在某些情况下,它可能会更困难,您可能会选择不使用它——例如,在您的 UI 的视觉布局的情况下。有时也可能会浪费精力——例如,对设计人员生成的代码或不是您编写的框架进行单元测试。生成数据不应该成为单元测试的障碍。您的测试应该足够小并且足够集中,以至于您通常不需要为任何单个测试生成整个数据集,因此在这些情况下模拟是一种非常有用的技术。如果我发现自己一遍又一遍地嘲笑同样的事情,我有时会将它合并成一个所有测试都可以依赖的假数据库类。

      单元测试和运行代码都不会验证其正确性。单元测试可以帮助消除错误,尤其是 TDD,并确保发现的错误得到修复。如果您需要确保您的代码是正确的,您将需要应用不同的、基于逻辑的技术来证明正确性。这些超出了单元测试的范围。

      【讨论】:

        【解决方案3】:

        我认为迈克尔总结得非常好:“不能真正正式指定的事物”。原来有很多东西不能正式指定。可用性就是一个例子(尽管一旦你决定了哪种行为是可用的,你当然可以而且应该测试那个行为!)。有点自相矛盾的是,许多数字运算任务无法正式指定:例如天气预报。目标当然是预测明天的天气,但这不是一个正式的规范。所以你可以测试你使用的算法是否做了它们应该做的事情(计算平均值、反转矩阵、可以正式指定的东西),但是你的天气预报程序可以通过所有测试,但 90% 的时间仍然是错误的.或者,您可以使用大量历史数据来测试算法是否产生良好的预测,但这很危险,因为它很容易导致算法只对您使用的历史数据准确,而不是一般情况下。这可能意味着您的单元测试需要数小时或数天才能运行。更糟糕的是,您的算法可能具有必须“调整”的参数,例如对于所使用的测量仪器,每个算法的最佳参数可能并不相同,因此单元测试需要手动交互才能找到好的参数。理论上可行,但可能不是很有用。我想同样的论点也适用于 OCR、ICR、许多信号处理任务、人脸识别(以及许多其他图像处理任务)、典型的 Photoshop 工具(如“红眼消除”)或搜索引擎排名算法(仅举几个例子) )。

        【讨论】:

          【解决方案4】:

          我不会说自动化测试在任何情况下都没有帮助。

          当然也有一些不太有用的地方。我不认为创建夹具数据是其中之一。有一些工具可以提供帮助,例如 factory_girl(至少在 Ruby 中)。实际上,如果您的模型非常复杂,以至于您需要创建十几个具有各种关联的对象,我会认为代码有异味,并且可能模型没有尽可能简洁。

          也就是说,在某些情况下,弊端可能会超过好处。前几天我写了一些代码来分叉一个外部进程。我不关心输出,我不关心返回码,我什至不关心它是否工作正常,它完全是一劳永逸的,如果有什么事情不正常,另一个进程将被清理,稍后。

          在那种情况下,我没有费心编写任何测试,因为这样做的好处不值得花时间设置一个虚假的外部程序来验证我的论点等等。

          【讨论】:

            【解决方案5】:

            只是对此的一些随机想法:

            1. 我假设 Microsoft 没有 单元测试的各种方式 关闭计算机。可能 用 Virtuals 完成,但它是 可能不值得
            2. 对于硬件制造商:确保驱动程序适用于不同的硬件 也可能是手动完成的(嗨 有nvidia,你弄坏了我的gfx卡 ;) )
            3. 运行一次的 shell 脚本。只需调整它们直到它们起作用

            但这些仍然是极端情况。我还认为它们几乎总是可行的,而且从长远来看,它们通常会给你带来比你一开始的投资更多的回报。

            【讨论】:

              【解决方案6】:
              * When generating test data is tricky: Sometimes, being able to come up with valid, non trivial test data is a challenge in itself.
              

              当您需要系统与“完整数据集”“在上下文中”时,您所做的不是单元测试。它正在测试,但是您对“单元”的压力很大。您需要为此进行 较小的 测试。 TDD 的难点在于让您的代码具有您可以在小范围内对其进行测试的形式。它很有价值,但并不容易。如果您进行后测试(不是 TDD),那么几乎不可能避免这种情况。

              因此,当您想测试比单元更大的东西(即类上的方法)时,您将需要使用 UAT 之类的东西。但在这种情况下,您仍然需要像练习 TDD 一样对单个函数进行测试。

              * When the only practical way of verifying correctness of the code is to run it.
              

              但是代码在单元测试中运行的。你的意思是当它在上下文中运行 或其他什么时候?

              * When you're testing visual elements of the design.
              

              我认为这是您的第二个要点,但我想不是。尝试在 UT 中测试布局是困难的,而且通常没有回报。这样的测试是脆弱的。

              因此在某些情况下使用 UT 进行大型子系统测试或验证屏幕布局可能没有价值。但即便如此,它对于你剩下的 90% 的工作来说还是非常有价值的。

              【讨论】:

                【解决方案7】:

                我坚信深思熟虑的测试;但是,我发现单元测试和 TDD 主要是在浪费时间。

                从经验的角度来看:

                1. 没有经验证据表明代码质量更高。
                2. 没有经验证据表明生产率更高。
                3. 没有经验证据表明可以节省成本。
                4. 有以伪科学方式呈现的“故事”表明 TDD 是有益的,但没有对照组,也没有真正的衡量标准。

                TDD 的好处:

                1. “了解”TDD 的布道者通过宣传他们的专业知识而受益。
                2. 销售/推广单元测试工具的软件组受益。
                3. 如果您的开发人员不是高素质的,那么单元测试可能会有一些好处。

                  • 单元测试只捕获最明显的错误
                  • 如果开发人员始终通过单元测试发现错误,我会替换它们。
                  • 如果我将开发外包给班加罗尔的一家车身修理厂,我会实施单元测试。否则,我将坚持与强大的开发人员合作——从长远来看,这些人更具成本效益。

                主观分析:

                1. 如果您听取 TDD 支持者提出的论点,您可以轻松地将 TDD 替换为祈祷,并且推理的有效性不会改变...
                2. 单元测试就是代码 - 您正在将代码库的大小增加一倍/三倍...也许可以更好地花时间分析您的代码。
                3. 高质量的软件来自敌对/合作的团队。编写代码的同一实体没有业务测试代码 - 这应该是 QA 分析师的工作。
                4. 高质量和具有成本效益的软件源于遵循良好的设计原则 - SOLID/GRASP/GoF
                5. 在回顾了单元测试和 TDD 之后,我会得出的真实世界类比是......这有点像对自己运行检查列表,其中包含以下项目:
                  • 吸入空气检查
                  • 呼气检查
                  • 左脚向前检查
                  • 右脚向前检查
                  • 眨眼检查
                  • 插入口香糖检查
                  • 闭口检查
                  • 张嘴检查
                  • 迭代直到下咽检查...
                  • 是的,您实际上可能会发现问题,但如果不花费大量精力编写代码,您将永远无法弄清楚任何后果。
                6. Jebus 告诉我,TDD 是个假神。

                【讨论】:

                  猜你喜欢
                  • 2021-05-08
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2018-03-24
                  • 1970-01-01
                  • 2015-01-10
                  • 1970-01-01
                  相关资源
                  最近更新 更多