当程序不适合功能样式时,单元测试如何工作?

时间:2009-03-04 03:09:41

标签: unit-testing

我正在考虑程序没有真正计算任何东西的情况,它只是做了很多。当你编写计算某些东西的函数并且你需要检查结果时,单元测试对我来说是有意义的,但如果你没有计算任何东西呢?例如,我在工作中维护的程序依赖于让用户填写表单,然后打开外部程序,并使外部程序自动执行基于用户输入的操作。这个过程相当复杂。有3000行代码(分布在多个函数中*),但我想不出单元测试有意义的单一事物。

这只是一个例子。您是否应该尝试对“程序”程序进行单元测试?

*编辑

10 个答案:

答案 0 :(得分:2)

我不是这方面的专家,但出于同样的原因已经困惑了一段时间。不知怎的,我正在做的应用程序不适合UNIT测试给出的示例(非常异步和随机,取决于繁重的用户交互) 我最近意识到(如果我错了请告诉我),进行一种全局测试是没有意义的,而是对每个组件进行了无数的小测试。最简单的方法是在创建实际程序的同时或甚至在构建实际程序之前构建测试。

答案 1 :(得分:2)

根据您的描述,这些是我要进行单元测试的地方:

  • 用户输入的表单验证工作是否正常工作
  • 如果表单中的有效输入是正确调用的外部程序
  • 将用户输入输入外部程序,看看是否输出正确

根据您的描述的声音,真正的问题是您使用的代码不是模块化的。我在单元测试中发现的一个好处是,难以测试的代码要么不够模块化,要么具有笨拙的界面。尝试将代码分解成更小的部分,您将找到编写单元测试的地方。

答案 2 :(得分:1)

您是否在一个程序/方法中有3000行代码?如果是这样,那么您可能需要将代码重构为更小,更易理解的部分以使其可维护。当你这样做时,你将拥有那些可以并且应该进行单元测试的部件。如果没有,那么你已经拥有了这些部分 - 主程序调用的各个程序/方法。

即使没有单元测试,您仍应编写代码测试,以确保为外部程序提供正确的输入,并测试在正常和异常条件下正确处理程序输出。单元测试中使用的技术 - 如模拟 - 可以在这些集成测试中使用,以确保您的程序正常运行而不涉及外部资源。

答案 3 :(得分:1)

您的应用程序的一个有趣的“切入点”是您说“用户填写表单”。如果要进行测试,则应重构代码以构造该表单作为数据结构的显式表示。然后,您可以开始收集表单并测试系统是否对每个表单做出适当的响应。

可能是您的系统所采取的操作在文件系统出现问题之前无法观察到。以下是一些想法:

  • 为文件系统的初始状态设置类似git存储库的东西,运行表单,然后查看git diff的输出。这可能会比单元测试更像回归测试。

  • 创建一个新模块,其唯一目的是使程序的操作可观察。这可以像将相关文本写入日志文件一样简单,也可以像您希望的那样复杂。如有必要,您可以使用条件编译或链接以确保此模块仅在系统处于测试状态时执行某些操作。这更接近传统的单元测试,因为您现在可以在接收到表单A时编写说明的测试,系统应该采取行动序列B 。显然,你必须决定应采取什么行动才能形成合理的测试。

我怀疑你会发现自己会转向看起来更像回归测试的东西,而不是单元测试本身。这不一定是坏事。不要忽视代码覆盖率!

(最后的括号内容:在交互式控制台应用程序的旧时代,Don Libes创建了一个名为Expect的工具,它非常有助于您编写与用户交互的程序脚本。意见我们迫切需要类似的东西与网页互动。我想我会发一个问题: - )

答案 4 :(得分:0)

你至少应该重构看起来可能有问题的东西并进行单元测试。但作为一项规则,功能不应该那么长。一旦开始重构,你可能会发现一些值得单元测试的东西

Good object mentor article on TDD

答案 5 :(得分:0)

您不一定要实现测试单个方法或组件的自动化测试。您可以实现一个自动化单元测试,模拟用户与您的应用程序交互,并测试您的应用程序是否以正确的方式响应。

我假设您目前正在手动测试您的应用程序,如果是这样,那么请考虑如何自动执行该应用程序并从那里开始工作。随着时间的推移,您应该能够将测试分解为逐渐变小的块,以测试较小的代码段。任何类型的自动化测试通常都比没有好。

答案 6 :(得分:0)

大多数程序(无论语言范例如何)都可以分解为原子单元,它们接受输入并提供输出。正如其他响应者所提到的那样,考虑重构程序并将其分解为更小的部分。在测试时,请少关注端到端功能,而应更多地关注处理数据的各个步骤。

此外,单元不一定需要是单独的功能(尽管通常是这种情况)。单元是功能的一部分,可以使用输入和测量输出进行测试。我在使用JUnit测试Java API时已经看到了这一点。单个方法可能不一定提供我需要的测试粒度,尽管会有一系列方法调用。因此,我认为“单位”的功能比单一方法略大。

答案 7 :(得分:0)

有些人之前已经回答过,有几种方法可以测试你所概述的内容。 首先是表单输入,可以通过几种方式进行测试。 如果输入无效数据,有效数据等会发生什么。 然后,可以测试每个功能,以查看当提供各种形式的正确和不正确数据时的功能是否以适当的方式作出反应。 接下来,您可以模拟正在调用的应用程序,以便确保应用程序正确地将数据发送和处理到外部程序。不要确保您的程序也处理来自外部程序的意外数据。

通常,我弄清楚如何为我已经分配维护的程序编写测试的方法是看看我手动测试程序的方法。然后尝试计算如何尽可能多地自动化。另外,不要将测试工具仅限于编写代码的编程语言。

答案 8 :(得分:0)

我认为一波测试偏执狂正在蔓延:)很好地检查事情,看看测试是否有意义,有时答案是否定的。

我要测试的唯一一件事就是确保正确处理伪形式输入。我真的没有看到自动化测试有何帮助。我认为您希望测试是非侵入性的(即测试期间实际上没有记录保存),因此可能排除其他几种可能性。

答案 9 :(得分:0)

如果你无法测试某些东西,你怎么知道它有效?软件设计的关键是代码应该是可测试的。这可能会使软件的实际编写变得更加困难,但是以后更容易维护会带来回报。