通过使用单元测试超时来衡量方法的性能是一个好主意吗?


14

在有非功能性需求的项目中,该非功能性需求指定了特定操作的最长时间执行时间,QA必须在精确负载下使用精密硬件检查专用设备上此动作的性能,硬件和负载均在需求中指定。

另一方面,对源代码的一些错误更改可能会严重影响性能。在源代码到达源代码控制并由QA部门验证之前尽早注意到这种负面影响可能会因为QA部门报告问题而浪费时间,而开发人员稍后再修复它会造成损失。

为此,这是一个好主意:

  • 要使用单元测试有花了执行相同action²时间的想法ñ倍,

  • 要在C#中通过属性使用每次测试超时[TestMethod, Timeout(200)]

我期望这种方法会出现几个问题:

  • 从概念上讲,单元测试并非真正做到这一点:它们应仅测试代码的一小部分,仅此而已:既不检查功能需求,也不进行集成测试,也不进行性能测试。

  • 考虑到这些测试不存在初始化和清除功能,或者它们太短而无法影响结果,Visual Studio中的单元测试超时是否真的可以衡量预期的结果?

  • 用这种方法衡量性能很难看。在独立于硬件,负载等因素的任何计算机上运行基准测试,就像进行基准测试一样,表明一种数据库产品总是比另一种数据库产品更快。另一方面,我不希望这些单元测试是确定的结果,也不希望质量检查部门使用这些东西。这些单元测试将仅用于提供有关预期性能的一般概念,并且实质上是在提醒开发人员,他的最后修改破坏了某些内容,从而严重影响了性能

  • 对于这些测试,无法进行测试驱动开发(TDD)。首先,在开始实施代码之前它将如何失败?

  • 性能测试太多将影响运行测试所需的时间,因此此方法仅限于短期操作。

考虑到这些问题,如果将此类单元测试与质量保证部门的实际性能指标结合使用,我仍然觉得很有趣。

我错了吗?还有其他问题使其完全不能使用单元测试吗?

如果我错了,那么在源代码到达源代码控制并由质量检查部门验证之前,警告开发人员该源代码的更改严重影响性能的正确方法是什么?


¹实际上,单元测试只能在具有相当硬件性能的开发人员PC上运行,从而缩小了永远无法通过性能测试的最快计算机与永远无法通过性能测试的最慢计算机之间的差距。

²实际上,我的意思是一段相当短的代码,需要花费几毫秒来运行。

Answers:


3

我们也正在使用这种方法,即,我们进行了一些测试,这些测试可以测量给定计算机上某些定义的负载情况下的运行时间。需要指出的是,我们不将这些包括在正常的单元测试中。单元测试基本上是由每个开发人员在提交更改之前在开发人员计算机上执行的。请参阅下文,了解为什么这对性能测试没有任何意义(至少在我们的案例中如此)。相反,我们将性能测试作为集成测试的一部分运行。

您正确地指出,这不应排除验证。我们不认为我们的测试是对非功能性要求的测试。相反,我们认为它仅仅是潜在问题的指标。

我不确定您的产品,但就我们而言,如果性能不足,则意味着需要大量工作来“修复”该产品。因此,当我们将所有工作完全交给质量检查人员时,周转时间真是太恐怖了。此外,性能修复将对很大一部分代码库产生严重影响,从而使以前的质量检查工作无效。总而言之,这是一个非常低效且令人不满意的工作流程。

话虽如此,以下是有关您各自问题的一些要点:

  • 从概念上讲:确实,这与单元测试无关。但是,只要大家都知道,该测试不应验证QA应该做的任何事情,就可以了。

  • Visual Studio:不能说什么,因为我们不使用VS的单元测试框架。

  • 机器:取决于产品。如果您的产品是为具有自定义个人台式机的最终用户开发的,那么实际上,在不同开发人员的计算机上执行测试将更为现实。在我们的案例中,我们为具有给定规格的机器交付产品,并且仅在此类机器上执行这些性能测试。的确,当客户端最终将运行16个或更多内核时,在双核开发人员机器上评估性能没有太大意义。

  • TDD:虽然最初的失败很典型,但这不是必须的。实际上,尽早编写这些测试可以使其更多地用作回归测试,而不是传统的单元测试。测试早日成功是没有问题的。但是,您确实获得了好处,那就是每当开发人员添加了使速度变慢的功能时,由于他/她不了解非功能性的性能要求,此TDD测试就会发现它。发生了很多,这是很棒的反馈。想象一下,在日常工作中:编写代码,提交代码,吃午饭,而当您返回时,构建系统会告诉您在重负载环境中执行该代码的速度太慢。这足以让我接受,TDD测试最初并未失败。

  • 运行时:如上所述,我们不是在开发人员机器上运行这些测试,而是作为某种集成测试中的构建系统的一部分。


3

我基本上符合您的想法。只是用独立的流程提出我的推理。

1.在使其变得更好/更快
之前使它工作,在代码提供任何性能度量(更不用说保证)之前,应首先使其正确即使其功能正常。优化功能上错误的代码不仅浪费时间,而且在开发中也存在障碍。

2.系统的性能仅在完整系统上才有意义
通常,任何有意义的性能始终取决于给定的基础结构,并且只能在整个系统下才能看到。例如,在模拟测试期间,如果模块从本地文本文件接收到答案,但是在生产环境中,它是从数据库中获取的,因此

3.应该按目标进行性能扩展。
一旦拥有了功能系统,就需要分析系统的性能并找到瓶颈,以了解需要在哪里扩展性能。甚至在您不知道整个系统的性能之前就盲目地尝试优化每种方法可能会导致无用的工作量(优化无关紧要的方法),并可能不必要地使您的代码变得肿。

我还不了解Visual Studio的功能,但是通常您需要更广泛的分析工具。


2

我前段时间做过类似的任务,最终的解决方案介于单元测试和成熟的自动化性能测试之间。

没有特别顺序的一些注意事项,可能会有用:

  • QA进行的性能测试是劳动密集型的,并且具有自己的计划(例如,一次迭代),因此实现源代码控制不是问题。
  • 我们的系统庞大且模块化,单元测试过于精细,无法满足我们的需求,并且我们精心创建了特殊的“胖”单元测试,以触发特定关注领域的性能问题(它们也已分类,但这是实施细节)。
  • 单元测试的通常约束仍然适用:它们应该小巧,快速并且切合实际。
  • 为了排除测试框架的影响,它们由特殊的包装程序运行,因此我们确切知道给定操作花费了多少时间。
  • 可以在实际实现完成之前编写它们(结果可能无关紧要或有用,取决于过程,也许开发人员仍在试验实现并希望了解实现的整体情况)。
  • 他们每次都由CI服务器运行构建,因此总运行时间应保持相对较短(如果不是这样,则查明确切的更改会触发问题变得相当困难)。
  • CI服务器功能强大且硬件已固定,因此我们将其视为专用计算机(可以通过使用远程构建代理来使用真正专用的服务器)。
  • 测试包装器收集了所有相关信息(硬件规格,测试名称/类别,系统负载,经过的时间等),并将其作为报告或数据库导出。
  • 我们为JIRA提供了一个小工具,可以通过使用某些控件(将以前的版本覆盖到当前版本等)按名称/类别/内部版本号提取这些报告并绘制精美的图表,以便开发人员可以快速查看其影响,并且经理可以获取概述(有些红色,全绿色,这对他们很重要)。
  • 通过使用收集到的统计数据,可以分析项目的进展情况。

因此,最后,我们有了可扩展,灵活且可预测的系统,可以根据自己的特殊需求快速进行调整。但这需要付出一些努力才能实现。

回到问题。从概念上讲,单元测试并不适合于此,但是您可以利用测试框架的功能。我从来没有将测试超时视为衡量的手段,它只是挂起之类的安全网。但是,如果您当前的方法对您有用,那么请继续使用它,这是可行的。如果需要的话,您以后总是可以花哨的。


0

我觉得你很好。这正是单元测试超时的关键所在:检查是否正在发生某些事情比应该发生的事情长得多。这种方法有局限性,但是您似乎已经意识到了它们,因此,只要牢记这些局限性,我就不会发现问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.