Kako TDD implementirati popis u Javi

1. Pregled

U ovom uputstvu proći ćemo kroz običaj Popis implementacija pomoću procesa vođenog testom (TDD).

Ovo nije uvod u TDD, pa pretpostavljamo da već imate osnovnu ideju o tome što to znači i trajni interes za poboljšanje.

Jednostavno rečeno, TDD je alat za dizajn koji nam omogućuje da provedbu implementiramo uz pomoć testova.

Brza izjava o odricanju odgovornosti - ovdje se ne fokusiramo na stvaranje učinkovite implementacije - već je koristimo kao izgovor za prikaz TDD praksi.

2. Početak rada

Prvo, definirajmo kostur za našu klasu:

javna klasa CustomList provodi List {private Object [] internal = {}; // prazne metode implementacije} 

The CustomList razred provodi Popis sučelje, stoga mora sadržavati implementacije za sve metode deklarirane u tom sučelju.

Za početak možemo pružiti prazna tijela za te metode. Ako metoda ima povratni tip, možemo vratiti proizvoljnu vrijednost tog tipa, kao što je null za Objekt ili lažno za boolean.

Radi kratkoće izostavit ćemo neobavezne metode, zajedno s nekim obveznim metodama koje se često ne koriste.

3. TDD ciklusi

Razvoj naše implementacije s TDD-om znači da to trebamo prvo stvorite test slučajeve, definirajući time zahtjeve za našu provedbu. Samo tada ćemo stvoriti ili popraviti implementacijski kod kako bi ti testovi prošli.

Na vrlo pojednostavljen način, tri glavna koraka u svakom ciklusu su:

  1. Testovi pisanja - definirati zahtjeve u obliku testova
  2. Provedbene značajke - neka testovi prođu bez previše fokusiranja na eleganciju koda
  3. Refaktoriranje - poboljšati kôd kako bi ga bilo lakše čitati i održavati dok još uvijek prolazite testove

Proći ćemo kroz ove TDD cikluse za neke metode Popis sučelje, počevši od onih najjednostavnijih.

4. The prazno je Metoda

The prazno je metoda je vjerojatno najjednostavnija metoda definirana u Popis sučelje. Evo naše početne implementacije:

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

Ova početna definicija metode dovoljna je za sastavljanje. Tijelo ove metode bit će "prisiljeno" poboljšati se kad se doda sve više i više testova.

4.1. Prvi ciklus

Napišimo prvi test koji osigurava da prazno je metoda se vraća pravi kada popis ne sadrži nijedan element:

@Test javna praznina givenEmptyList_whenIsEmpty_thenTrueIsReturned () {Popis popisa = novi CustomList (); assertTrue (list.isEmpty ()); }

Dati test ne uspijeva od prazno je metoda se uvijek vraća lažno. Možemo ga proći samo okretanjem povratne vrijednosti:

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

4.2. Drugi ciklus

Da bi potvrdio da prazno je metoda se vraća lažno kada popis nije prazan, moramo dodati barem jedan element:

@Test javna praznina givenNonEmptyList_whenIsEmpty_thenFalseIsReturned () {Popis popisa = novi CustomList (); list.add (null); assertFalse (list.isEmpty ()); }

Provedba dodati sada je potrebna metoda. Evo dodati metodu započinjemo sa:

@Preuzmi javni logički dodatak (E element) {return false; }

Ova implementacija metode ne radi jer se ne vrše promjene u unutarnjoj strukturi podataka popisa. Ažurirajmo ga da pohrani dodani element:

@Override javni logički dodatak (E element) {interni = novi objekt [] {element}; return false; }

Naš test još uvijek ne uspijeva od prazno je metoda nije poboljšana. Učinimo to:

@Override public boolean isEmpty () {if (internal.length! = 0) {return false; } else {vratiti true; }}

U ovom trenutku test koji nije prazan prolazi.

4.3. Refaktoriranje

Oba testna slučaja koja smo do sada vidjeli prolaze, ali kôd prazno je metoda mogla biti elegantnija.

Refaktoriziramo:

@Override public boolean isEmpty () {return internal.length == 0; }

Vidimo da testovi prolaze, pa je primjena prazno je metoda je sada gotova.

5. The veličina Metoda

Ovo je naša početna provedba veličina metoda koja omogućuje CustomList klasa za sastavljanje:

@Preuzmi javnu int veličinu () {return 0; }

5.1. Prvi ciklus

Koristeći postojeće dodati metodom, možemo stvoriti prvi test za veličina metodom, kojom se provjerava je li veličina popisa s jednim elementom 1:

@Test javna praznina givenListWithAnElement_whenSize_thenOneIsReturned () {Popis popisa = novi CustomList (); list.add (null); assertEquals (1, list.size ()); }

Test ne uspijeva kao veličina metoda se vraća 0. Učinimo da to prođe novom implementacijom:

@Preuzmi javnu int veličinu () {if (isEmpty ()) {return 0; } else {return internal.length; }}

5.2. Refaktoriranje

Možemo refaktorizirati veličina metoda kako bi je učinili elegantnijom:

@Preuzmi javnu int veličinu () {return internal.length; }

Provedba ove metode je sada dovršena.

6. The dobiti Metoda

Evo početne implementacije dobiti:

@Preuzmi javno E get (int index) {return null; }

6.1. Prvi ciklus

Pogledajmo prvi test za ovu metodu koji provjerava vrijednost pojedinačnog elementa na popisu:

@Test javna praznina givenListWithAnElement_whenGet_thenThatElementIsReturned () {Popis popisa = novi CustomList (); list.add ("baeldung"); Element objekta = list.get (0); assertEquals ("baeldung", element); }

Test će proći s ovom provedbom dobiti metoda:

@Preuzmi javni E get (int index) {return (E) internal [0]; }

6.2. Poboljšanje

Obično bismo dodali više testova prije nego što učinimo dodatna poboljšanja dobiti metoda. Za te testove trebale bi druge metode Popis sučelje za provedbu ispravnih tvrdnji.

Međutim, ove druge metode još nisu dovoljno zrele, pa prekidamo TDD ciklus i stvaramo cjelovitu implementaciju dobiti metoda, koja zapravo nije jako teška.

Lako je to zamisliti dobiti mora izvući element iz unutarnja polje na navedenom mjestu pomoću indeks parametar:

@Preuzmi javni E get (int index) {return (E) internal [index]; }

7. The dodati Metoda

Ovo je dodati metoda koju smo stvorili u odjeljku 4:

@Override javni logički dodatak (E element) {interni = novi objekt [] {element}; return false; }

7.1. Prvi ciklus

Slijedi jednostavan test kojim se provjerava povratna vrijednost dodati:

@Test javna praznina givenEmptyList_whenElementIsAdded_thenGetReturnsThatElement () {Popis popisa = novi CustomList (); logička vrijednost uspjela = list.add (null); assertTrue (uspjelo); }

Moramo izmijeniti dodati metoda za povratak pravi za polaganje testa:

@Override javni logički dodatak (E element) {interni = novi objekt [] {element}; povratak istinit; }

Iako test prolazi, dodati metoda još ne pokriva sve slučajeve. Ako na popis dodamo drugi element, postojeći će se element izgubiti.

7.2. Drugi ciklus

Evo još jednog testa koji dodaje zahtjev da popis može sadržavati više od jednog elementa:

@Test javna praznina givenListWithAnElement_whenAnotherIsAdded_thenGetReturnsBoth () {Popis popisa = novi CustomList (); list.add ("baeldung"); list.add (".com"); Element objekta1 = list.get (0); Objekt element2 = list.get (1); assertEquals ("baeldung", element1); assertEquals (". com", element2); }

Test neće uspjeti od dodati metoda u trenutnom obliku ne dopušta dodavanje više od jednog elementa.

Promijenimo kod za implementaciju:

@Override javni logički dodatak (E element) {Object [] temp = Arrays.copyOf (internal, internal.length + 1); temp [unutarnja.duljina] = element; interno = temp; povratak istinit; }

Implementacija je dovoljno elegantna, stoga je ne moramo refaktorirati.

8. Zaključak

Ovaj je vodič prošao testni razvojni proces da bi stvorio dio prilagođenog Popis provedba. Korištenjem TDD-a možemo korak po korak implementirati zahtjeve, istovremeno održavajući pokrivenost testom na vrlo visokoj razini. Također, zajamčeno je da će se provjera testirati, jer je stvorena kako bi testovi prošli.

Imajte na umu da se prilagođena klasa kreirana u ovom članku koristi samo u demonstracijske svrhe i ne bi je trebalo usvojiti u stvarnom projektu.

Cjeloviti izvorni kod za ovaj vodič, uključujući izostavljene metode testiranja i implementacije radi kratkoće, možete pronaći na GitHub-u.