Når skriver du den "ekte" koden i TDD?

johnny 08/19/2017. 11 answers, 20.464 views
tdd

Alle eksemplene jeg har lest og sett på treningsvideoer har enkle eksempler. Men det jeg ikke ser om hvordan jeg gjør den "ekte" koden etter at jeg blir grønn. Er dette "Refactor" -delen?

Hvis jeg har et ganske komplisert objekt med en kompleks metode, og jeg skriver min test og det minste minimum for å få det til å passere (etter at det først feilet, Rødt). Når går jeg tilbake og skriver den virkelige koden? Og hvor mye ekte kode skriver jeg før jeg prøver? Jeg gjetter at den siste er mer intuisjon.

Edit: Takk til alle som svarte. Alle svarene hjalp meg enormt. Det synes å være forskjellige ideer om hva jeg spurte eller forvirret om, og kanskje det er, men det jeg spurte var, sier jeg har en søknad om å bygge en skole.

I mitt design har jeg en arkitektur jeg vil starte med, User Stories, og så videre og så videre. Herfra tar jeg de brukerhistoriene, og jeg lager en test for å teste brukerhistorien. Brukeren sier at vi har folk tilmeldt skolen og betaler registreringsavgift. Så, jeg tenker på en måte å gjøre det mislykkes. Ved å gjøre det, designer jeg en testklasse for klasse X (kanskje student), som vil mislykkes. Jeg lager deretter klassen "Student". Kanskje "Skole" vet jeg ikke.

Men i hvert fall tvinger TD Design meg til å tenke gjennom historien. Hvis jeg kan få en testfeil, vet jeg hvorfor det feiler, men dette forutsetter at jeg kan få det til å passere. Det handler om design.

Jeg ligner dette på å tenke på Rekursjon. Rekursjon er ikke et hardt konsept. Det kan være vanskeligere å faktisk holde styr på det i hodet ditt, men i virkeligheten er det vanskeligste å vite når rekursjonen "bryter" når skal stoppe (min mening, selvfølgelig.) Så jeg må tenke på hva som stopper Rekursjonen først. Det er bare en ufullkommen analogi, og det antas at hver rekursiv iterasjon er et "pass". Igjen, bare en mening.

I gjennomføringen er skolen vanskeligere å se. Numeriske og banktransaksjoner er "enkle" i den forstand at du kan bruke enkel aritmetikk. Jeg kan se a + b og returnere 0, etc. I tilfelle av et system av mennesker, må jeg tenke hardere på hvordan å implement det. Jeg har begrepet svikt, pass, refactor (hovedsakelig på grunn av studier og dette spørsmålet.)

Det jeg ikke vet er basert på mangel på erfaring, etter min mening. Jeg vet ikke hvordan jeg skal melde meg på en ny student. Jeg vet ikke hvordan jeg skal mislykkes noen som skriver inn etternavn, og det blir lagret i en database. Jeg vet hvordan jeg lager en + 1 for enkel matte, men med enheter som en person vet jeg ikke om jeg bare tester for å se om jeg får tilbake en database unikt ID eller noe annet når noen går inn i et navn i en database eller begge deler eller heller ikke.

Eller kanskje dette viser at jeg fortsatt er forvirret.

5 Comments
187 hobbs 07/25/2017
Etter at TDD-folkene går hjem for natten.
14 Goyo 07/25/2017
Hvorfor tror du at koden du skrev, ikke er ekte?
2 johnny 07/26/2017
@RubberDuck Mer enn de andre svarene gjorde. Jeg er sikker på at jeg snart vil referere til det. Det er fortsatt litt utenlandsk, men jeg skal ikke gi opp det. Det du sa var fornuftig. Jeg prøver bare å gjøre det fornuftig i min sammenheng eller en vanlig forretningsapplikasjon. Kanskje et lager system eller lignende. Jeg må vurdere det. Jeg er takknemlig for tiden din skjønt. Takk.
1 Edmund Reed 07/26/2017
Svarene har allerede truffet neglen på hodet, men så lenge alle tester går forbi, og du ikke trenger noen nye tester / funksjonalitet, kan det antas at koden du har er ferdig, strykes linting.
3 Borjab 07/26/2017
Det er en asumption i spørsmålet som kan være problematisk i "Jeg har et ganske komplisert objekt med en kompleks metode". I TDD skriver du testene først, slik at du starter med en ganske enkel kode. Dette vil tvinge deg til å kode en testvennlig struktur som må moduleres. Så komplisert oppførsel vil bli opprettet ved å kombinere enklere objekter. Hvis du slutter med et ganske komplisert objekt eller metode, så er det når du refactor

11 Answers


RubberDuck 07/27/2017.

Hvis jeg har et ganske komplisert objekt med en kompleks metode, og jeg skriver min test og det minste minimum for å få det til å passere (etter at det først feilet, Rødt). Når går jeg tilbake og skriver den virkelige koden? Og hvor mye ekte kode skriver jeg før jeg prøver? Jeg gjetter at den siste er mer intuisjon.

Du "ikke gå tilbake" og skrive "ekte kode". Det er all ekte kode. Det du gjør er å gå tilbake og legge til en annen test som forces deg til å change koden din for å få den nye testen til å passere.

Når det gjelder hvor mye kode skriver du før du testet? Ingen. Du skriver zero kode uten en feil test som forces deg til å skrive mer kode.

Legg merke til mønsteret?

La oss gå gjennom (et annet) enkelt eksempel i håp om at det hjelper.

 Assert.Equal("1", FizzBuzz(1)); 

Lett peazy.

 public String FizzBuzz(int n) {
    return 1.ToString();
} 

Ikke hva du vil kalle ekte kode, ikke sant? La oss legge til en test som tvinger en forandring.

 Assert.Equal("2", FizzBuzz(2)); 

Vi kunne gjøre noe dumt som if n == 1 , men vi hopper over til den rene løsningen.

 public String FizzBuzz(int n) {
    return n.ToString();
} 

Kul. Dette vil fungere for alle ikke-FizzBuzz-numre. Hva er neste inngang som vil tvinge produksjonskoden til å endres?

 Assert.Equal("Fizz", FizzBuzz(3));

public String FizzBuzz(int n) {
    if (n == 3)
        return "Fizz";
    return n.ToString();
} 

Og igjen. Skriv en test som ikke vil passere ennå.

 Assert.Equal("Fizz", FizzBuzz(6));

public String FizzBuzz(int n) {
    if (n % 3 == 0)
        return "Fizz";
    return n.ToString();
} 

Og vi har nå dekket alle flertallene av tre (det er ikke mange ganger fem, vi merker det og kommer tilbake).

Vi har ikke skrevet en test for "Buzz" ennå, så la oss skrive det.

 Assert.Equal("Buzz", FizzBuzz(5));

public String FizzBuzz(int n) {
    if (n % 3 == 0)
        return "Fizz";
    if (n == 5)
        return "Buzz"
    return n.ToString();
} 

Og igjen, vi vet at det er et annet tilfelle vi må håndtere.

 Assert.Equal("Buzz", FizzBuzz(10));

public String FizzBuzz(int n) {
    if (n % 3 == 0)
        return "Fizz";
    if (n % 5 == 0)
        return "Buzz"
    return n.ToString();
} 

Og nå kan vi håndtere alle multipler av 5 som ikke er også multipliser med 3.

Frem til dette punktet har vi ignorert refactoring-trinnet, men jeg ser litt duplisering. La oss rydde opp nå.

 private bool isDivisibleBy(int divisor, int input) {
    return (input % divisor == 0);
}

public String FizzBuzz(int n) {
    if (isDivisibleBy(3, n))
        return "Fizz";
    if (isDivisibleBy(5, n))
        return "Buzz"
    return n.ToString();
} 

Kul. Nå har vi fjernet dupliseringen og opprettet en velkalt funksjon. Hva er neste test vi kan skrive som vil tvinge oss til å endre koden? Vel, vi har unngått saken hvor tallet er delbart med både 3 og 5. La oss skrive det nå.

 Assert.Equal("FizzBuzz", FizzBuzz(15));

public String FizzBuzz(int n) {
    if (isDivisibleBy(3, n) && isDivisibleBy(5, n))
        return "FizzBuzz";
    if (isDivisibleBy(3, n))
        return "Fizz";
    if (isDivisibleBy(5, n))
        return "Buzz"
    return n.ToString();
} 

Tester passerer, men vi har mer duplisering. Vi har alternativer, men jeg skal søke "Extract Local Variable" noen ganger, slik at vi refactoring istedenfor omskrivning.

 public String FizzBuzz(int n) {

    var isDivisibleBy3 = isDivisibleBy(3, n);
    var isDivisibleBy5 = isDivisibleBy(5, n);

    if ( isDivisibleBy3 && isDivisibleBy5 )
        return "FizzBuzz";
    if ( isDivisibleBy3 )
        return "Fizz";
    if ( isDivisibleBy5 )
        return "Buzz"
    return n.ToString();
} 

Og vi har dekket alle rimelige innspill, men hva med unreasonable innspilling? Hva skjer hvis vi sender 0 eller en negativ? Skriv de testene.

 public String FizzBuzz(int n) {

    if (n < 1)
        throw new InvalidArgException("n must be >= 1);

    var isDivisibleBy3 = isDivisibleBy(3, n);
    var isDivisibleBy5 = isDivisibleBy(5, n);

    if ( isDivisibleBy3 && isDivisibleBy5 )
        return "FizzBuzz";
    if ( isDivisibleBy3 )
        return "Fizz";
    if ( isDivisibleBy5 )
        return "Buzz"
    return n.ToString();
} 

Er dette begynt å se ut som "ekte kode" ennå? Enda viktigere, på hvilket tidspunkt stanset det å være "uvirkelig kode" og overgang til å være "ekte"? Det er noe å tenke på ...

Så, jeg klarte å gjøre dette bare ved å lete etter en test som jeg visste ikke ville passere ved hvert trinn, men jeg har hatt mye øvelse. Når jeg er på jobb, er det aldri så enkelt, og jeg kan ikke alltid vite hvilken test som vil tvinge en forandring. Noen ganger skal jeg skrive en test og bli overrasket over å se at den allerede går! Jeg anbefaler at du blir vant til å lage en "Test List" før du kommer i gang. Denne testlisten skal inneholde alle de "interessante" innspillene du kan tenke på. Du kan ikke bruke dem alle, og du vil sannsynligvis legge til tilfeller mens du går, men denne listen fungerer som en veikart. Min testliste for FizzBuzz ville se noe ut som dette.

  • Negativ
  • Null
  • En
  • To
  • Tre
  • Fire
  • Fem
  • Seks (ikke trivielt flertall av 3)
  • Ni (3 kvadrert)
  • Ti (ikke trivielt flere av 5)
  • 15 (flere av 3 og 5)
  • 30 (ikke trivielt flertall av 3 og 5)
5 comments
3 maple_shaft♦ 07/27/2017
Kommentarer er ikke for utvidet diskusjon; denne samtalen er flyttet til chat .
40 GManNickG 07/27/2017
Med mindre jeg er helt misforstå dette svaret: "Vi kunne gjøre noe dumt som om n == 1, men vi hopper over til den rene løsningen." - Det hele var dumt. Hvis du vet opp foran, vil du ha en funksjon som <spec>, skriver tester for <spec> og hopper over delen der du skriver versjoner som åpenbart svikter <spec>. Hvis du finner en feil i <spec>, vær sikker: skriv en test først for å bekrefte at du kan trene den før reparasjonen og observere testpasningene etter reparasjonen. Men det er ikke nødvendig å falle alle disse mellomstridene.
15 user3791372 07/28/2017
Kommentarene som peker på de store feilene i dette svaret og TDD generelt har blitt flyttet til chat. Hvis du vurderer å bruke TDD, vennligst les "chat". Dessverre er "kvalitetskommentarene" nå skjult blant en masse chat for fremtidige studenter å lese.
nbro 07/28/2017
Jeg ville være mer presis angående innholdet i denne "testlisten", hvis du ønsket å forbedre dette svaret. Jeg vil eksplisitt snakke om "grenseverdier" og "klassedeling".
2 hvd 07/30/2017
@GanNickG Jeg tror poenget er å få riktig mengde tester. Å skrive tester på forhånd gjør det enkelt å savne hvilke spesielle tilfeller som skal testes, noe som fører til at situasjoner ikke dekkes tilstrekkelig i testene, eller at i det vesentlige den samme situasjonen blir meningsløst dekket mange ganger i testene. Hvis du kan gjøre det uten disse mellomstridene, flott! Ikke alle kan gjøre det ennå, men det er noe som trener.

GenericJon 07/24/2017.

Den "ekte" koden er koden du skriver for å gjøre testpasset ditt. Really . Det er så enkelt.

Når folk snakker om å skrive det minste minimumet for å gjøre testen grønn, betyr det bare at din virkelige kode skal følge YAGNI-prinsippet .

Tanken med refaktortrinnet er bare å rydde opp det du har skrevet når du er glad for at den oppfyller kravene.

Så lenge testene du skriver faktisk omfatter produktkravene dine, når de passerer, er koden fullført. Tenk på det, hvis alle dine forretningsbehov har en test og alle disse testene er grønne, hva mer er det å skrive? (Ok, i det virkelige liv har vi ikke en tendens til å ha full testdekning, men teorien er lyd.)

5 comments
44 Derek Elkins 07/24/2017
Enhetstester kan egentlig ikke omfatte produktkravene dine for til og med relativt trivielle krav. I beste fall prøver de innspillingsutgangsspalten, og ideen er at du (riktig) generaliserer til hele innspillingsutgangen. Selvfølgelig kan koden din bare være en stor switch med et tilfelle for hver enhetstest som ville passere alle tester og mislykkes for andre innganger.
8 Taemyr 07/25/2017
@DerekElkins TDD mandater feilsøkende tester. Ikke sviktende enhetstester.
6 jonrsharpe 07/25/2017
@DerekElkins derfor skriver du ikke bare enhetstester, og også hvorfor det er en generell forutsetning at du prøver å lage noe, ikke bare falle det!
35 Derek Elkins 07/25/2017
@jonrsharpe Av den logikken, ville jeg aldri skrive trivielle implementeringer. F.eks. I FizzBuzz-eksemplet i RubberDucks svar (som bare bruker enhetstester), forklarer den første implementeringen klart "bare det". Min forståelse av spørsmålet er akkurat denne dikotomi mellom skrive kode som du vet er ufullstendig og kode som du virkelig tror vil implementere kravet, den "ekte koden". Min "store switch " var ment som en logisk ekstreme av "skrive det minste minimum for å gjøre testene grønne". Jeg ser OP-spørsmålet som: hvor i TDD er prinsippet om å unngå denne store switch ?
2 Luaan 07/25/2017
@GenericJon Det er litt for optimistisk i min erfaring :) For en, er det folk som liker tankeløst repeterende arbeid. De vil bli lykkeligere med en gigantisk bryteretning enn med en "komplisert beslutningstaking". Og for å miste jobben, ville de enten trenge noen som kaller dem ut på teknikken (og de har bedre bevis på at det faktisk mister selskapets muligheter / penger!), Eller gjør usedvanlig dårlig. Etter å ha overtatt vedlikeholdet på mange slike prosjekter, kan jeg fortelle at det er enkelt for veldig naiv kode å vare i flere tiår, så lenge det gjør kunden glad (og betaler).

Carl Raymond 07/24/2017.

Det korte svaret er at den "ekte koden" er koden som gjør testen bestått. Hvis du kan gjøre testen din bestått med noe annet enn ekte kode, legg til flere tester!

Jeg er enig i at mange opplæringsprogrammer om TDD er enkle. Det fungerer mot dem. En for enkel test for en metode som sier, beregner 3 + 8, har egentlig ingen valg enn å også beregne 3 + 8 og sammenligne resultatet. Det gjør at det ser ut som om du bare skal duplisere kode over alt, og at testingen er meningsløst, feilfrekvent ekstra arbeid.

Når du er god til testing, vil det informere om hvordan du strukturerer søknaden din, og hvordan du skriver koden din. Hvis du har problemer med å komme opp med fornuftige, hjelpsomme tester, bør du nok tenke på utformingen litt. Et godt designet system er enkelt å teste - det betyr at fornuftige tester er enkle å tenke på og å implementere.

Når du skriver tester først, se dem mislykkes, og skriv deretter koden som gjør at de passerer, det er en disiplin for å sikre at hele koden din har tilsvarende tester. Jeg følger ikke sabbaten når jeg kodes; ofte skriver jeg tester etter det faktum. Men å gjøre tester bidrar først til å holde deg ærlig. Med litt erfaring, begynner du å legge merke til når du kodes deg selv i et hjørne, selv når du ikke skriver tester først.

4 comments
6 Steve Jessop 07/26/2017
Personlig vil testen jeg skriver skrive være assertEqual(plus(3,8), 11) , ikke assertEqual(plus(3,8), my_test_implementation_of_addition(3,8)) . For mer komplekse tilfeller ser du alltid etter et middel til å bevise resultatet riktig, other than beregne det riktige resultatet i testen og kontrollere likestilling.
Steve Jessop 07/26/2017
Så for en veldig dum måte å gjøre det for dette eksempelet, kan du bevise at plus(3,8) har returnert det riktige resultatet ved å trekke 3 fra det, trekke 8 fra det og sjekke resultatet mot 0. Dette er så tydelig tilsvarer assertEqual(plus(3,8), 3+8) å være litt absurd, men hvis koden under test bygger noe mer komplisert enn bare et heltall, så tar resultatet og sjekker hver del for korrekthet. den riktige tilnærmingen. Alternativt, noe som for (i=0, j=10; i < 10; ++i, ++j) assertEqual(plus(i, 10), j)
Steve Jessop 07/26/2017
... siden det unngår den store frykten, som er at når du skriver testen, gjør vi den samme feilen om emnet "hvordan å legge til 10" som vi laget i live-koden. Så forsøke forsøket å skrive noen kode som legger 10 til noe, i testen som plus() kan legge til 10 til ting. Vi stoler fortsatt på programmerer-verifiserte innledende loopverdier, selvfølgelig.
3 Warbo 07/28/2017
Ønsker bare å påpeke at selv om du skriver tester etter det, er det fortsatt en god ide å se dem mislykkes. finn en del av koden som virker avgjørende for hva du jobber med, juster det litt (for eksempel bytt ut en + med en eller annen), kjør testene og se dem mislykkes, angre endringen og se dem passere. Mange ganger har jeg gjort dette, testen feiler faktisk ikke, noe som gjør det verre enn ubrukelig: det er ikke bare å teste noe, det gir meg feil tillit til at noe blir testet!

Victor Cejudo 07/25/2017.

Noen ganger kan noen eksempler på TDD være misvisende. Som andre har påpekt før, er koden du skriver for å gjøre tester passere den virkelige koden.

Men tro ikke at den virkelige koden ser ut som magi, det er feil. Du trenger en bedre forståelse av hva du vil oppnå, og da må du velge testen i henhold til det, fra de enkleste tilfellene og hjørnesaker.

For eksempel, hvis du trenger å skrive en lexer, starter du med tom streng, deretter med en mengde hvite rom, deretter et tall, deretter med et tall omgitt av hvite rom, deretter et feil nummer osv. Disse små transformasjonene vil lede deg til Den riktige algoritmen, men du hopper ikke fra det enkleste tilfellet til et svært komplekst tilfelle valgt dumt for å få den virkelige koden ferdig.

Bob Martin forklarer det perfekt her .


CandiedOrange 07/25/2017.

Refactor-delen er ren opp når du er sliten og vil gå hjem.

Når du skal legge til en funksjon, er refactor-delen hva du endrer før neste test. Du refactor koden for å gjøre rom for den nye funksjonen. Du gjør dette når du know hva den nye funksjonen vil være. Ikke når du bare forestiller deg det.

Dette kan være like enkelt som å omdøpe GreetImpl til GreetWorld før du oppretter en GreetMom klasse (etter å ha lagt til en test) for å legge til en funksjon som vil skrive ut «Hei mor».


graeme 07/27/2017.

Men den virkelige koden vil vises i refaktortrinnet i TDD-fasen. Dvs. koden som skal være en del av den endelige utgivelsen.

Testene bør kjøres hver gang du gjør en endring.

Mottoet til TDD-livssyklusen vil være: RØD GRØN REFAKTOR

RED : Skriv testene

GREEN : Gjør et ærlig forsøk på å få funksjonskode som passerer tester så raskt som mulig: duplikat kode, uklart navngitte variabler hacks av høyeste rekkefølge, etc.

REFACTOR : REFACTOR opp koden, REFACTOR riktig variablene. Tørk opp koden.

5 comments
5 mcottle 07/25/2017
Jeg vet hva du sier om "Grønn" -fasen, men det innebærer at hardverdige returverdier for å få testene passere, kan være aktuelle. I min erfaring skal "Green" være et ærlig forsøk på å gjøre arbeidskode for å oppfylle kravet, men det kan ikke være perfekt, men det skal være så komplett og "shippable" som utvikleren kan klare seg i et første pass. Refactoring er trolig best gjort litt tid senere etter at du har gjort mer utvikling, og problemene med første pass blir tydeligere og muligheter til å DRY oppstår.
graeme 07/25/2017
@mcottle Jeg anser disse som en del av samme oppgave. få det gjort, og ryd det opp. Ytterligere refactorings bør foregå når tiden går videre som en del av andre oppgaver.
1 Bryan Boettcher 07/25/2017
@mcottle: Det kan hende du er overrasket over hvor mange implementeringer av et bare-butikkregister kan være hardkodede verdier i kodebase. :)
6 Kaz 07/25/2017
Hvorfor skulle jeg noen gang skrive skrekkkode og rydde den opp, når jeg kan veksle ut fin, produksjonskvalitetskode nesten like fort som jeg kan skrive? :)
1 Kaz 07/27/2017
@TimothyTruckle Hva tar det om 50 minutter å finne den enkleste mulige endringen, men bare 5 for å finne den nest enkleste mulige endringen? Går vi med andre enkleste eller fortsetter å lete etter enkleste?

Timothy Truckle 07/27/2017.

Når skriver du den "ekte" koden i TDD?

Den red fasen er hvor du write kode.

I refactoring er det primære målet å delete kode.

I den red fasen gjør du noe for å gjøre testen as quick as possible og at any cost . Du ser helt bort fra hva du noensinne har hørt om gode kodingspraksis eller designmønster. Å gjøre testen grønn er alt som betyr noe.

I refactoring rydder du opp rotet du nettopp har gjort. Nå ser du først om endringen du nettopp har gjort, er den slags toppen mest i Transformation Priority-listen, og hvis det er noen kodet duplisering, kan du fjerne det mest sannsynlig ved å bruke en design patter.

Til slutt forbedrer du lesbarheten ved å omdøpe identifikatorer og trekke ut magic numbers og / eller bokstavsstrenge til konstanter.


Det er ikke rødreflektor, det er rødgrønn refaktor. - Rob Kinyon

Takk for at du peker på dette.

Så det er den green fasen der du skriver den real code

I den red fasen skriver du executable specification ...

2 comments
Rob Kinyon 07/27/2017
Det er ikke rødreflektor, det er rødgrønn refaktor. Den "røde" er at du tar testpakken din fra grønt (alle tester passerer) til rødt (en test mislykkes). Den "grønne" er hvor du sloppily tar testpakken din fra rødt (en test mislykkes) til grønn (alle tester passerer). "Refactor" er hvor du tar koden din og gjør den pen mens du holder alle tester passert.
Timothy Truckle 07/27/2017
@RobKinyon Takk, oppdatert svaret.

Robert Andrzejuk 07/27/2017.

Du skriver Real Code hele tiden.

Ved hvert trinn skriver du kode for å tilfredsstille vilkårene som Koden din vil tilfredsstille for fremtidige innringere av koden din (som kan være deg eller ikke ...).

Du tror du skriver ikke nyttig ( real ) kode, for i et øyeblikk kan du refactor det ut.

Kode-Refactoring er prosessen med å restrukturere eksisterende datakode, og endrer factoring-uten å endre ekstern oppførsel.

Hva dette betyr er at selv om du endrer koden, blir betingelsene koden tilfredsstilt, uendret. Og sjekker ( tests ) Du har implementert for å bekrefte Koden din er allerede der for å bekrefte om endringene dine har endret noe. Så koden du skrev hele tiden er der inne, bare på en annen måte.

En annen grunn Du kan tro at det ikke er ekte kode, det er at du gjør eksempler der sluttprogrammet allerede kan forutsies av deg. Dette er veldig bra, som det viser. Du har kunnskap om domain du programmerer i.
Men mange ganger programmerere er i et domain som er new , unknown for dem. De vet ikke hva sluttresultatet vil være, og TDD er en technique å skrive programmer trinnvis, dokumentere vår knowledge om hvordan dette systemet skal fungere og verifisere at koden vår fungerer på den måten.

Da jeg leste boken (*) på TDD, var det viktigste for meg som var: TODO-listen. Det viste meg at TDD er også en teknikk som hjelper utviklere å fokusere på en ting om gangen. Så dette er også et svar på ditt spørsmål om How much Real code to write ? Jeg vil si nok kode for å fokusere på 1 ting om gangen.

(*) "Testdrevet utvikling: Ved eksempel" av Kent Beck

1 comments
2 Robert Andrzejuk 07/27/2017
"Testdrevet utvikling: Ved eksempel" av Kent Beck

Zenilogix 07/31/2017.

Du skriver ikke kode for å få testene dine feilet.

Du skriver tester for å definere hvilken suksess som skal se ut, som alle i utgangspunktet skulle mislykkes fordi du ennå ikke har skrevet koden som vil passere.

Hele poenget med å skrive i utgangspunktet sviktende tester er å gjøre to ting:

  1. Dekk alle tilfeller - alle nominelle tilfeller, alle kantsaker, etc.
  2. Bekreft testene dine. Hvis du bare ser dem passere, hvordan kan du være sikker på at de på en pålitelig måte vil rapportere en feil når man oppstår?

Poenget bak rødgrønn refaktor er at det å skrive de riktige testene først gir deg selvtilliten til å vite at koden du skrev for å bestå testene er riktig, og lar deg refactor med tilliten til at testene dine vil informere deg så snart som noe bryter, så du kan umiddelbart gå tilbake og fikse det.

I min egen erfaring (C # /. NET) er ren test-først litt uoppnåelig, fordi du ikke kan samle et kall til en metode som ikke eksisterer ennå. Så "test først" handler egentlig om å koble opp grensesnitt og stikkende implementeringer først, og deretter skrive tester mot stubber (som først vil mislykkes) til stubene er riktig fleshed ut. Jeg skriver aldri "failing code", bare å bygge ut fra stubber.


Zan Lynx 07/27/2017.

Jeg tror du kan være forvirret mellom enhetstester og integreringstester. Jeg tror det kan også være aksepttest, men det avhenger av prosessen.

Når du har testet alle de små "enhetene", tester du dem alle sammen, eller "integrert". Det er vanligvis et helt program eller bibliotek.

I kode som jeg har skrevet integreringstestene, er et bibliotek med ulike testprogrammer som leser data og matet det til biblioteket, så sjekk resultatene. Da gjør jeg det med tråder. Da gjør jeg det med tråder og gaffel () i midten. Så kjører jeg det og dreper -9 etter 2 sekunder, så starter jeg det og sjekker gjenopprettingsmodus. Jeg fuzz det. Jeg torturerer det på alle måter.

Alt dette er også test, men jeg har ikke en fin rød / grønn skjerm for resultatene. Det lykkes enten, eller jeg graver gjennom noen få tusen linjer med feilkode for å finne ut hvorfor.

Det er her du tester "ekte koden".

Og jeg tenkte bare på dette, men kanskje du ikke vet når du skal ferdig skrive enhetstester. Du er ferdig med å skrive enhetstester når testene utøver alt du oppgav det skulle gjøre. Noen ganger kan du miste oversikten over alle feilhåndterings- og kantsaker, så du vil kanskje gjøre en fin testgruppe med gode sti tester som bare går rett gjennom spesifikasjonene.

1 comments
Peter Mortensen 07/27/2017
(dens = possessive, det er = "det er" eller "det har". Se for eksempel How to Use Its and It's .)

user3791372 07/27/2017.

Svar på tittelen på spørsmålet: "Når skriver du den" ekte "koden i TDD?", Svaret er: "neppe" eller "veldig sakte".

Du høres ut som en student, så jeg vil svare som om å gi råd til en student.

Du skal lære mange kodende teorier og teknikker. De er gode for å passere tiden på overpriced studentkurs, men med svært liten fordel for deg som du ikke kunne lese i en bok om halve tiden.

Jobben til en koder er bare for å produsere kode. Kode som fungerer veldig bra. Det er derfor du, koderen planlegger koden i tankene dine, på papir, i et passende program, etc., og du planlegger å jobbe om mulige feil / hull på forhånd ved å tenke logisk og sideværts før koding.

Men du trenger å vite hvordan du kan bryte søknaden din for å kunne designe anstendig kode. For eksempel, hvis du ikke visste om Little Bobby Table (xkcd 327), ville du sannsynligvis ikke være sanitizing dine innganger før du jobbet med databasen, slik at du ikke ville kunne sikre dataene dine rundt det konseptet.

TDD er bare en arbeidsflyt utformet for å minimere feilene i koden din ved å skape tester av hva som kan gå galt før du kodes programmet fordi koding kan bli eksponentielt vanskeligere, jo mer kode du introduserer, og du glemmer feil som du en gang trodde på. Når du tror at du er ferdig med søknaden din, kjører du tester og bommen, forhåpentligvis blir bugs fanget med testene dine.

TDD er ikke - som noen tror - skrive en test, få den til å passere med minimal kode, skriv en annen test, få det forbi med minimal kode osv. I stedet er det en måte å hjelpe deg med å kode trygt. Dette ideet om kontinuerlig refactoring kode for å få det til å fungere med tester er idiotisk, men det er et fint konsept blant elevene fordi det får dem til å føle seg bra når de legger til en ny funksjon, og de lærer fortsatt å kodes ...

Vennligst ikke fall ned denne fellen og se din rolle som koding for hva det er - jobben til en koder er bare for å produsere kode. Kode som fungerer veldig bra. Nå husk at du kommer til å være døgnet som en profesjonell koder, og klienten din bryr deg ikke om du skrev 100 000 påstander, eller 0. De vil bare ha kode som fungerer. Virkelig bra, faktisk.

5 comments
3 johnny 07/25/2017
Jeg er ikke engang nær en student, men jeg leser og prøver å bruke gode teknikker og være profesjonell. Så i den forstand er jeg en "student". Jeg spør bare veldig grunnleggende spørsmål fordi det er slik jeg er. Jeg liker å vite nøyaktig hvorfor jeg gjør det jeg gjør. Sakens kjerne. Hvis jeg ikke forstår det, liker jeg det ikke og begynner å stille spørsmål. Jeg må vite hvorfor, hvis jeg skal bruke den. TDD virker intuitivt bra på noen måter som å vite hva du trenger for å skape og tenke gjennom ting, men implementeringen var vanskelig å forstå. Jeg tror jeg har en bedre forståelse nå.
4 Sean Burton 07/27/2017
Dette er reglene for TDD. Du er fri til å skrive kode, men du vil, men hvis du ikke følger disse tre reglene, gjør du ikke TDD.
2 user3791372 07/27/2017
"Regler" for en person? TDD er et forslag til å hjelpe deg med å kode, ikke en religion. Det er trist å se så mange mennesker holder seg til en ide så analt. Selv opprinnelsen til TDD er kontroversiell.
2 Alex 07/28/2017
@ user3791372 TDD er en veldig streng og klart definert prosess. Selv om mange synes det bare betyr "Gjør noe testing når du programmerer", er det ikke. La oss prøve å ikke blande vilkår her, dette spørsmålet handler om prosessen TDD, ikke generell testing.

Related questions

Hot questions

Language

Popular Tags