我目前正在使用模拟库对我的代码进行单元测试。我现在正处于我想测试一切都与数据库很好地配合并按预期工作的地步。
复制大量单元测试并调整它们以使用测试数据库是否有意义?
我目前正在使用模拟库对我的代码进行单元测试。我现在正处于我想测试一切都与数据库很好地配合并按预期工作的地步。
复制大量单元测试并调整它们以使用测试数据库是否有意义?
不要复制你的测试。
我之前已经这样做了,以针对不同版本的 MySQL 和 SQL Server 进行测试。我遇到的一个问题是当 MySQL 服务器实例在 Windows 或 UNIX 上运行时,MySQL 在命名表等时如何处理“大小写”。因此,针对不同数据库引擎运行集成测试的能力被证明是相当有价值的。
我推荐以下模式。它使用 MSTest 完成,但是您可以将其调整到其他人。它假定 IMyRepository 是一个包装数据库逻辑的接口。
[TestClass]
public abstract class MyTestBase
{
protected abstract IMyRepository CreateRepository();
[TestMethod]
public void MyTest1()
{
// use IMyRepository
// execute tests
}
}
[TestClass]
public sealed class MyUnitTest : MyTestBase
{
protected abstract IMyRepository CreateRepository()
{
IMyRepository mockedRepository = /* create a mock */;
}
// additional unit tests that are not dependent upon database
}
[TestClass]
public sealed class MyIntegrationTest : MyTestBase
{
[TestSetup]
public void TestSetup()
{
// configure the database to be pristine
}
[TestCleanup]
public void TestCleanup()
{
// dispose of database connections etc.
}
protected abstract IMyRepository CreateRepository()
{
IMyRepository mockedRepository = /* create real repository */;
}
}
另一种方法是只为 IMyRepository 编写集成测试,而 IMyRepository 又使用不同的数据库引擎。在您的业务逻辑测试中,您只需模拟 IMyRepository。如果您的业务逻辑模拟数据库问题并且 IMyRepository 适当地封装了数据库问题,那么两次测试业务逻辑实际上并没有任何价值。
取决于测试,我们需要更多关于他们在做什么的细节。
但是,如果您只是复制测试,您现在必须维护两个副本。也许您可以在两种模式下运行相同的测试。一种模式使用模拟基础设施,另一种使用真实(测试)基础设施。您如何完成此操作取决于您如何完成模拟以及您的配置系统如何工作。
在做任何事情之前,先想想你的目标是什么。集成测试很容易过火,最终导致大量测试需要很长时间才能运行,但实际上并没有提供任何价值。
话虽如此,将最高级别的单元测试作为集成测试的模板(最高含义离数据库最远)可能会有一些好处。这些测试对该服务的功能有期望,因此插入真正的依赖项、服务和数据库可以让您对该部分进行很好的测试。这不是一个完整的测试,但它确实可以确保一切都按预期工作。