You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
To run this sample, you need the following prerequisites.
31
+
To run this example, the following basic concepts are required.
32
+
33
+
[tSQLt](https://tsqlt.org/) is a unit testing framework for SQL Server. It provides the APIs to create and execute test cases, as well as integrates them with continuous integration servers. The power of the tSQLt framework has been described in my article [The tSQLt framework and the execution of a test](https://segovoni.medium.com/unit-testing-the-tsqlt-framework-and-the-execution-of-a-test-e4d135c3e343).
34
+
35
+
[Docker](https://www.docker.com/) is one of the most popular systems for running applications in isolable, minimal and easily deployable environments called containers. Since SQL Server 2017, the SQL Server Engine can run in a Docker container, a typical usage of running SQL Server in a Docker container concerns the automation of software tests.
36
+
37
+
[GitHub Actions](https://github.com/features/actions/) is a continuous integration and continuous delivery (CI/CD) platform that allows you to automate your build, test, and deployment pipeline. You can create workflows that build and test every pull request to your repository, or deploy merged pull requests to production. GitHub provides Linux, Windows, and macOS virtual machines to run your workflows, or you can host your own self-hosted runners in your own data center or cloud infrastructure such as Microsoft Azure.
40
38
41
39
**Software prerequisites:**
42
40
43
-
<!-- Examples -->
44
-
1. SQL Server 2016 (or higher) or an Azure SQL Database
45
-
2. Visual Studio 2015 (or higher) with the latest SSDT installed
41
+
1. GitHub account. If you don't already have a GitHub account, you can get one for free [here](https://github.com/signup)!
42
+
2. GitHub sample repository
43
+
44
+
<aname=case-history></a>
45
+
46
+
## Case history
46
47
47
-
**Azure prerequisites:**
48
+
The AdventureWorks2017 database contains the Production.Product table that stores products managed and sold by the fake company Adventure Works LTD.
48
49
49
-
<!-- Examples -->
50
-
1. Permission to create an Azure SQL Database
50
+
The trigger we have wrote is to prevent the insertion of new products with values less than 10 as a “safety stock”. The Company wishes to always have a warehouse stock of no less than 10 units for each product. The safety stock level is a very important value for the automatic procedures: it allows to re-order materials. The creation of new purchase orders and production orders are based on the safety stock level. To make our trigger simple, it will only respond to the OnInsert event, for INSERT commands.
51
51
52
52
<aname=run-this-sample></a>
53
53
54
54
## Run this sample
55
55
56
-
<!-- Step by step instructions. Here's a few examples -->
56
+
<!-- Step by step instructions -->
57
+
58
+
The implementation of the trigger and related unit tests has been done.
59
+
60
+
The challenge is to automate the execution of the tests at each commit on the main branch of the repository. GitHub Actions is our CI/CD platform, it supports the use of Docker containers and it is intimately integrated into GitHub, the source control that manages our source code.
61
+
62
+
**Create your first workflow**
63
+
64
+
Let's go ahead with the creation of a workflow: an automated and configurable process that will execute one or more jobs.
65
+
66
+
Workflows are defined with a YAML file stored in the same repository which holds the source code. The workflows will be triggered when an event occurs in the repository. Anyway, a workflow can also be activated manually or according to a defined schedule. Follow [these instructions](https://docs.github.com/en/actions/quickstart) to create your first workflow.
67
+
68
+
A sample YAML file that implements the test automation workflow is available here, the fundamental steps are:
69
+
70
+
1. Definition of activation events
71
+
2. Creating a Docker container from a SQL Server image on Linux
72
+
3. AdventureWorks2017 database recovery
73
+
4. Installation of the tSQLt framework
74
+
5. Creating the database objects to be tested (SUT)
75
+
6. Creation and execution unit tests
76
+
77
+
**1. Definition of activation events**
78
+
79
+
The definition of the activation events is typically done at the beginning of the YAML script with a code snippet similar to the one shown below. The workflow is activated when push or pull request events occur on the “master” branch. The “workflow_dispatch” specification allows you to run the workflow manually from the actions tab.
80
+
81
+
```
82
+
# Controls when the workflow will run
83
+
on:
84
+
# Triggers the workflow on push or pull request events but only for the "master" branch
85
+
push:
86
+
branches: [ "master" ]
87
+
pull_request:
88
+
branches: [ "master" ]
89
+
90
+
# Allows you to run this workflow manually from the Actions tab
91
+
workflow_dispatch:
92
+
```
93
+
94
+
**2. Creating a Docker container from a SQL Server image on Linux**
95
+
96
+
Creating a Docker container from a SQL Server image on Linux can be done by requesting the sqlserver service accompanied by the path to the Docker image you want to use.
97
+
98
+
The official images provided by Microsoft for SQL Server on Linux are available [here](https://hub.docker.com/_/microsoft-mssql-server).
99
+
100
+
We will not use an official image downloaded from the Microsoft registry. We will use a Docker image of SQL Server with the AdventureWorks database installed, this image is published by [chriseaton](https://hub.docker.com/u/chriseaton), you can find it at this [link](https://hub.docker.com/r/chriseaton/adventureworks).
101
+
102
+
The following YAML code snippet sets up the SQL Server service.
103
+
104
+
```
105
+
jobs:
106
+
windows-auth-tsqlt:
107
+
name: Installting tSQLt with SQL Auth
108
+
# The type of runner that the job will run on
109
+
runs-on: ubuntu-latest
110
+
111
+
services:
112
+
sqlserver:
113
+
image: chriseaton/adventureworks:latest
114
+
ports:
115
+
- 1433:1433
116
+
env:
117
+
ACCEPT_EULA: Y
118
+
SA_PASSWORD: 3uuiCaKxfbForrK
119
+
```
120
+
121
+
In order to reference the newly created Docker container it is important to save its identifier in an environment variable.
122
+
123
+
The following snippet of YAML code sets the ENV_CONTAINER_ID variable with the ID of the container created.
The AdventureWorks2017 database recovery can be performed using the following docker exec command.
133
+
134
+
```
135
+
- name: Restore AdventureWorks2017
136
+
run: docker exec -i $ENV_CONTAINER_ID /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P "3uuiCaKxfbForrK" -Q "RESTORE DATABASE [AdventureWorks2017] FROM DISK = '/adventureworks.bak' WITH MOVE 'AdventureWorks2017' TO '/var/opt/mssql/data/AdventureWorks.mdf', MOVE 'AdventureWorks2017_log' TO '/var/opt/mssql/data/AdventureWorks_log.ldf'"
137
+
```
138
+
139
+
**4. Installation of the tSQLt framework**
140
+
141
+
The installation of the latest version of tSQLt framework in the AdventureWorks2017 database is done using the GitHub Actions tSQLt Installer published by [lowlydba](https://github.com/lowlydba), you can find more details [here](https://github.com/lowlydba/tsqlt-installer) and on the [GitHub Actions marketplace](https://github.com/marketplace/actions/tsqlt-installer).
142
+
143
+
The snippet of YAML code used for the installation of the tSQLt framework in the AdventureWorks2017 database is the following.
144
+
145
+
```
146
+
steps:
147
+
- uses: actions/checkout@v2
148
+
- name: Install tSQLt with SQL auth on AdventureWorks2017
149
+
uses: lowlydba/tsqlt-installer@v1
150
+
with:
151
+
sql-instance: localhost
152
+
database: AdventureWorks2017
153
+
version: latest
154
+
user: sa
155
+
password: 3uuiCaKxfbForrK
156
+
```
157
+
158
+
**5. Creating the database objects to be tested (SUT)**
159
+
160
+
The test environment is ready, we have a SQL Server instance on Linux inside a Docker container; the AdventureWorks2017 database has been restored and it is ready for use.
161
+
162
+
Let's go ahead with the creation of the trigger and the stored procedure (that manages errors), they represent our [System Under Test (SUT)](https://en.wikipedia.org/wiki/System_under_test).
163
+
164
+
The TR_Product_SafetyStockLevel trigger creation script and the usp_Raiserror_SafetyStockLevel stored procedure creation script are saved in the source directory of this sample.
165
+
166
+
Triggers and stored procedures are created in the AdventureWorks2017 database attached to the SQL Server instance, the YAML code snippet that performs this operation is the following.
The last phase of this workflow is represented by the creation and execution of the unit tests.
178
+
179
+
The test class and the unit tests creation scripts are contained in the unit-test subfolder of this sample.
180
+
181
+
Let's go ahead with the creation of the test class dedicated to the TR_Product_SafetyStockLevel trigger, we called it UnitTestTRProductSafetyStockLevel.
182
+
183
+
The following docker exec command, that uses sqlcmd, executes the TSQL commands contained in the test-class-trproductsafetystocklevel.sql script.
184
+
185
+
```
186
+
- name: Create test class UnitTestTRProductSafetyStockLevel
Let's go ahead with the creation and execution of the unit tests. Each .sql file of the "test case" family contains the TSQL commands for creating and running the related unit test. Each store procedure tests one and only one test case.
57
191
58
-
1. From Visual Studio, open the **sample.sln** file from the root directory.
192
+
The following snippet of YAML code creates and runs the test units.
59
193
60
-
2. In Visual Studio Build menu, select **Build Solution** (or Press F6).
194
+
```
195
+
- name: Create and run test case try to insert one wrong row
0 commit comments