Published on

April 20, 2022

Why Writing Unit Tests for SQL Server is Important

Unit testing is a crucial aspect of software development, and this holds true for SQL Server as well. Many developers often question the value of writing unit tests, believing that it requires a significant effort and may not catch all bugs. However, the benefits of writing unit tests far outweigh the perceived challenges.

One area where unit tests can be particularly useful in SQL Server is when writing queries that involve running totals. While experienced T-SQL developers may find this task relatively straightforward, it is easy to make mistakes. Let’s consider a simple example:

SELECT
  CustomerID,
  OrderDate,
  CustomerRunningTotal =
  (
      SELECT CustomerRunningTotal = SUM(TotalDue)
       FROM  Sales.SalesOrderHeader
       WHERE
             CustomerID    = A.CustomerID
             AND OrderDate <= A.OrderDate
  )
FROM Sales.SalesOrderHeader AS A
ORDER BY
  A.CustomerID,
  A.OrderDate;

This query produces a large number of results, and it is impractical to manually validate each one. In fact, this query contains a bug that can easily go unnoticed. To address this, we can rewrite the query using window functions, which are available in SQL Server 2012 and later versions.

Now, instead of manually experimenting with the query and checking a few results, we can write a unit test to ensure the accuracy of our code. Let’s walk through the process of creating a simple test:

EXEC tsqlt.NewTestClass @ClassName = N'ztsqltests'
GO
CREATE PROCEDURE [ztsqltests].[test running total query on Sales Order Header]
AS
BEGIN
    -- Assemble
    DECLARE @expected INT, @actual INT
    
    -- Act
    
    -- Assert
    EXEC tsqlt.AssertEquals @Expected = @expected, 
                            @Actual = @actual,   
                            @Message = N'Incorrect result'
END    
GO

In the above example, we have created a new test class and a test procedure. The test follows a basic structure:

  1. Assemble an environment
  2. Act on some data
  3. Assert a truth

In the “Assemble” section, we set up the necessary data for the test. This can be done using tools like tsql.faketable to create a copy of the table we are testing. We can then insert test data into this table.

The “Act” section is where we execute our code or stored procedure that we want to test. In this case, we can call our stored procedure that contains the running total query.

Finally, in the “Assert” section, we compare the expected results with the actual results using assertions provided by the testing framework. This ensures that our code is producing the desired outcome.

By writing unit tests, we can catch bugs and ensure the correctness of our code. Unit tests are repeatable and can be automated, allowing for easy regression testing. They also serve as documentation for our thought process as developers and can be shared with others for review.

While writing unit tests may initially seem challenging, with practice and the use of templates or snippets, it becomes a streamlined process. Starting with testing code that is being refactored or modified is a good approach. Over time, we can build up a comprehensive set of tests to cover different scenarios.

Unit testing is an essential part of the software development lifecycle, and SQL Server is no exception. It helps us write better code, catch bugs early, and ensure the reliability of our database applications.

Click to rate this post!
[Total: 0 Average: 0]

Let's work together

Send us a message or book free introductory meeting with us using button below.