3

TestInitialize在 Visual Studio 中运行单元(或在这种情况下为集成)测试时,是否可以将数据库项目(在同一解决方案中)作为方法的一部分发布?

这个想法是每个实际命中数据库的集成测试都应该命中一个已知良好且干净的数据库,而做到这一点的最佳方法是在每次测试时完全刷新数据库。我一直在网上寻找很多关于数据库和测试的相关信息,但没有关于在运行自动化测试时刷新数据库的信息。我也没有在 Visual Studio 界面中找到任何东西,或者至少我错过了它。

我正在使用 Visual Studio Ultimate 2012 RC。

4

3 回答 3

3

在一位同事提供的有用链接之后,我最终使用Process.Start来运行sqlpackage.exe部署。从 Visual Studio 的角度来看,它不像我希望的那样干净,但它完成了工作。我的引导现在看起来像这样:

private const string SQL_PUBLISH_COMMAND = @"C:\Program Files (x86)\Microsoft SQL Server\110\DAC\bin\sqlpackage.exe";
private const string SQL_PUBLISH_COMMAND_ARGUMENTS = @"/Action:Publish /SourceFile:C:\Data\Code\NewEdCo\Domain\NewEdCo.Database.SQLExpress\bin\Debug\NewEdCo.Database.SQLExpress.dacpac /Properties:CreateNewDatabase=True /TargetServerName:hactar\sqlexpress2012 /TargetDatabaseName:NewEdCoTest";


private void DeployTestDatabase()
{
    var procInfo = new ProcessStartInfo
    {
        Arguments = SQL_PUBLISH_COMMAND_ARGUMENTS,
        CreateNoWindow = true,
        ErrorDialog = false,
        FileName = SQL_PUBLISH_COMMAND,
        RedirectStandardOutput = true,
        UseShellExecute = false
    };
    var proc = new Process
    {
        StartInfo = procInfo
    };

    proc.Start();
    var result = proc.StandardOutput.ReadToEnd();
}

[TestInitialize]
public void BootstrapTests()
{
    DeployTestDatabase();
}

[TestCleanup]
public void TearDownTests()
{
    DeployTestDatabase();
}

用于ProcessStartInfo标准输出和读取的选项(即使我还没有对它做任何事情)是为了保持任务同步。这样测试就不会互相影响。这增加了集成测试的执行时间,但这对我的需求来说很好。

我意识到我在前后都进行了彻底的刷新。如果随着我的测试数量增加而这需要太长时间,我会重新考虑。但是现在我想确保它在测试前被刷新,并且在测试后不留下任何痕迹。

MSDN 提供了广泛sqlpackage.exe.

于 2012-06-07T14:02:34.257 回答
0

面对同样的问题,我发现DACSmash NuGet 包很容易从项目站点上的示例开始工作。

于 2015-03-03T23:26:35.090 回答
0

这个想法是每个实际命中数据库的集成测试都应该命中一个已知良好且干净的数据库,而做到这一点的最佳方法是在每次测试时完全刷新数据库。

我最近遇到了类似的问题,并决定最初遵循相同的数据库娱乐路线,但是当有很多测试运行时,测试运行速度太慢了。

因此,我还尝试了其他一些方法,以使测试更快,同时仍然具有弹性:

  • 针对它们引入的突变将测试拆分为读取和写入,以避免前者的数据库恢复;
  • 使用瞬态事务,在测试运行后恢复;
  • 使用数据库快照而不是完整数据库备份恢复/重新创建;
  • 使用允许并行化测试的数据库池;
  • 使用 dotnet-testcontainers 在 docker 中运行 sql server;

最终得到了一个使用简单的插入/删除脚本的Reseed库,但效率很高。希望对遇到同样问题的人有所帮助。

Respawn也是数据库清理需要考虑的东西。

于 2021-11-09T19:03:05.823 回答