【问题标题】:How to unit test the database code for Sql Server 2014如何对 Sql Server 2014 的数据库代码进行单元测试
【发布时间】:2017-04-07 05:11:23
【问题描述】:

我正在为 Sql Server 2014 中的 db 代码开发单元测试框架。我的要求如下:

  • 该工具应提供足够的断言来检查数据库架构、正值、负值、异常和约束。
  • 该工具应为 db 存储过程提供模拟和存根
  • 该工具应该能够为通过/失败的测试用例生成 .TRX 报告,因为我想使用 VSTS/TFS 构建发布这些报告
  • 尽可能的代码覆盖率
  • 该工具应该能够与 TFS 构建模板集成以用于 CI 目的。

在做了一些研究之后,我认为借助工具 SSDT 与 MSTest 和 tSqlT 的帮助我有三个选择:

  • 使用 SSDT 进行测试数据库初始化/清理和使用 MsTest 进行 Sql 单元测试,但它没有模拟功能,并且断言选项也受到限制。清理也是手动的
  • 将 tSqlT 用于单元测试用例。它是一个不错且功能强大的工具,但它不提供像 SSDT 这样的 GUI。 redGate GUI 是付费的,这在我的情况下是不可能的。此外,将它与 TFS 构建集成似乎更难。这不会生成 .TRX 格式的报告,而是生成 .XML 格式的报告。
  • 使用 SSDT 和 tSqlT 的组合作为 SSDT 进行数据库初始化、TFS 集成和运行 MSTest 项目中的 tSqlT 代码和 tSqlT 进行数据库单元测试。

任何人都可以提出更好的数据库单元测试方法吗?

谢谢

【问题讨论】:

    标签: unit-testing tfs mstest sql-server-data-tools tsqlt


    【解决方案1】:

    Steph locke 已经为你准备好了:

    https://itsalocke.com/unit-testing-in-ssdt-a-quick-intro/

    亮点:

    好吗?

    编辑

    【讨论】:

    • 虽然我需要查看您提出的解决方案,但乍一看它看起来不错,所以从我这边 +1。在验证可用性后,我会将其标记为答案。 :)
    • 您也可以将 tsqlt 模拟与 VSTest 运行器一起使用,但与 tsqlt 的断言相比,断言相当弱。您当然可以创建自定义断言,但这是额外的工作。这可能也可以与 SQLCover 一起使用,但这不是我测试过的场景。还有一些方法(xslt...)可以将 NUnit 输出转换为 trx 文件。
    • 让几个测试用例的安装部分通用是个好主意吗? IE;把它写在一个存储过程中,然后在测试用例的Setup部分的不同测试用例中调用它?
    【解决方案2】:

    这里的情况类似。我尚未评估“纯 RedGate”解决方案 - 但对于以 MS 为中心的商店,我会推荐

    • 一个用于 PROD 就绪模式控制的 SQLProject(即,您要发布的任何东西,都放在这里)
    • 仅包含 tSQLt 和 tSQLt 单元测试脚本的 SQLProject
    • MSTest 数据驱动测试调用 tSQLt 来执行测试

    在 CICD 设置中部署 PROD-ready SQLProject,然后部署 tSQLt SQLProject,然后执行 MSTest 套件。

    详情

    不幸的是,没有简单的方法来枚举您的开发人员可能在 TestExplorer 中作为单独项目编写的每个 tSQLt 单元测试,除非您强制他们为每个 tSQLt 测试编写 C# 代理测试(这容易出错并且重复工作) ,或者您利用 T4 模板(例如,为 tSQLt 测试列表探测 SQL,然后使用模板动态生成 MSTest 源文件),这似乎是做作和矫枉过正。

    MSTest 数据驱动的测试设置起来有点麻烦,但它是documented,一旦完成,就不需要再碰了。

    public TestContext TestContext { get; set; }
    
    [TestCategory("Integration")]
    [TestMethod]
    // NOTE: DataSources should be configured as described here
    // https://msdn.microsoft.com/en-us/library/ms182527.aspx 
    // 
    // NOTE: when configuring DataSource table, use tSQLt.Tests
    [DataSource("MyDataSource")]
    public void Test()
    {
        // NOTE: tSQLt.Tests returns a multi-column table, index
        // as appropriate
        string name = $"{TestContext.DataRow[1]}.{TestContext.DataRow[3]}";
        using (SqlConnection connection = new SqlConnection(ConfigurationManager.
            ConnectionStrings["MyConnectionString"].
            ConnectionString))
        {
            connection.Open();
            // NOTE: using Dapper to invoke
            try { connection.Query($"exec tSQLt.Run '{name}'"); }
            // NOTE: this is how we surface individual test names
            // on failure
            catch { Assert.Fail($"Failed tSQLt test '{name}'."); }
        }
    }
    

    样本输出

    替代方案和注意事项

    SSDT 单元测试:我没有真正看到这里的附加值。 GUI 很笨拙,完全不直观。如果你是一个强大的 C# 开发人员,按钮和设计器是一个障碍。如果您是强大的 SQL 开发人员,那么代码隐藏和新的 IDE(VS 与 SSMS)会很痛苦。

    NUnit:就表示而言,NUnit 的TestCase 属性将是最佳的,因为将 tSQLt 测试名称直接放在 TestExplorer 中而不作为单独的测试前缀是理想的。不幸的是,我们无法对TestCase 进行数据驱动。相反,我们可能只使用TestCaseSource,它似乎用[TestMethodName]("[tSQLtTestName]") 格式化每个测试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-19
      • 2016-02-02
      • 1970-01-01
      • 1970-01-01
      • 2011-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多