2009-08-25 113 views
16

我们的团队进行了数百次集成测试,它们击中数据库并验证结果。我为所有集成测试提供了两个基类,一个用于仅检索测试,另一个用于创建/更新/删除测试。只能检索的基类在TestFixtureSetup期间重新生成数据库,因此它仅对每个测试类执行一次。 CUD基类在每次测试之前重新生成数据库。每个存储库类都有自己相应的测试类。如你所想,这整件事情需要相当长的一段时间(接近7-8分钟才能运行并快速增长)。将它作为CI(CruiseControl.Net)的一部分运行并不成问题,但在本地运行需要很长时间,并且在提交代码之前确实禁止运行它们。集成测试最佳实践

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

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

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

你是如何在你的店里完成这件事的?

谢谢!

回答

5

我是一名java开发人员,但遇到了类似的问题。我发现运行本地数据库实例的效果很好,因为速度很快(无需通过网络发送数据),并且因为这样您就不会在集成测试数据库上发生争用。

我们用来解决这个问题的一般方法是设置构建脚本从配置文件读取数据库连接字符串,然后在每个环境中设置一个文件。例如,一个用于WORKSTATION的文件,另一个用于CI。然后,您将设置构建脚本以根据指定的环境读取配置文件。因此使用WORKSTATION配置运行在开发人员工作站上运行,并使用CI设置在CI环境中构建运行。

如果可以从单个脚本创建整个数据库模式,那么每个开发人员都可以快速设置本地数据库进行测试,这也非常有帮助。您甚至可以将此概念扩展到下一个级别,并将数据库设置脚本添加到构建过程中,以便可以编写整个数据库设置以跟上数据库模式的变化。

11

在NUnit的,你可以用一个属性如装饰你的测试类(或方法):

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

然后,您可以在服务器上构建过程规定所有类别的车子撞到,只是需要你的开发人员运行可用测试类别的子集。他们需要运行哪些类别取决于你会比我更好地理解的东西。但要点是,他们能够在单元级别进行测试,并且服务器负责处理集成测试。

+1

+1这几乎是我们在工作中所做的。在我们的CIS中,单元测试每天进行一次签入和集成测试。 – mezoid 2009-08-25 14:53:17

+2

我在哪里工作,我们在每个构建上运行集成测试。您运行集成测试的频率越高越好。 – 2009-08-25 14:58:34

+1

@ Ken_Liu - 当然。通常情况下,将CI服务器上的可用cpu周期与每时每刻的提交数量进行平衡。这对每个开发团队/环境都会有所不同。 – grenade 2009-08-25 15:01:39

3

你有没有做过任何测量(使用计时器或类似的)来确定测试大部分时间花在哪里?

如果您已经知道数据库重新创建是耗费时间的原因,则不同的方法是重新生成一次数据库并使用事务来保存测试之间的状态。每个CUD类型测试都会在安装程序中启动事务并在拆卸后执行回滚。这可以显着减少每次测试花费在数据库设置上的时间,因为事务回滚比完整的数据库娱乐更便宜。

+0

是的,我以前见过这个想法,但如果你测试的某些代码使用事务本身(记住,这些是集成测试)呢?然后一切都会中断,所以我不认为这是一般的实际情况。 – sleske 2009-08-27 10:18:55

+1

如果你在你的方法内部进行明确的事务管理,你是绝对正确的。在使用方面或代理来处理事务的情况下,此方法效果最佳。我们在基于Spring的项目中使用了这种方法,集成测试设置用单元测试管理的事务替换了代理。像魅力一样工作。 – henrik 2009-08-27 11:22:15

3

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

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

+0

mmm SQL Compact。那*会很甜蜜! – grenade 2009-08-25 15:07:29

+0

我喜欢这个想法,当然! – 2009-08-25 15:13:03

13

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

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

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