Rupendra
Rupendra

Reputation: 608

How to unit test the database code for Sql Server 2014

I am working on developing a unit test framework for the db code in Sql Server 2014. My requirement is following:

After doing some research, I think i have three options with the help of the tools SSDT with MSTest and tSqlT as:

Can anyone suggest a better approach on the db unit testing?

Thanks

Upvotes: 0

Views: 1178

Answers (2)

johnny g
johnny g

Reputation: 3561

In a similar situation here. I have yet to evaluate a "pure RedGate" solution - but for an MS-centric shop, I would recommend

  • a SQLProject for PROD-ready schema control (ie anything you're going to ship, place here)
  • a SQLProject that contains only tSQLt and tSQLt unit tests scripts
  • MSTest data-driven test invokes tSQLt to execute tests

In CICD setup deploy PROD-ready SQLProject, then tSQLt SQLProject, then execute MSTest suite.

Details

Unfortunately, there is no easy way to enumerate each tSQLt unit test your developers may author as an individual item in TestExplorer, unless you force them to write a C# proxy test for each tSQLt test (which is error prone and duplicates work), or you leverage T4 templating (eg probe SQL for tSQLt test list, then use a template to dynamically generate MSTest source files), which seems hokey and overkill.

MSTest data-driven tests are a bit of a pain to set up, but it's documented, and once it's done, doesn't need to be touched again.

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}'."); }
    }
}

Sample output

Sample output of MSTest with tSQLt integration

Alternatives and considerations

SSDT unit tests: I don't really see the value add here. The GUI is clumsy and completely unintuitive. If you are a power C# developer, the buttons and designer are a hindrance. If you are a power SQL developer, the code-behind and new IDE (VS vs SSMS) is a pain.

NUnit: In terms of presentation, NUnit's TestCase attributes would be optimal, as having the tSQLt test name surface directly in TestExplorer without prefix as an individual test would be ideal. Unfortunately, we cannot data-drive TestCase. Instead, we may only use TestCaseSource, which seems to format every test with [TestMethodName]("[tSQLtTestName]").

Upvotes: 0

Ed Elliott
Ed Elliott

Reputation: 6856

Steph locke pretty much has this wrapped up for you:

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

Highlights:

ok?

ed

Upvotes: 5

Related Questions