在数据库上运行测试的策略

Gil*_*les 7 .net sql-server testing mstest

我已经开始研究一个包含1800多个功能/集成测试的现有项目.这些都是用MSTest编码的.

其中许多直接连接到SQL Server数据库.数据库由代码生成器生成,代码生成器在许多方面创建数据库.生成数据库很慢而且很麻烦.

这有以下问题:

  • 测试清理db,这意味着我们必须为测试维护一个单独的db,而另一个使用该应用程序.现在的过程是在运行测试和运行应用程序之间进行更改时更改数据库.
  • 每个分支都需要拥有自己的数据库,因为每个数据库中的数据库模型可能不同(这意味着每个分支有2个数据库,步骤1)
  • 这很慢
  • 必须安装SQL Server和db才能运行测试

我希望现有的测试不依赖于这样的安装,如果可能的话运行得更快,而不必通过代码生成器,杂耍连接字符串等来处理维护数据库.

我试图尽快实现这一点,因为重写测试不在预算范围内.我已经引入了模拟来帮助新测试减少对数据库的依赖,我现在的问题是现有的测试.

我的第一个是改变我们的基本单元测试类连接到一个SQLite数据库,它将由代码生成器创建,该代码生成器已经生成了主数据库而不是SQL Server数据库.然后可以删除SQLite并将其重新复制到每次运行之间的测试文件夹中.这本来很快,不需要2个SQL Server数据库,事实上如果只是运行测试,则不需要SQL Server安装.

我的问题是生成的代码使用了SQLite中没有包含的许多概念; T-SQL,SQL Server特定语法,模式,存储过程和嵌入式clr程序集.

然后我尝试了SQL Server CE 4,它有许多与SQLite相同的限制.

除了重写代码以与SQLite(或CE)兼容,重写现有测试或我们维护2 seperatedb的系统之外,还有其他可用的替代方案吗?

编辑:将单元测试更改为功能测试,澄清了一些事情.把一些东西放大胆.我同意这些测试不是适当的单元测试.我同意嘲笑在这里会很好.我想要做的是尝试解决我面临的混乱局面.

A.J*_*own 7

如果要连接到数据库或任何其他资源,则不是单元测试.适当的单元测试被隔离到被测单元或您的班级.在被测单元之外的任何东西都应该被嘲笑.

我不是.NET开发人员所以我不能推荐最好的Mocking框架/工具,但也许这个问题会指出你正确的方向.

为什么单元测试不应该访问资源:

你会想要以不同的方式看待这个问题.您没有任何测试数据库本身的愿望,因为您必须假设您正在使用的数据库产品正常工作.因此,没有必要测试"$ dao-> save()"实际插入记录.您可能感兴趣的是在完成某些其他操作时是否正在调用save()方法,或者您的DAO是否正在生成正确的INSERT语句.

如果您必须在单元测试中进行数据库调用,因为您无法模拟进行数据库调用的对象,则需要重构.

肥皂盒时间:

这就是测试驱动开发如此有益的原因.从一开始就强调要保持脱钩和隔离,从而带来更好的整体设计,灵活性和可测试性.


Fil*_*Vos 7

您可以在每次测试之前创建数据库快照,然后还原数据库.创建和恢复快照比完全备份/恢复或重建数据库更轻松

 CREATE DATABASE myDb_snapshot ON
    ( NAME = myDb_snapshot, FILENAME = 'C:\MSSQL\Data\myDb_snapshot.ss' )
 AS SNAPSHOT OF myDb;
Run Code Online (Sandbox Code Playgroud)

在测试执行后恢复:

 RESTORE DATABASE myDb FROM DATABASE_SNAPSHOT = myDb_snapshot
Run Code Online (Sandbox Code Playgroud)

因此,在每次测试之后,您都可以恢复快照,让您的数据库为下一次测试做好准备.

另外需要注意的是:在Mocked数据层上运行单元测试不能代替在"真实数据库"上运行测试.从数据库外部看不到许多"连锁"效应.(触发器/默认值/权限/资源可用性).要获得更快的测试用例并生成更多可插拔代码,请模拟您的数据层.但最终您必须在"真实"数据库上运行测试用例.


art*_*tol 0

生成数据库不应该这么慢和麻烦。您可以更改配置以针对本地主机数据库运行吗?在每个开发人员的计算机上安装 SQL Server 并不是很麻烦,而且测试会更快,因为您将减少网络延迟。