unit testing for sql prepared for sugsa codelabs alain king paul johnson
TRANSCRIPT
![Page 1: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/1.jpg)
UNIT TESTINGFOR SQL
Prepared for SUGSA CodeLabs
Alain King
Paul Johnson
![Page 2: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/2.jpg)
Unit Testing for SQL 2
Why?
Simply put, we want quality!
![Page 3: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/3.jpg)
Unit Testing for SQL 3
How
• KRS is committed to Behaviour Driven Development (BDD), i.e. using stories and scenarios to drive development.
• With most of the newer technologies, these scenarios turn into unit tests, either in MSTest, Nunit, Junit, and others
![Page 4: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/4.jpg)
Unit Testing for SQL 4
…But…
• We also have big, complex legacy systems that have served us well for many years…
• …and these are mostly written using MS SQL Server stored procedures…
• …and yet we still demand quality, robust, elegant solutions…
![Page 5: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/5.jpg)
Unit Testing for SQL 5
…And…
• Clients have invested in high-end servers to host the database so we want to harness that power for large processing tasks (like month end processes)…
• … and there are a number of functions that happen through SQL code in the BI environment (like the ETL process) …
![Page 6: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/6.jpg)
Unit Testing for SQL 6
Now what?
• How do you safely add new database functionality?
• How do you safely refactor existing stored procedures/functions?
…without breaking the existing system…
![Page 7: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/7.jpg)
Unit Testing for SQL 7
Introducing tSQLt
• tSQLt is a database unit testing framework for Microsoft SQL Server.
• tSQLt is compatible with SQL Server 2005 (service pack 2 required) and above on all editions.
• tSQLt allows you to implement unit tests in T-SQL.
• This is important as you do not have to switch between various tools to create your code and your unit tests.
![Page 8: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/8.jpg)
Unit Testing for SQL 8
tSQLt Features
• Tests are automatically run within transactions – this keeps tests independent and reduces any cleanup work you need
• Tests can be grouped together within a schema – allowing you to organize your tests and use common setup methods
• Output can be generated in plain text or XML – making it easier to integrate with a continuous integration tool
• Provides the ability to fake tables and views, and to create stored procedure spies – allowing you to isolate the code which you are testing
![Page 9: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/9.jpg)
Unit Testing for SQL 9
Examples
Lets look at some sample code• Write a test for a new stored proc
![Page 10: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/10.jpg)
Unit Testing for SQL 10
Examplesbegin tran
select * from Person.Person where BusinessEntityID = 2
BusinessEntityID PersonType NameStyle Title FirstName MiddleName LastName 2 EM 0 NULL Terri Lee Duffy
declare @BusinessEntityID int, @MiddleName varchar(50) select @BusinessEntityID = 2, @MiddleName = 'Leigh'
update Person.Person set MiddleName = @MiddleName where BusinessEntityID = @BusinessEntityID select * from Person.Person where BusinessEntityID = 2
BusinessEntityID PersonType NameStyle Title FirstName MiddleName LastName 2 EM 0 NULL Terri Leigh Duffy
rollback transaction
select * from Person.Person where BusinessEntityID = 2
BusinessEntityID PersonType NameStyle Title FirstName MiddleName LastName 2 EM 0 NULL Terri Lee Duffy
![Page 11: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/11.jpg)
Unit Testing for SQL 11
Examplesselect * from Person.Person where BusinessEntityID = 2
BusinessEntityID PersonType NameStyle Title FirstName MiddleName LastName 2 EM 0 NULL Terri Lee Duffy
begin tran
declare @BusinessEntityID int, @MiddleName varchar(50) select @BusinessEntityID = 2, @MiddleName = 'Leigh'
exec Person.uspUpdatePersonInfo @BusinessEntityID = @BusinessEntityID, @MiddleName = @MiddleName select * from Person.Person where BusinessEntityID = 2
BusinessEntityID PersonType NameStyle Title FirstName MiddleName LastName 2 EM 0 NULL Terri Leigh Duffy
rollback transaction
-- check that data is back to originalselect * from Person.Person where BusinessEntityID = 2
BusinessEntityID PersonType NameStyle Title FirstName MiddleName LastName 2 EM 0 NULL Terri Lee Duffy
![Page 12: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/12.jpg)
Unit Testing for SQL 12
Examplesexec tSQLt.NewTestClass 'TestPerson'godrop proc TestPerson.[test Person middle name updated correctly]gocreate proc TestPerson.[test Person middle name updated correctly]asbegin declare @BusinessEntityID int, @MiddleName varchar(50) select @BusinessEntityID = 2, @MiddleName = 'Leigh'
-- When I update the MiddletName declare @retval int exec @retval = Person.uspUpdatePersonInfo @BusinessEntityID = @BusinessEntityID, @MiddleName = @MiddleName declare @ActualMiddleName varchar(50) select @ActualMiddleName = middlename from Person.Person where BusinessEntityID = @BusinessEntityID exec tSQLt.AssertEqualsString @MiddleName, 'broken' end
exec tSQLt.RunAll
![Page 13: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/13.jpg)
Unit Testing for SQL 13
Examplesexec tSQLt.RunAll
[TestPerson].[test Person middle name updated correctly] failed: Expected: <Leigh> but was: <broken> +----------------------+|Test Execution Summary|+----------------------+ |No|Test Case Name |Result |+--+--------------------------------------------------------+-------+|1 |[TestPerson].[test Person middle name updated correctly]|Failure|-----------------------------------------------------------------------------Msg 50000, Level 16, State 10, Line 1Test Case Summary: 1 test case(s) executed, 0 succeeded, 1 failed, 0 errored.-----------------------------------------------------------------------------
![Page 14: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/14.jpg)
Unit Testing for SQL 14
Examples
• Write a test for a new stored proc
• So what did I do wrong?
• Test First
![Page 15: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/15.jpg)
Unit Testing for SQL 15
Examples
Scenario
Given Person with ID 2 and Middle Name of Lee
When I update the Middle Name to be Leigh
Then the Middle Name for Person with ID 2 should be Leigh
![Page 16: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/16.jpg)
Unit Testing for SQL 16
Examples
Write a test for a new stored proc
• Lets have a look at some code
![Page 17: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/17.jpg)
Unit Testing for SQL 17
Examples
• Write a test to compare 2 result sets
• Upgrading legacy systems to be 2008 / 2012 compliant
• Replacing complex queries with CTE’s to be easier to maintain
• In both cases, you are making changes to code and the expect result should be same
![Page 18: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/18.jpg)
Unit Testing for SQL 18
Examples
• Write a test to compare 2 result sets
• We can check this by writing a test to output the results from the original code into one table and the results of the modified code into another table and comparing them.
• But we don’t just want to compare for one set of inputs
![Page 19: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/19.jpg)
Unit Testing for SQL 19
Examples
• Write a test to compare 2 result sets
• JUnit and NUnit have TestCase functionality that allows one to run the same test with just supplying inputs and expected results as parameters.
![Page 20: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/20.jpg)
Unit Testing for SQL 20
ExamplesEXEC tSQLt.NewTestClass 'test_BillingReports';GO
/* ----------------------------------------------------------------------------- */create procedure test_BillingReports.[test periodbilling (@periodno 201101).]asbegin exec test_BillingReports.periodbilling_sub 201101end;
/* ----------------------------------------------------------------------------- */create procedure test_BillingReports.[test periodbilling (@periodno 201201).]asbegin exec test_BillingReports.periodbilling_sub 201201 end;
/* ----------------------------------------------------------------------------- */create procedure test_BillingReports.[test periodbilling (@periodno 201202).]asbegin exec test_BillingReports.periodbilling_sub 201202 end;
![Page 21: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/21.jpg)
Unit Testing for SQL 21
Examplescreate procedure test_BillingReports.periodbilling_sub(@periodno int)asbegin if object_id('actual') is not null drop table actual; if object_id('expected') is not null drop table expected;
------Assertion create table actual ( columns )
create table expected ( columns )
--OtherDatabase has the original version of the sproc insert expected ( columns ) exec OtherDatabase..periodbilling @periodno = @periodno
insert actual ( columns ) exec periodbilling @periodno = @periodno
exec tSQLt.assertEqualsTable 'expected', 'actual'; end;go
EXEC tSQLt.run 'test_BillingReports';
![Page 22: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/22.jpg)
Unit Testing for SQL 22
Examples
• Write a test to compare 2 result sets
• Lets take a look at some more code
![Page 23: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/23.jpg)
Unit Testing for SQL 23
Examples
• Write a test for an existing stored procedure
• This can be used for DDT – Defect Driven Testing or for enhancing existing functionality.
• Lets look at a test for an existing procedure in AdventureWorks called uspGetEmployeeManagers
![Page 24: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/24.jpg)
Unit Testing for SQL 24
Exercises
• Download from tsqlt.org
• exec tSQLt.NewTestClass 'TestPerson'• Go
• create proc TestPerson.[test UpdatePersonMiddleName]• as
• exec tSQLt.AssertEqualsString @MiddleName, @ActualMiddleName
• end
• exec tSQLt.RunAll
![Page 25: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/25.jpg)
Unit Testing for SQL 25
Exercises
• Write a test for a new stored procedure to check if an email address already exists in the database
![Page 26: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/26.jpg)
Unit Testing for SQL 26
Exercises
• Write a test for a new stored procedure to update available leave hours for an employee
![Page 27: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/27.jpg)
Unit Testing for SQL 27
Exercises
• We want to make changes to an existing stored procedure, write a test for uspGetBillOfMaterials to ensure that any changes you make do not have a negative impact on existing functionality.
![Page 28: UNIT TESTING FOR SQL Prepared for SUGSA CodeLabs Alain King Paul Johnson](https://reader034.vdocument.in/reader034/viewer/2022042822/56649e455503460f94b39454/html5/thumbnails/28.jpg)
28
Questions?
www.krs.co.za
( (021) 681 2900Alain King: [email protected] Johnson: [email protected]
Unit Testing for SQL