Presentation is loading. Please wait.

Presentation is loading. Please wait.

Unit Testing with tSQLt

Similar presentations


Presentation on theme: "Unit Testing with tSQLt"— Presentation transcript:

1 Unit Testing with tSQLt
reluctantly Or, “How I ˄ Became a Better SQL Developer...” by Mark Fugel

2 Course Abstract: Unit Testing with
This session is for anyone interested in getting started in setting up an environment where you wish to establish unit testing for SQL. It will include how to install, setup, create, run and even come to depend on (& maybe even enjoy!) having your unit tests in place to "have your back"! Real examples will used to show how unit tests can be used to test stored procedures and functions. We will discuss how tSQLt can even be used to enforce development standards in your team. We will show how it can even be integrated into your automated build and release processes (such as Team City). 2 | 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

3 About me… Mark Fugel Rutgers ’77 St Peter’s ‘86
Database Developer/Development DBA Application Developer Old fart: After leaving teaching in 1984, worked with various companies including 17 years with AT&T, 3M, & currently in a TnwDevLabs agile The Network 3 | 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

4 My Story starts when… Returning to my old company after 6 years, I found a different company & culture – developer-driven & agile focused using all the “latest” languages, tools, techniques and practices. Assigned project to establish data transfer from RavenDb (NoSQL) front-end application to reporting back-end system in SQL Server using MS Service Broker messaging architecture. Created a multitude of “shredder” stored procedures” as Service Broker Queue Activation procedures to transfer data from JSON to XML and populate SQL tables. 4 | 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

5 My Challenge… Developer Leads’ Questions to me:
My Feeble Initial Responses to them: If you’re implementing code in sp’s, triggers, functions – are you testing your code as we do the app code? Our tests are part of our application and in source control. Will yours be? Can your tests be run by others? Can they be automated? We practice TDD. Will you be doing the same with your project? I test all my code. I can check-in test scripts as part of my code too if that’s what you want. Uh…sure. I guess so. Huh? TDD…hmm… I guess so. If that’s what our shop does, then by golly, I will do it too! 5 | 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

6 My “Real” Initial Reaction…
I do quality work. They just don’t know me. I do test. Ok…they are manual scripts but I make sure everything I do works. This is DB work. It’s different. I don’t have the same tools they are lucky to have. It’s just me. They have a lot more people. It will take way too long for me to setup and do all that testing alone, even if I had a way. 6 | 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

7 Their “Real” Belief 7 | 5/14/2015 |
7 | 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

8 Their “Real” Thoughts of My Methods
8 | 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

9 Their Expectation & Demands
If it's worth building, it's worth testing. If it's not worth testing, why are you wasting your time working on it? Test as often and early as possible, and better yet, test first. Test with a purpose! 9 | 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

10 What exactly were they looking for…
What Is Test-Driven Development? What Test-Driven Development Is NOT? Not a panacea. Not bug-free code. Not integration, load or acceptance testing. 10 | 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

11 My Initial Reservations
My “Conversion”… My Initial Reservations No time or desire to, yet again, learn something new - just to write tests! Writing tests takes much too long and slows down the development process. We have real deadlines. DB Unit testing is too hard because it involves setting up lots of test data and dependencies. Too much legacy code – setting up unit testing would be overwhelming. Lack of experience & no one does it My Actual Experience Provides Earlier Bug Notification Leads to Better Design, Cleaner & More Extensible Code, & more Stable product Gives me Confidence to Refactor Contributes to Team Work & Documentation Leads to Greater Developer Satisfaction Easier than I anticipated Eat the elephant one byte at a time! 11 | 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

12 Searching for a SQL Unit Testing Framework
The Quest Began… Searching for a SQL Unit Testing Framework Similar to xUnit, NUnit frameworks used in C# Arrange, Act, Assert (AAA) Model for testing Robust Assertion Engine No special debugging code in our prod code Has Mocking/Faking & should be simple Run tests singly, in groups, or all & in any order No dependencies between tests Test Setup &Teardown should be easy No new language to learn/same IDE preferably Standard human readable output Can be automated & output redirected to reporting Good documentation & industry support 12 | 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

13 DB Unit Testing Candidates:
The Quest Continued… DB Unit Testing Candidates: DbFit SQLUnit TSQLUnit Visual Studio Unit Testing tSQLt 13 | 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

14 And the Winner was… Why tSQLt ?
Reusable Setup functionality available. Variety of Assertions for varied testing scenarios. Allows for testing of non-Happy path exceptions Easy to separate test objects from production code Tests can be run one at time or all at once Test output in XML Rich testing framework exclusively for SQL Server Tests are written in T-SQL Tests can be versioned & stored in source control Tests are executed as stored procedures No need to work in another tool – can work in SSMS or Visual Studio. (or Redgate’s SQLTest) Test Isolation. Each test is a transaction. 14 | 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

15 Installing tSQLt… Download the latest version at SourceForge.
Select a DB in SSMS to install it in. Run SetClrEnabled.sql Run tSQLt.class.sql That’s it! You’re ready to test! Optional: Download tSQLt.PrepareTableForFaking.sql at This stored proc is necessary when testing objects with dependencies; specifically, objects with SCHEMABINDING (ex. Indexed Views). 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

16 What did we get with tSQLt…
All tSQLt commands are tSQLt Stored Procedures ! 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

17 Setting up our first Unit Test…
Each test is a stored procedure. Each test must have a name beginning with ‘test’. Each test should only try to answer one question or requirement All together, your tests should cover all paths Happy path Errors/Exceptions Boundaries/Extremes 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

18 Things to think about… Remember the Definition of a Unit Test
A Method (Code) that tests specific functionality, has clear pass/fail criteria and runs in isolation 3 Areas of Every Unit Test: Arrange Act Assert 18 | 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

19 First, create a tSQLt Class:
tSQLt Class is nothing more than a “schema”. Provides way to categorize your tests into groups Make them meaningful I recommend starting them with “tSQLt_” You create a new Class by issuing the command: exec tSQLt.NewTestClass ‘tSQLt_YourTestClassGoesHere’ 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

20 Next, Create a Test Using a Template:
-- For test case examples, see: CREATE PROCEDURE [mytestclass].test_my_test_template AS BEGIN -- <<ARRANGE>> or Assemble -- This section is for code that sets up the environment. -- It often contains calls to methods such as tSQLt.FakeTable and tSQLt.SpyProcedure along with INSERTs of relevant data. -- For more information, see exec [tSQLt].[Private_Print] 'Running SQL Test: [mytestclass].[test_my_test_template]' exec [tSQLt].[Private_Print] ' Purpose:<<<Test Purpose Goes Here>>' exec [tSQLt].[Private_Print] ' ' --Test Exec SQL: exec tSQLt.Run '[mytestclss].[test_my_test_template]' */ -- Create new Expected table here CREATE TABLE dbo.Expected (<<< DECLARE COLUMNS OF EXPECTED TABLE HERE>>>) -- Populate Expected Table here INSERT into dbo.Expected SELECT <<< POPULATE COLUMNS OF EXPECTED TABLE HERE>>> -- Create empty Actual table SELECT TOP 0 * INTO dbo.Actual FROM dbo.Expected -- Fake any other stored procedures/functions here if needed -- Fake tables here if needed 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

21 Unit Testing with tSQLt by Mark Fugel
-- <<ACT>> -- Execute the code under test like a stored procedure, function or view -- and capture the results in variables or tables. --*****FUNCTION/STORED PROCEDURE TO TEST GOES HERE************************ EXEC <<<dbo.myprocecuretotest ‘myparam1’>>> --*************************************************************** -- Get the rows just affected by test and put into Actual table for comparison w/Expected INSERT INTO dbo.Actual SELECT <<<GET RESULTS INTO ACTUAL TABLE>>> -- <<ASSERT>> -- Compare the expected and actual values, or call tSQLt.Fail in an IF statement. -- Available Asserts: tSQLt.AssertEquals, tSQLt.AssertEqualsString, tSQLt.AssertEqualsTable -- For a complete list, see: -- EXEC tSQLt.Fail ‘<<<Test Not implemented>>>’; EXEC = N'[dbo].[Expected]', @Actual = N'[dbo].[Actual]', @FailMsg = N'Tables do not match’ int = (SELECT COUNT(*) FROM dbo.Actual) int = <<<PUT EXPECTED COUNT HERE>>> END; GO 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

22 Finally, Running Unit Test(s)…
Run a single test: exec tSQLt.Run ‘YourTestGoesHere’ Run only unit tests that belong to the same test class: exec tSQLt.Run ‘YourTestClassGoesHere’ Run All Unit Tests: exec tSQLt.RunAll Run tSQLt 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

23 Run tSQLt Demo Setup Current application returns the Top 10 Most Expensive Products Current application utilizes this Stored Procedure: CREATE procedure [dbo].[Ten Most Expensive Products] AS SET ROWCOUNT 10 SELECT Products.ProductName AS TenMostExpensiveProducts, Products.UnitPrice FROM Products ORDER BY Products.UnitPrice DESC New requirements are delivered to you: Allow for variable number of products to be returned based on input Columns returned should be ProductName, CategoryName and UnitPrice Error if no input or zero is provided as input Unit Testing with tSQLt by Mark Fugel 5/14/2015 |

24 Demo 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

25 Isolating Dependencies Test Creation/Execution
Other tSQLt commands… Assertions Expectations Isolating Dependencies AssertEmptyTable ExpectException ApplyContraint AssertEquals ExpectNoException FakeTable AssertEqualsString Test Creation/Execution SpyProcedure AssertLike NewTestClass FakeFunction AssertNotEquals DropClass RemoveObjectIfExists AssertObjectDoesNotExist RunAll ApplyTrigger AssertObjectExists Run RemoveObject Fail RenameClass PrepareTableForFaking* AssertResultSetsHaveSameMetaData For full explanation of each with examples, see: 5/14/2015 Unit Testing with tSQLt by Mark Fugel

26 Using SQL Test Redgate’s SQL Test Add-in for SSMS
UI for tSQLt framework Easier to interface with tSQLt tests 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

27 Using SQL Cop Series of tSQLt tests (by G. Mastros) to highlight potential problems or violations of best practices. Detects “Issues” in: • Code • Columns • Tables/Views • Indexes • Configuration • Db Health Download all 48 tests here: dl.dropbox.com/u/ /SQLCop%20Tests.zip Use only the ones that make sense for your situation Demonstrates how you can create your own tests to enforce your own shop’s DB standards and/or naming conventions. 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

28 Integrating tSQLt with CI
Our team utilizes JetBrain’s TeamCity to do our builds and deployments tSQLt runner plugin for TeamCity Step by step instructions in David Green’s Simple Talk excellent article: 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

29 Uninstalling tSQLt… Easily uninstall all tSQLt framework objects by running uninstall script from database: EXEC tSQLt.Uninstall 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

30 References & Resources…
Topic Link tSQLt Tsqlt.org SQL Test SQL Cop Why tSQLt? By Greg Lucas Getting Started with tSQLt by Robert Sheldon Getting Started with Test Driven Design in Sql Server by Sebastian Meine Pluralsight tSQLt Course Using SQL Test Database Unit Testing with TeamCity Continuous Integration by David Green Agile Sql Club – Ed Elliott’s blog DB Unit Testing for Sql Server Using tSQLt Robert C Martin Series By Dennis Lloyd 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

31 Final thought… 5/14/2015 | Unit Testing with tSQLt by Mark Fugel

32 Special thanks to our Sponsors!


Download ppt "Unit Testing with tSQLt"

Similar presentations


Ads by Google