20

我们的团队有数百个集成测试,这些测试可以访问数据库并验证结果。我有两个用于所有集成测试的基类,一个用于仅检索测试,一个用于创建/更新/删除测试。仅检索基类在 TestFixtureSetup 期间重新生成数据库,因此每个测试类只执行一次。CUD 基类在每次测试之前重新生成数据库。每个存储库类都有自己对应的测试类。

正如你可以想象的那样,这整个过程需要相当长的时间(大约 7-8 分钟才能运行并快速增长)。将此作为我们的 CI (CruiseControl.Net) 的一部分运行不是问题,但在本地运行需要很长时间,并且确实禁止在提交代码之前运行它们。

我的问题是是否有任何最佳实践来帮助加快执行这些类型的集成测试?

我无法在内存中执行它们(la sqlite),因为我们使用了一些在 sqlite 中不受支持的特定于数据库的功能(计算列等)。

此外,整个团队必须能够执行它们,因此在 SQL Server Express 的本地实例上运行它们可能容易出错,除非这些实例的连接字符串都相同。

你是如何在你的商店里做到这一点的,什么效果很好?

谢谢!

4

5 回答 5

16

将您的快速(单元)测试和慢速(集成)测试分开,以便您可以单独运行它们。使用测试框架提供的任何方法对测试进行分组/分类。如果测试框架不支持对测试进行分组,请将集成测试移动到仅包含集成测试的单独模块中。

快速测试应该只需要几秒钟就可以运行所有它们,并且应该具有很高的代码覆盖率。这类测试允许开发人员进行无情的重构,因为他们可以做一个小的改动并运行所有的测试,并且非常有信心这个改动没有破坏任何东西。

缓慢的测试可能需要几分钟才能运行,它们将确保各个组件正确地协同工作。当开发人员所做的更改可能会破坏由集成测试而不是单元测试测试的某些内容时,他们应该在提交之前运行这些集成测试。否则,慢速测试由 CI 服务器运行。

于 2009-08-25T17:48:41.537 回答
11

in NUnit you can decorate your test classes (or methods) with an attribute eg:

[Category("Integration")]
public class SomeTestFixture{
    ...
}
[Category("Unit")]
public class SomeOtherTestFixture{
    ...
}

You can then stipulate in the build process on the server that all categories get run and just require that your developers run a subset of the available test categories. What categories they are required to run would depend on things you will understand better than I will. But the gist is that they are able to test at the unit level and the server handles the integration tests.

于 2009-08-25T14:49:55.367 回答
5

I'm a java developer but have dealt with a similar problem. I found that running a local database instance works well because of the speed (no data to send over the network) and because this way you don't have contention on your integration test database.

The general approach we use to solving this problem is to set up the build scripts to read the database connection strings from a configuration file, and then set up one file per environment. For example, one file for WORKSTATION, another for CI. Then you set up the build scripts to read the config file based on the specified environment. So builds running on a developer workstation run using the WORKSTATION configuration, and builds running in the CI environment use the CI settings.

It also helps tremendously if the entire database schema can be created from a single script, so each developer can quickly set up a local database for testing. You can even extend this concept to the next level and add the database setup script to the build process, so the entire database setup can be scripted to keep up with changes in the database schema.

于 2009-08-25T14:46:30.210 回答
3

您是否进行了任何测量(使用计时器或类似方法)来确定测试将大部分时间花在哪里?

如果您已经知道数据库重新创建是他们耗时的原因,那么另一种方法是重新生成数据库一次并使用事务来保留测试之间的状态。每个 CUD 类型的测试在 setup 中启动一个事务,并在 teardown 中执行回滚。这可以显着减少每次测试花费在数据库设置上的时间,因为事务回滚比完整的数据库重建更便宜。

于 2009-08-25T14:56:33.157 回答
3

作为开发环境的一部分,我们有一个 SQL Server Express 实例,它为每台开发机器运行相同的数据库定义。使用 Windows 身份验证,连接字符串是稳定的 - 字符串中没有用户名/密码。

我们真正想做但还没有做的是看看我们是否可以让我们的系统在SQL Server Compact Edition上运行,这就像带有 SQL Server 引擎的 SQLite。然后我们可以在内存中运行它们,也可以并行运行(使用多个进程)。

于 2009-08-25T15:05:35.497 回答