CONNECTED Conference 2023 - Aufzeichnungen jetzt hier verfügbar +++                     

Suche

über alle News und Events

 

Alle News

 

Was ist ein Excel-Plugin – und wann ist es...

Weiterlesen

Wir expandieren, bringen Kunden und Talente besser...

Weiterlesen

Um HTML zum PDF zu konvertieren, werden wir...

Weiterlesen

Die Logic Apps-Plattform von Microsoft ermöglicht...

Weiterlesen

Du bist neugierig auf aktuelle KI-Technologien und...

Weiterlesen

Am 27.09. ab 12.30h starten die vierten QUIBIQ...

Weiterlesen

"Das Beste von SAP und Microsoft nutzen": auf dem...

Weiterlesen

Azure Bicep wird verwendet, um Ressourcen in Azure...

Weiterlesen

In einer Welt, die immer digitaler wird, ist es...

Weiterlesen

Dieser Artikel beschreibt wie JSON-Dateien anhand...

Weiterlesen

How-to: UnitTesting für den SQL-Server

Der Schnelleinstieg in die Welt der Tests für den SQL-Server.

  1. Ausgangssituation
    1. Über die Dringlichkeit von Tests

Wie bereits in vielen wissenschaftlichen Abhandlungen gezeigt wird, ist das Testen von Code von großer qualitativer und finanzieller Bedeutung bei der Softwareentwicklung.

Je früher und modularer Tests in der Entwicklung angewendet werden, desto einfacher ist deren Bereitstellung. Im Gegenzug dazu sind Fehler, die in der Entwicklungsphase früh erkannt werden, einfacher und kostengünstiger zu beheben. Hier also die zwei Hauptgründe, Test auf unterster funktionaler Ebene, also in kleinen Units, beim SQL-Server auf der Ebene der stored procedures und functions, durchzuführen.

Die Ausführung von Test wird dabei vorzugsweise von einem Testsystem automatisiert übernommen, das alle vorliegenden Tests bei jedem Testlauf durchführt. Dabei werden auch Module getestet, die für den aktuellen Zeitpunkt keine Neuentwicklung oder Veränderung erfahren haben. So können ungeahnte Seiteneffekte schnell erkannt und rechtzeitig behoben werden.

1.2. Viel Code, wenig Test

Bislang haben sich Unittests für Programmcode in C#, Angular und vielen andern Programmiersprachen etabliert. Ein Schattendasein stellt allerdings SQL-Code dar, der oft nur unzureichend oder überhaupt nicht automatisiert getestet wird. Um die Kosteneffizienz und Qualität von SQL-Code zu verbessern, kann tSQLt als Framework für das Testen eingesetzt werden.

2. Test-Framework tSQLt

2.1. tSQLt

Die Beschreibung zu tSQLt, Beispiele, Tutorials und Download sind zu finden unter https://tsqlt.org

2.2. tSQLt vs. Professionellen Unit-Testing Tools

Derzeit ist eine Reihe von professionellen Datenbank-Testing-Tools auf dem Markt, die einfach und intuitiv zu bedienen sind und eine komfortable GUI-Unterstützung bieten. Allerdings bauen alle der marktführenden Tools auf tSQLt auf und sind was Leistungsfähigkeit, Flexibilität und Abdeckung mit tSQLt direkt vergleichbar.

2.3. Übersicht zu tSQLt

Hier zunächst eine Veranschaulichung der Funktionen:

Abbildung 1 tSQLt-Features

2.3.1. Keine Kontextumschaltung von T-SQL

Die Entwicklung der Tests erfolgt in derselben Sprache, in der auch die Datenbankanwendung geschrieben ist. Hier sind keine weiteren Werkzeuge oder Sprachkenntnisse erforderlich.

2.3.2. Gruppierung von Datenbank-Unit-Tests

Die Unit-Tests sind in Gruppen angeordnet, die bei Bedarf unabhängig voneinander, bedarfs- und testfallabhängig ausgeführt werden können.

​​​​​​​2.3.3. Echte Isolierung der zu testenden Objekte

Ein weiterer wichtiger Punkt bei der Entwicklung von Unit-Tests ist die Isolierung der zu testenden Objekte. Nur durch die Entkoppelung von Daten und Verarbeitungslogik kann der Code unabhängig von der Datenkonstellation getestet werden.

​​​​​​​2.3.4. In Transaktionen ausgeführte Tests

tSQLt führt die Tests in Transaktionen aus, bestehende Daten und Strukturen werden dabei nur temporär verändert und nach Testablauf vollständig wiederhergestellt. D.h. Vorbereitung und Aufräumen übernimmt der Test bzw. das Testframework.
Dennoch wird von Tests auf produktiven Datenbanken abgeraten!

​​​​​​​2.3.5 Unterstützung für kontinuierliche Datenbankintegration (CI)

tSQLt bietet die Integrationsunterstützung für die kontinuierliche Integration und das Deployment von Datenbanken durch DevOps für Datenbanken.

In einfachen Worten: Die in tSQLt geschriebenen Unit-Tests können vollständig automatisiert werden, so dass jede Änderung an der Datenbank, die in die Zielumgebung deployt wird, automatisch die zugehörigen Unit-Tests ausführt.

​​​​​​​2.3.6. Erweiterte SQL-Unit-Tests Unterstützung

tSQLt bietet auch erweiterte SQL-Unit-Testing-Unterstützung, sodass auch datenbankübergreifende Objekte (Datenbankobjekte aus verschiedenen Datenbanken) mit Unit-Test getestet werden können.

 

​​​​​​​2.4. Philosophie der Erstellung und Ausführung von Unit-Tests in tSQLt

Ein Datenbank-Unit-Test basiert auf der AAA-Regel, die aus den folgenden Schritten besteht:

Arrange: Hier werden die am Test teilnehmenden Datenbankobjekte ‚arrangiert‘, die erwarteten Objekte erstellt und die aktuellen Tabellen simuliert (mock).

ACT: Hier wird das zu testende Objekt (stored procedure, function oder view) ausgeführt und die Ergebnisse werden in die gespiegelte aktuelle Tabelle eingetragen.

Assert: Assert ist der letzte Schritt, bei dem die erwarteten Ergebnisse mit den tatsächlichen Ergebnissen verglichen werden und das Testergebnis (bestanden/fehlgeschlagen) protokolliert wird.

3. Beispiele tSQLt

Einfaches Beispiel nach AAA-Prinzip, Testaufruf und Ergebnis

​​​​​​​3.1 Die zu testende Funktion

Dbo.svf_ISOweek() ist eine Funktion ohne äußere Abhängigkeiten zur Ermittlung der Kalenderwoche des übergebenen Datumswertes nach europäischer Norm.

Ziel des Tests: alle Code-Pfade müssen überprüft werden:

  • Normalfall
  • Datum gehört in KW des Vorjahres
  • Datum gehört in KW des Folgejahres

Quellcode der Funktion:

CREATE FUNCTION [dbo].[svf_ISOweek] (@DATE datetime)
RETURNS int
AS
BEGIN
  DECLARE @ISOweek int
 --Normal case
  SET @ISOweek = DATEPART(wk, @DATE) + 1 -
  DATEPART(wk, CAST( DATEPART( yy, @DATE ) AS CHAR(4) ) + '0104' )
  --Jan 1-3 may belong to the previous year
  IF ( @ISOweek = 0 )
  BEGIN
    DECLARE @Date2 datetime
   SET @DATE2 = CAST( DATEPART( yy, @DATE ) - 1 AS CHAR(4) ) +
    '12' + CAST( 24 + DATEPART( DAY, @DATE ) AS CHAR(2) )
    -- rekursiver Aufruf:
    SET @ISOWeek = dbo.svf_ISOweek(@DATE2) + 1
  END

    --Dec 29-31 may belong to the next year
  IF (     ( DATEPART( mm, @DATE ) = 12 )
       AND (( DATEPART( dd, @DATE ) - DATEPART( dw, @DATE) ) >= 28 ))
  BEGIN
    SET @ISOweek=1
  END

    RETURN(@ISOweek)
END

 

​​​​​​​3.2. Eine Test-Klasse erstellen (Gruppe)

Zunächst muss eine ‚Gruppe‘ hier eine Testklasse erstellt werden, zu der ein Testfall gehört:
tSQLT stellt dafür eine Funktion ‚tSQLt.NewTestClass‘ bereit

EXEC tSQLt.NewTestClass "testISOweek"
GO​​​​​​​

3.3. Ein Test-Case

Nun brauchen wir für jeden zu testenden CodePfad bzw. Testfall eine stored procedure:

CREATE PROCEDURE [testISOweek].[test_ISOweek_2021-10-18 is 42]
AS
BEGIN
  -- Arrange
  DECLARE @actualComputedResult INT;
  -- Act
  SET @actualComputedResult = dbo.svf_ISOweek('2021-10-18');
  -- Assert
  EXEC tSQLt.AssertEquals 42, @actualComputedResult;
END;
GO

Namenskonventionen:
‚test_‘              als Namensanfang für das Framework erforderlich.
‚Erläuterung‘    die zu testende Funktion mit Parameter und dem erwarteten Ergebnis.

​​​​​​​3.4 Test ausführen

Die Testausführung erfolgt über den Aufruf EXEC tSQLt.Run
Als Parameter wird hier die Test-Klasse, also der Gruppenname, übergeben.

Das Ergebnis zeigt nun alle „Test-Cases“, deren Laufzeit und das Resultat: ‚Success‘ bedeutet hier, dass die Rückgabe der getesteten Funktion dem erwarteten Ergebnis entspricht.

Alternativ könnte hier auch EXEC tSQLt.RunAll stehen, dann werden alle Tests, die in der DB definiert sind, ausgeführt.

4. Ausblicke

Der hier beschrieben Test einer simplen Funktion ohne äußere Abhängigkeiten zeigt, dass der Aufbau von Testfällen mit tSQLt einfach und komfortabel realisiert werden kann.

Allerdings sind die Funktionen und Prozeduren in unseren Datenbanken normalerweise nicht so einfach gestrickt und weisen Abhängigkeiten auf, greifen auf Tabellen oder Views oder arbeiten mit verschachtelter Verarbeitungslogik und Funktionsaufrufen.

Wie jedoch in tSQLt auch abhängige Funktionen und Prozeduren für einen Test von ihrer Außenwelt isoliert werden können, wird im 2. Teil „Unit Testing für den SQL-Server - Der Schnelleinstieg in die Welt der Tests für den SQL-Server“ genauer betrachtet.

Dieser quiTeq-Tipp kommt von Thomas, QUIBIQ Stuttgart.

Ihre Kontaktmöglichkeiten

Sie haben eine konkrete Frage an uns


 

Bleiben Sie immer auf dem Laufenden


 

Mit meinem "Ja" erkläre ich mich mit der Verarbeitung meiner Daten zur Zusendung von Informationen einverstanden. Ich weiß, dass ich diese Erklärung jederzeit durch einfache Mitteilung widerrufen kann. Bei einem Nein an dieser Stelle erhalte ich zukünftig keine Informationen mehr.

© QUIBIQ GmbH · Impressum · Datenschutz