Design og implementér en teststrategi

Fuldført

Et SQL-databaseprojekt, der bygger succesfuldt, betyder ikke, at de lagrede procedurer indeni det returnerer de rigtige resultater. En procedure kan kompilere uden fejl og stadig beregne de forkerte totaler eller springe en valideringskontrol over. Test opdager disse problemer, før de når produktionen.

Forstå databasetestniveauer

Databasetest fungerer i lag, hvor hvert lag fanger en forskellig klasse af problemer:

  • Build-validering er det dotnet build skridt, du allerede har. Den fanger syntaksfejl og ødelagte objektreferencer. Hurtigt, men det beviser kun, at skemaet er strukturelt gyldigt.
  • Enhedstests verificerer, at individuelle lagrede procedurer og funktioner giver de rigtige resultater for et givent sæt input. De opdager logiske fejl.
  • Integrationstests udfører end-to-end scenarier mod en deployeret database. De beviser, at objekter fungerer korrekt sammen, men de kræver en kørende instans og tager mest tid.

Hvert lag er langsommere og dyrere end det forrige, men fanger også problemer, som det forrige lag ikke kan.

Opret SQL Server enhedstests

SQL Server Data Tools (SSDT) i Visual Studio inkluderer en indbygget ramme til databaseenhedstests. Hver test udfører T-SQL mod en live database og validerer resultaterne ved hjælp af testbetingelser.

Struktur af en enhedstest

Hver test har tre sektioner, der følger et setup-execute-cleanup-mønster:

  • Fortest: opsæt de data, testen har brug for. Indsæt kundeposter, ryd resterende data fra tidligere kørsler.
  • Test: udfør den operation, du tester. Kald den lagrede procedure og forespørg visningen.
  • Efter testen: ryd op efter testen, så det ikke forurener næste runde.

Testforhold

Efter testen kører T-SQL, validerer testbetingelserne det, der kom tilbage. De mest almindeligt anvendte betingelser er:

  • Rækkeantal: verificerer, at resultatsættet indeholder det forventede antal rækker.
  • Skalar værdi: verificerer, at en specifik celle i resultatsættet indeholder forventet værdi.
  • Forventet skema: verificerer, at resultatsættet har de forventede kolonnenavne og datatyper.

Andre indbyggede betingelser inkluderer Data Checksum, Empty ResultSet, Not Empty ResultSet og Execution Time.

Opret et enhedstestprojekt

Opsætning af SQL Server enhedstests i Visual Studio kræver et par trin:

  1. Åbn dit SQL-databaseprojekt.
  2. I SQL Server Object Explorer skal du finde den lagrede procedure eller funktion, du vil teste.
  3. Højreklik på objektet og vælg Opret enhedstests.
  4. Vælg eller opret et C#-testprojekt.
  5. Sæt testforbindelsen til din udviklingsdatabase.
  6. Vælg Automatisk udrul databaseprojektet, før enhedstests køres. Denne mulighed holder testdatabasen synkroniseret med dine seneste projektændringer.

Designeren åbner med en T-SQL-skabelon, hvor du skriver din testlogik og vedhæfter testbetingelser.

Skriv effektive databaseenhedstests

En god enhedstest besvarer et specifikt spørgsmål: "Gør denne procedure det, den skal for et kendt input?" Her er et eksempel, der tester uspPlaceNewOrder, og verificerer, at korrekt afgivelse af en ordre opdaterer kundens samlede antal for år til dato:

-- Pre-test: Set up customer and clear previous data
DECLARE @CustomerID INT;
INSERT INTO [Sales].[Customer] (CustomerName) VALUES (N'Test Customer');
SET @CustomerID = SCOPE_IDENTITY();
DELETE FROM [Sales].[Orders] WHERE [CustomerID] = @CustomerID;

-- Test: Place an order and verify YTDOrders updated correctly
DECLARE @RC INT;
EXECUTE @RC = [Sales].[uspPlaceNewOrder] @CustomerID, 100, GETDATE(), 'O';

SELECT [YTDOrders]
FROM [Sales].[Customer]
WHERE [CustomerID] = @CustomerID;

📝 Parr denne test T-SQL med en Skalar Værdi testbetingelse, der forventer, at værdien YTDOrders er 100.

Negative tests

Du skal også verificere, at lagrede procedurer fejler korrekt, når de modtager ugyldige input. For eksempel bør annullering af en ordre, der allerede er sendt, give en fejl, ikke lykkes uden at det sker. En negativ test bekræfter, at den forventede fejl opstår.

Når du vælger Opret enhedstests i trin 3 i den forrige sektion, genererer Visual Studio et C#-testprojekt i Solution Explorer med en .cs fil, der indeholder en test for hver gemt procedure, du har valgt. For eksempel, hvis du oprettede en test for uspCancelOrder, indeholder den genererede fil en sektion kaldet Sales_uspCancelOrder_Test. For at markere testen som negativ, åbn .cs filen i Solution Explorer og tilføj attributten ExpectedSqlException direkte over den og gem filen:

[TestMethod()]
[ExpectedSqlException(Severity = 16, MatchFirstError = false, State = 1)]
public void Sales_uspCancelOrder_FilledOrder_Test()

Testen består kun, når den lagrede procedure giver en fejl, der matcher den specificerede sværhedsgrad og tilstand. Hvis proceduren lykkes stille, fejler testen, hvilket er præcis det, du ønsker.

Design en integrationstestmetode

Enhedstests isolerer individuelle objekter. Integrationstests går videre og tester scenarier, der spænder over flere operationer. De besvarer spørgsmål som:

  • Efterlader en sekvens af stored procedure-kald databasen i den forventede tilstand?
  • Udløses triggere korrekt, når data ankommer gennem applikationslaget?
  • Giver visninger nøjagtige resultater efter en række relaterede tabelændringer?

Integrationstests kræver en dedikeret database. Udrul SQL-databaseprojektet til en testinstans før hver kørsel ved at bruge indstillingen Automatisk deploy databaseprojektet før enhedstests køres . Denne indstilling holder testskemaet opdateret.

Overvejelser for testdatabaser

Både enhedstests og integrationstests kører T-SQL mod en live database, så testmiljøet kræver omhyggelig opsætning for at levere pålidelige resultater.

  • Isoler tests fra produktionen. Brug en separat instans eller dedikeret testdatabase. Det anbefales aldrig at køre tests mod produktionen.
  • Nulstil til en kendt tilstand før hver gennemspilning. Post-deployment scripts eller testoprydningsscripts håndterer dette problem.
  • Eksternaliser forbindelsesstrenge i konfigurationsfiler, så lokal udvikling og CI-pipelines hver især peger til den rigtige database uden kodeændringer.

Integrer tests i CI/CD-pipelines

Tilføj et testtrin efter build og deployment, så tests kører automatisk på hver commit. I Azure DevOps bruger du opgaven VSTest :

- task: VSTest@2
  inputs:
    testAssembly: '**\*Tests.dll'
    searchFolder: '$(System.DefaultWorkingDirectory)'

I GitHub Actions kør testene ved at bruge dotnet test:

- name: Run database unit tests
  run: dotnet test ./DatabaseTests/DatabaseTests.csproj

Tips

Konfigurér testprojektet til automatisk at udrulle databaseprojektet, før testene kører. Denne indstilling sikrer, at testdatabaseskemaet matcher projektet på testtidspunktet.

Når en test fejler, stopper pipelinen, og ændringen når ikke frem til staging eller produktion. Denne forsinkelse giver teamet tid til at løse problemet, før det påvirker noget miljø.

Vigtige takeaways

Databasetest spænder over tre niveauer: opbygningsvalidering for strukturel korrekthed, enhedstests til logikverifikation og integrationstests for end-to-end arbejdsgange. SQL Server-enhedstests følger en trefasestruktur med testpreactions, testhandlinger og testefterhandlinger. For at verificere lagret procedure og funktionsadfærd bruges testbetingelser som Scalar Value, Row Count, og Expected Schema. For at teste metoder, der skal validere fejlhåndteringsstier, tilføj attributten ExpectedSqlException . Wire test projekter ind i din CI/CD-pipeline, så en fejlende test blokerer deploymenten, før ændringerne når staging eller produktion. Sammen udgør disse tre lag et sikkerhedsnet, der gør det muligt for dit team at implementere databaseændringer med selvtillid i stedet for nervøsitet.