10

我有大约 100 个单元测试,覆盖率为 %20,我正在尝试增加覆盖率,这也是一个正在开发的项目,所以请不断添加新的测试。

目前在每次构建后运行我的测试是不可行的,它们大约需要 2 分钟。

测试包括:

  • 从测试文件夹中读取的文件(模拟一些 HTTP 内容的数据驱动风格)
  • 向本地网络服务器发出实际的 HTTP 请求(模拟起来非常痛苦,所以我不会)
  • 并非所有这些都是单元测试,但也有相当复杂的多线程类需要测试,我确实测试了测试的整体行为。这可以被视为功能测试,但也需要每次都运行。

大多数功能需要读取 HTTP、执行 TCP 等。我无法更改它们,因为如果我更改这些测试,这就是项目的全部想法,那么测试东西将毫无意义。

此外,我认为我没有最快的工具来运行单元测试。我当前的设置使用带有 Gallio 和 nUnit 作为框架的 VS TS。我认为 VS TS + Gallio 也比其他人慢一些。

你会推荐我什么来解决这个问题?我想在 btu 的每一点变化之后运行单元测试,目前这个问题正在打断我的流程。

进一步澄清编辑:

代码高度耦合!不幸的是,改变就像一个巨大的重构过程。而且有一个鸡蛋综合症,我需要单元测试来重构这么大的代码,但是如果我不重构它,我就不能有更多的单元测试:)

高度耦合的代码不允许我将测试分成更小的块。另外我不测试私人的东西,这是个人的选择,这让我发展得更快,仍然获得了大量的好处。

而且我可以确认所有单元测试(具有适当的隔离)实际上都非常快,而且我对它们没有性能问题。


进一步澄清:

代码高度耦合!不幸的是,改变就像一个巨大的重构过程。而且有一个鸡蛋综合症,我需要单元测试来重构这么大的代码,但是如果我不重构它,我就不能有更多的单元测试:)

高度耦合的代码不允许我将测试分成更小的块。另外我不测试私人的东西,这是个人的选择,这让我发展得更快,仍然获得了大量的好处。

而且我可以确认所有单元测试(具有适当的隔离)实际上都非常快,而且我对它们没有性能问题。

4

6 回答 6

13

这些对我来说听起来不像单元测试,而更像是功能测试。很好,自动化功能测试很好,但是功能测试很慢是很常见的。他们正在测试整个系统(或其中的大部分)。

单元测试往往很快,因为它们测试的是与其他一切隔离的一件事。如果您不能将事物与其他所有事物隔离开来进行测试,那么您应该考虑一个警告信号,表明您的代码耦合过于紧密

你能告诉你哪些测试是单元测试(仅测试 1 件事)与功能测试(同时测试 2 件或更多件事)吗?哪些快,哪些慢?

于 2008-12-15T15:06:32.213 回答
8

您可以将测试分成两组,一组用于短期测试,另一组用于长期运行测试,并在每次更改后运行短期测试时降低运行长期测试的频率。除此之外,模拟来自网络服务器的响应和您的应用程序发出的其他请求会导致更短的测试运行。

于 2008-12-15T15:07:11.760 回答
8

我会推荐一种组合方法来解决您的问题:

  • 经常运行与您更改的代码接近的测试子集(例如来自相同包、模块或类似的测试)。不太频繁地运行与您当前正在处理的代码相距较远的测试。
  • 将您的套件至少分成两部分:快速运行测试和慢速运行测试。更频繁地运行快速运行的测试。
  • 考虑让一些不太可能失败的测试仅由自动化的持续集成服务器执行。
  • 学习提高测试性能的技术。最重要的是,用更快的假货代替对慢速系统资源的访问。例如,在内存流而不是文件中使用。存根/模拟 http 访问。等等
  • 了解如何使用低风险的依赖破坏技术,例如(非常强烈推荐的)“有效地使用遗留代码”一书中列出的技术。这些允许您在不应用高风险重构的情况下有效地使您的代码更具可测试性(通常通过暂时使实际设计变得更糟,例如破坏封装,直到您可以使用测试安全网重构为更好的设计)。

One of the most important things I learned from the book mentioned above: there is no magic, working with legacy code is pain, and always will be pain. All you can do is accept that fact, and do your best to slowly work your way out of the mess.

于 2008-12-15T15:51:59.347 回答
3

首先,这些不是单元测试。

在每次小的更改之后运行这样的功能测试并没有多大意义。在进行了相当大的更改后,您将需要运行功能测试。

其次,不要害怕模拟应用程序的 Http 部分。如果您真的想对应用程序进行单元测试,那是必须的。如果您不愿意这样做,您将浪费更多时间尝试测试您的实际逻辑,等待 HTTP 请求返回并尝试设置数据。

我会保留您的集成级别测试,但会努力创建真正的单元测试。这将解决您的速度问题。真正的单元测试没有 DB 交互或 HTTP 交互。

于 2008-12-15T15:39:47.327 回答
2

我总是使用“LongTest”的类别。这些测试每天晚上执行,而不是在白天执行。这样你就可以大大减少你的等待时间。试试看:分类你的单元测试。

于 2008-12-15T15:42:37.837 回答
1

听起来您可能还需要管理开发团队的期望。

我假设人们每天要进行几次构建,​​并且希望在每次构建之后运行测试。我们可能会很好地为您切换您的测试计划,以便在午餐时间运行带有测试的构建,然后在晚上运行另一个。

我同意 Brad 的观点,这些听起来像是功能测试。如果您可以将代码分开,那就太好了,但在那之前,我会切换到不那么频繁的测试。

于 2008-12-15T15:43:55.603 回答