2010-08-18 69 views
2

大家都喜欢单元测试。但是测试实体的持久性有点不同。您正在使用不同的语言测试跨多个图层的过程。你的测试有副作用(在行被添加/修改等的意义上)。测试实体持久性的方法和建议

我想知道你是如何做到这一点的。例如,您的测试是否会创建一个全新的数据库模式并每次都放弃它?您是否必须维护用于测试模式创建的SQL脚本,并让它们与生产数据库保持同步?你甚至可以测试你在生产中使用的相同数据库产品吗?你是随机产生你的实体的状态,还是总是使用相同的值?你如何配置你的测试,以确保它们是针对测试数据库而不是生产测试数据库执行的?

在这方面可能有一堆我没有想到的重要问题。为了争分夺秒,我会将答案标记为似乎副作用最小并且最容易实现的答案。

+0

哇,我真的希望有更多的意见,而不仅仅是两个。也许不是一场完整的火焰战争,但也许是一些教育方面的分歧。 – David 2010-08-18 15:50:31

回答

1

单元测试数据持久性几乎是不可能的,所以我通常在集成层面上做。

关于数据库,在我当前的项目中,集成测试套装确实会删除整个模式,并从头开始重新创建所有内容(当测试从构建服务器运行时使用)。但是,您也可以针对已经创建的数据库运行测试 - 如果您正在从机器进行测试/调试,并且不想浪费时间或松散测试数据,则这是有意义的。你应该维护你的数据库脚本(它们应该和生产脚本一样) - 这样你就可以测试你的脚本以及你的.Net代码。一般来说,脚本不会创建任何数据(可能除了静态数据) - 它应该成为测试的一部分,以创建测试数据,对其执行一些操作并验证期望值 - 确保您可以针对每个数据库运行测试正确的模式。在创建测试数据时,我们通常会使用随机标识符和唯一字段并硬编码其他所有内容

关于环境管理,您应该已经有一些机制来配置数据库连接(以便您可以拥有测试和生产环境) - 有很多方法可以实现它,包括Microsoft产品和内部解决方案 - 所以你应该使用相同的方式来配置你的构建机器。

+0

我想这几乎是我想象的。一个相当的工作实施,加上可能会烦人保持我猜。但不痛不收! – David 2010-08-18 11:00:45

0

我的方法是创建一套用于测试数据访问层(存储库和映射)的集成测试。我认为这是非常重要的,如果你使用ORM工具,它使用“约定配置”方法 - 比如EF中的POCO映射。我有数据库初始化脚本,它创建新的数据库(与当前的开发数据库相同)并创建初始测试数据集。该脚本在测试运行开始时只运行一次。数据库在测试运行结束时被删除。每个集成测试使用在测试结束时回滚的事务,因此所有测试的测试数据都是相同的。验证数据库中的数据我使用标准SqlCommand方法使用助手类。要使用SqlCommand,您必须为您的测试使用ReadUncommited事务隔离级别,因为您通常不会在SqlCommand和EF上下文之间共享连接。

+0

谢谢 - 有趣。我有点不确定你为什么回滚事务。正如你所说,你必须使用ReadUncommitted隔离级别。为什么不使用SqlCommand辅助类来运行一些SQL来删除相关表中的行呢? – David 2010-08-18 10:59:49

+0

因为在这种情况下,您必须为每个与回滚具有相同结果的测试创建清理代码。 – 2010-08-18 13:00:00

1

在过去的六年里,我主要使用NHibernate进行持久化。

在单元测试级别上,我使用内存中的SQLite测试持久性/实体映射,并在集成测试级别上使用真实数据库服务器(本地和构建服务器)。

在这两种情况下,我设置数据库与NHibernate的/功能NHibernate可以为你每个测试(并在整合之后的情况下杀DB)的脚本。这需要更长的时间才能运行,但恕我直言,清理代码变坏的风险更糟(顺便说一下,在xUnit测试模式书中有关于此的讨论)。

+0

但是这只有在你使用模型第一种方法时才有效,不是吗? – 2010-08-19 08:55:43

+0

是的。我自己是DDD /“Model + POCO第一人”。 – 2010-08-19 08:57:38