Hvordan TDD en listeimplementering i Java

1. Oversikt

I denne opplæringen går vi gjennom en tilpasset Liste implementering ved hjelp av TDD-prosessen (Test-Driven Development).

Dette er ikke en intro til TDD, så vi antar at du allerede har en grunnleggende ide om hva det betyr og den vedvarende interessen for å bli bedre på det.

For å si det enkelt, TDD er et designverktøy som gjør det mulig for oss å drive implementeringen ved hjelp av tester.

En rask ansvarsfraskrivelse - vi fokuserer ikke på å skape effektiv implementering her - bare bruker den som en unnskyldning for å vise TDD-praksis.

2. Komme i gang

La oss først definere skjelettet for klassen vår:

offentlig klasse CustomList implementerer List {private Object [] internal = {}; // tomme implementeringsmetoder} 

De CustomList klasse implementerer Liste grensesnitt, derfor må den inneholde implementeringer for alle metodene som er angitt i grensesnittet.

For å komme i gang kan vi bare skaffe tomme kropper for disse metodene. Hvis en metode har en returtype, kan vi returnere en vilkårlig verdi av den typen, for eksempel null til Gjenstand eller falsk til boolsk.

For korthets skyld vil vi utelate valgfrie metoder, sammen med noen obligatoriske metoder som ikke ofte brukes.

3. TDD Sykler

Å utvikle implementeringen vår med TDD betyr at vi trenger det lage testtilfeller først, og definerer derved krav til vår implementering. Kun så oppretter eller fikser vi implementeringskoden for å få testene bestått.

På en veldig forenklet måte er de tre hovedtrinnene i hver syklus:

  1. Skrivetester - definere krav i form av tester
  2. Implementeringsfunksjoner - få testene til å bestå uten å fokusere for mye på kodens eleganse
  3. Refactoring - forbedre koden for å gjøre det lettere å lese og vedlikeholde mens du fortsatt består testene

Vi vil gå gjennom disse TDD-syklusene for noen metoder for Liste grensesnitt, og starter med de enkleste.

4. Den er tom Metode

De er tom metoden er trolig den mest enkle metoden som er definert i Liste grensesnitt. Her er vår første implementering:

@Override public boolean isEmpty () {return false; }

Denne innledende metodedefinisjonen er nok til å kompilere. Kroppen til denne metoden vil bli “tvunget” til å forbedre seg når flere og flere tester blir lagt til.

4.1. Den første syklusen

La oss skrive den første prøvesaken som sørger for at er tom metoden returnerer ekte når listen ikke inneholder noe element:

@Test offentlig ugyldig givenEmptyList_whenIsEmpty_thenTrueIsReturned () {List list = new CustomList (); assertTrue (list.isEmpty ()); }

Den gitte testen mislykkes siden er tom metoden returnerer alltid falsk. Vi kan få det til å passere bare ved å snu returverdien:

@Override offentlig boolsk isEmpty () {return true; }

4.2. Den andre syklusen

For å bekrefte at er tom metoden returnerer falsk når listen ikke er tom, må vi legge til minst ett element:

@Test public void givenNonEmptyList_whenIsEmpty_thenFalseIsReturned () {List list = new CustomList (); list.add (null); assertFalse (list.isEmpty ()); }

En implementering av legge til metoden er nå nødvendig. Her er legge til metoden vi starter med:

@ Override public boolean add (E element) {return false; }

Denne metodeimplementeringen fungerer ikke da det ikke gjøres noen endringer i den interne datastrukturen i listen. La oss oppdatere den for å lagre elementet som er lagt til:

@ Override public boolean add (E element) {internal = new Object [] {element}; returner falsk; }

Testen vår mislykkes fremdeles siden er tom metoden har ikke blitt forbedret. La oss gjøre det:

@Override public boolean isEmpty () {if (internal.length! = 0) {return false; } annet {returner sant; }}

Den ikke-tomme testen består på dette tidspunktet.

4.3. Refactoring

Begge testsakene vi har sett så langt, passerer, men koden til er tom metoden kan være mer elegant.

La oss omformulere det:

@Override offentlig boolsk isEmpty () {return internal.length == 0; }

Vi kan se at testene består, så implementeringen av er tom metoden er fullført nå.

5. Den størrelse Metode

Dette er vår første implementering av størrelse metode som muliggjør CustomList klasse å kompilere:

@ Override public int size () {return 0; }

5.1. Den første syklusen

Bruke det eksisterende legge til metoden, kan vi lage den første testen for størrelse metode, og verifiserer at størrelsen på en liste med et enkelt element er 1:

@Test offentlig ugyldig givenListWithAnElement_whenSize_thenOneIsReturned () {List list = new CustomList (); list.add (null); assertEquals (1, list.size ()); }

Testen mislykkes som den størrelse metoden er tilbake 0. La oss få det til å passere med en ny implementering:

@Override public int size () {if (isEmpty ()) {return 0; } annet {returner intern. lengde; }}

5.2. Refactoring

Vi kan refaktorere størrelse metode for å gjøre det mer elegant:

@Override public int size () {return internal.length; }

Implementeringen av denne metoden er nå fullført.

6. Den Metode

Her er den første implementeringen av :

@ Override public E get (int index) {return null; }

6.1. Den første syklusen

La oss ta en titt på den første testen for denne metoden, som verifiserer verdien av det enkelte elementet i listen:

@Test offentlig ugyldig givenListWithAnElement_whenGet_thenThatElementIsReturned () {List list = new CustomList (); list.add ("baeldung"); Objektelement = list.get (0); assertEquals ("baeldung", element); }

Testen vil bestå med denne implementeringen av metode:

@ Overstyr offentlig E get (int-indeks) {retur (E) intern [0]; }

6.2. Forbedring

Vanligvis vil vi legge til flere tester før vi gjør ytterligere forbedringer av metode. Disse testene vil trenge andre metoder for Liste grensesnitt for å implementere riktige påstander.

Imidlertid er disse andre metodene ikke modne nok, så vi bryter TDD-syklusen og lager en fullstendig implementering av metode, som faktisk ikke er veldig vanskelig.

Det er lett å forestille seg det må trekke ut et element fra innvendig array på det angitte stedet ved hjelp av indeks parameter:

@ Overstyr offentlig E get (int-indeks) {retur (E) intern [indeks]; }

7. Den legge til Metode

Dette er legge til metoden vi opprettet i seksjon 4:

@ Override public boolean add (E element) {internal = new Object [] {element}; returner falsk; }

7.1. Den første syklusen

Følgende er en enkel test som verifiserer returverdien av legge til:

@Test public void givenEmptyList_whenElementIsAdded_thenGetReturnsThatElement () {List list = new CustomList (); boolsk vellykket = list.add (null); assertTrue (lykkes); }

Vi må endre legge til metode for å returnere ekte for at testen skal bestå:

@ Override public boolean add (E element) {internal = new Object [] {element}; returner sant; }

Selv om testen består, legge til metoden dekker ikke alle tilfeller ennå. Hvis vi legger til et annet element i listen, vil det eksisterende elementet gå tapt.

7.2. Den andre syklusen

Her er en annen test som legger til kravet om at listen kan inneholde mer enn ett element:

@Test offentlig ugyldig givenListWithAnElement_whenAnotherIsAdded_thenGetReturnsBoth () {List list = new CustomList (); list.add ("baeldung"); list.add (". com"); Objekt element1 = list.get (0); Objekt element2 = list.get (1); assertEquals ("baeldung", element1); assertEquals (". com", element2); }

Testen vil mislykkes siden legge til metoden i sin nåværende form tillater ikke at mer enn ett element legges til.

La oss endre implementeringskoden:

@ Override public boolean add (E element) {Object [] temp = Arrays.copyOf (intern, intern.lengde + 1); temp [intern.lengde] = element; intern = temp; returner sant; }

Gjennomføringen er elegant nok, derfor trenger vi ikke å omformulere den.

8. Konklusjon

Denne opplæringen gikk gjennom en testdrevet utviklingsprosess for å lage en del av en tilpasset Liste gjennomføring. Ved hjelp av TDD kan vi implementere kravene trinn for trinn, samtidig som vi holder testdekningen på et veldig høyt nivå. Implementeringen er garantert testbar, siden den ble opprettet for å få testene til å bestå.

Vær oppmerksom på at den tilpassede klassen som er opprettet i denne artikkelen, bare brukes til demonstrasjonsformål og ikke bør vedtas i et virkelig prosjekt.

Den komplette kildekoden for denne opplæringen, inkludert test- og implementeringsmetoder som er utelatt for kortfattethet, finner du på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found