Få praktisk praksis med testdrevet udvikling i C #

Så lad os tale om TDD - hvad er det?

TDD står for Test Driven Development , og det er en designproces inden for softwareudvikling. Det er afhængig af gentagelsen af ​​en meget kort udviklingscyklus, og kravene bliver til meget specifikke testsager.

Der er et par trin i TDD-processen:

  1. Skriv en enhedstest, der mislykkes.
  2. Skriv nok kode til at få testen bestået - på dette trin er vi ligeglad med god kode.
  3. Refaktor din kode fra det foregående trin.

Hvad er fordelene ved denne tilgang?

Først og fremmest får du en bedre forståelse af den aktuelle kode, før du skriver den. Dette er en af ​​de største fordele ved TDD. Når du først skriver testsagerne, tænker du mere klart om systemkravene og mere kritisk om hjørnesagerne .

Når du taler om afhængigheder , er det også vigtigt at nævne, at arbejde med TDD giver dig mulighed for at fokusere på logikken i dine klasser. På denne måde holder du alle afhængigheder uden for dine klasser. Det er også vigtigt at nævne, at din kode kører mere sikkert, da logikken ikke behøver at håndtere forskelleafhængigheder som databaseforbindelser, filsystemer og så videre.

Det er også en sikrere måde at omlægge koden på. Når du skriver TDD, er der test for et bestemt stykke logik. Når du omlægger koden, kan du muligvis bryde noget, men med denne tilgang ved du, at testene har ryggen.

Når du bruger TDD, har du også en hurtigere måde at forstå, hvad koden gør. Når du begynder at arbejde på et stykke kode, som du ikke er bekendt med, kan du læse testsagerne for det stykke kode og forstå dets formål. Disse tests er også dokumentationen til din kode.

Og endelig kan du fokusere på at bygge de mindre komponenter på den bedste måde og undgå hovedpine i det store billede. Så hvordan hjælper dette? Du skriver en fejlagtig test og fokuserer udelukkende på den for at få den bestået. Det tvinger dig til at tænke på mindre klumper af funktionalitet ad gangen snarere end applikationen som helhed. Derefter kan du gradvist bygge videre på en bestået test i stedet for at prøve at tackle det større billede fra starten, hvilket sandsynligvis vil resultere i flere fejl.

Før vi begynder at skrive TDD ...

For at være ærlig er der flere artikler, hvor du kan læse endnu dybere om TDD. Derfor undgik jeg at skrive hele TDD-teorien her, fordi det ville tage meget lang tid at læse alt.

Derfor forklarede jeg netop den generelle idé og fordelene ved TDD-designprocessen.

Det er tid til at skrive nogle tests, så lad os gøre det

Beskrivelse og krav

Vi bruger C # til at skrive en stakimplementering. Hvorfor C #? Nå, fordi jeg elsker C #, så hvorfor ikke? ?

Så vores krav er ret enkle: vi vil implementere en Stack-klasse, så kravene er:

  1. Begræns størrelsen på stakken.
  2. Tilføj element. (skubbe)
  3. Fjern elementet. (pop)
  4. Kontroller, hvad der var det sidste element. (kig)
  5. Få den aktuelle størrelse på stakken.
  6. Har en klasse, der kan acceptere enhver datatype.
  7. Når kunden overstiger størrelsen på stakken, skal vi kaste en passende undtagelse.

Når vi ved, hvad systemets krav er, kan vi begynde at definere, hvordan vi løser dette. Vi implementerer det ved hjælp af en matrix.

Stakimplementering i TDD - Bygningsinfrastruktur

Jeg bruger visual studio 2017. I det åbner jeg et nyt projekt:

File -> New -> P roject, C hoose Conso le App (.NET Framework).

Vælg et projektnavn - som "Stak".

Nu åbner vi et andet projekt kun for testene, og vi kalder det "StackTests".

Åbn løsningsudforskeren. Vi har et projekt derovre kaldet "Stack". Højreklik nu på Løsning, og vælg Tilføj -> Ny projekt ect og vælg Klassebibliotek (.NET Framework).

Lad os installere vores enhedstest : højreklik på StackTests- projektet, vælg Administrer NuGet-pakker , naviger til "Gennemse" og installer følgende pakker:

  • NUnit
  • NUnit3TestAdapter

Føj en ny klasse til StackTests- projektet, og kald det StackTest. Nu skal løsningen se sådan ud:

Den packages.config skal se sådan ud:

Stakimplementering i TDD - Skriv kode

Vi begynder at udskrive testenheder i StackTests-projektet under StackTest-klassen.

Før vi kan begynde at skrive koden, skal vi lære 3 vigtige ting: TestFixture, Test og Assert.

TestFixture er attributten, der markerer en klasse, der indeholder test og eventuelt opsætnings- eller nedrivningsmetoder.

Den Test attribut er en måde til mærkning af en fremgangsmåde i en TestFixture klasse som en test.

Den Assert klasse er en samling af hjælper klasser at afprøve forskellige betingelser inden unit tests. Hvis betingelsen, der testes, ikke er opfyldt, kastes en undtagelse.

Importer "NUnit.Framework" og sæt attributten [TestFixture] over din klassedefinition.

Oprettelsestest

Okay, det er tid til at skrive vores første funktion. Vi skriver en oprettelsestest, der opretter et nyt objekt i vores stak, og det kontrollerer, at størrelsen på stakken er 0 i starten.

Nu har vi skrevet vores første test, så lad os køre den.

Klik på Test -> Kør -> Alle tests i din værktøjslinje .

Hvis din Test Explorer ikke åbnes, skal du klikke på Test -> Windows -> Test eksplorer, og dette udvider testudforskeren.

Som du kan se, har vi ikke engang vores Stack-klasse defineret, så vi får en kompileringsfejl. Lad os nu skrive nok kode til at få testen bestået.

Lad os lave vores første testarbejde:

  • Opret en ny klasse i Stack-projektet , og kald denne klasse "Stack". Gør denne klasse til en generisk type klasse (T-type).
  • Vi definerede denne klasse (Stack), der skal gennemføres som en matrix, derfor vil vi definere medlem felt som en vifte af type T .
  • Vi skal passere den maksimale længde af stakken ved konstruktøren, derfor opretter vi en konstruktør, der tager et størrelsesargument.
  • Og da vi kræver, at vi modtager den aktuelle størrelse af stakken til enhver tid, definerer vi en egenskab med "Størrelse". Naturligvis vil ingen være i stand til at ændre størrelsen, derfor vil det være et privat sæt .

Lad os nu køre testene igen (se ovenfor, hvordan du kører tests) og se resultaterne.

Og der går vi, vi har lavet vores første iteration med TTD-design! Nu skal vi omformulere vores kode - men på dette tidspunkt har vi ikke rigtig noget at refaktorere, så vi går videre.

Push & Pop test

Nu vil vi teste push- og pop-funktionalitet, så lad os oprette testcase.

  • Push tager et argument og tilføjer det til toppen af ​​stakken.
  • Pop fjerner elementet fra stakken og returnerer det.

Vi tilføjer 3 elementer til stakken, så tager vi det sidste element ud. På dette tidspunkt vil vi kontrollere, at det sidste element er det nøjagtige, som vi forventer at få, og at stakkens størrelse faldt.

Som du kan se, findes der ikke engang push- og pop-funktioner, så når vi kører tests, får vi en fejl i vorestest resultater. Lad os gå til Stack-klassen og implementere dem.

Lad os køre vores tests igen, og boom, alt fungerer perfekt! Alle test bestået med succes?

Fejl ved overskridelse af den tilladte størrelse

Vi vil kaste brugerdefinerede undtagelser, når vi:

  1. Skub nyt element, når stakken er fuld.
  2. Popelement, når der ikke er nogen elementer i stakken.

Så som du allerede ved ... hvad skal vi gøre nu?

Korrekt! Vi definerer testsager, og så får vi koden til at fungere.

Som du kan se, er vi nødt til at oprette to nye brugerdefinerede undtagelser.

  • ExpenditureProhibitedException - Denne undtagelse opstår, når stakken er tom, og klienten forsøger at poppe et nyt element ud.
  • ExceededSizeException - Denne undtagelse opstår, når stakken er fuld, og klienten forsøger at tilføje et nyt element til stakken.

Gå til Stack Project, og opret en ny klasse kaldet CustomExceptions. I denne klasse definerer vi vores nye undtagelser, og de arver fra klassen Undtagelse.

Rediger vores nuværende push- og pop-funktionalitet for at give en undtagelse, når det er nødvendigt.

Så nu, som en del af TDD's livscyklus, kører vi testene ... og Hurra! Alle prøver er bestået med succes.

Kig det sidste element

Vi er ved at afslutte med de sidste tests. Vi vil kigge på det sidste element i stakken. Hvis stakken er tom, kaster vi en ExpenditureProhibitedException-undtagelse, ellers returnerer vi det sidste element.

Lad os oprette vores testcases.

  1. Forsøg at kigge på elementet, når stakken er tom. I denne test kaster vi en brugerdefineret undtagelse.
  2. Indsæt nogle elementer i stakken, kig derefter et element, sørg for at dette er det rigtige element, og kontroller at matrixstørrelsen ikke er ændret.

Når vi kører testene, vil de mislykkes - peek-metoden findes ikke engang, og der er ingen funktionalitet.

Vi opretter funktionen Peek at Stack-klassen .

Nu når vi kører testene igen, kan vi se, at de alle gennemføres med succes.

Afslutningsvis

Som du kan se, er ideen ikke kompliceret, og der er mange værktøjer, der hjælper med at implementere TDD-principperne.

Du kan se hele koden på Pastebin.

Stack-klasse - Denne klasse indeholder alle implementeringer af stack.

StackTests-klasse - Indeholder alle testcases.

CustomException-klasser - Indeholder de undtagelser, systemet kræves til TDD-design.

Hver kommentar og al feedback er velkommen - hvis det er nødvendigt, løser jeg artiklen.

Du er velkommen til at kontakte mig direkte på LinkedIn - Klik her.