Kailan mo isusulat ang "real" code sa TDD?

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

Ang lahat ng mga halimbawa na nabasa ko at nakita sa mga video ng pagsasanay ay may mga simpleng halimbawa. Ngunit kung ano ang hindi ko makita kung paano ko gawin ang "real" na code pagkatapos makakuha ako ng green. Ito ba ang bahagi ng "Refactor"?

Kung mayroon akong isang medyo kumplikadong bagay na may isang kumplikadong pamamaraan, at isinusulat ko ang aking pagsubok at ang pinakamaliit na upang ipasa ito (pagkatapos itong unang nabigo, Pula). Kailan ako babalik at isulat ang tunay na code? At gaano karami ang tunay na code na isusulat ko bago ako muling sumulat? I'm guessing that last one is more intuition.

Edit: Salamat sa lahat na sumagot. Nakatulong sa akin ang lahat ng iyong mga sagot. Tila may iba't-ibang mga ideya sa kung ano ako ay humihingi o nalilito tungkol sa, at marahil ay may, ngunit kung ano ako ay humihingi ay, sabihin mayroon akong isang application para sa pagbuo ng isang paaralan.

Sa aking disenyo, mayroon akong arkitektong gusto kong magsimula, Mga Kuwento ng Gumagamit, at iba pa. Mula dito, kukuha ako ng Mga Kuwento ng Gumagamit, at gumawa ako ng isang pagsubok upang subukan ang User Story. Sinasabi ng Gumagamit, Mayroon kaming mga taong nagpatala para sa paaralan at magbayad ng mga bayarin sa pagpaparehistro. Kaya, iniisip ko ang isang paraan upang mabigo iyon. Sa paggawa nito nag-disenyo ako ng isang Class ng pagsubok para sa klase X (siguro Mag-aaral), na kung saan ay mabibigo. Pagkatapos ay lilikha ako ng klase na "Mag-aaral." Siguro "Paaralan" hindi ko alam.

Ngunit, sa anumang kaso, ang TD Design ay pumipilit sa akin na isipin ang kuwento. Kung mabibigo ako ng pagsubok, alam ko kung bakit ito nabigo, ngunit ito ay nangangahulugang maaari kong ipasa ito. Ito ay tungkol sa pagdidisenyo.

Ibinabahagi ko ito sa pag-iisip tungkol sa Recursion. Ang rekurso ay hindi isang mahirap na konsepto. Maaaring mas mahirap na aktwal na subaybayan ang mga ito sa iyong ulo, ngunit sa katotohanan, ang hardest bahagi ay alam, kapag ang recursion "break," kapag upang itigil (ang aking opinyon, siyempre.) Kaya dapat kong isipin kung ano ang hihinto ang Recursion muna. Ito ay isang di-perpektong pagkakatulad, at ipinapalagay na ang bawat recursive na pag-ulit ay isang "pass." Muli, isang opinyon lamang.

Sa pagpapatupad, mas mahirap makita ang paaralan. Ang mga numerical at banking ledger ay "madali" sa diwa na maaari mong gamitin ang simpleng aritmetika. Maaari ko bang makita ang isang + b at bumalik 0, atbp Sa kaso ng isang sistema ng mga tao, kailangan kong mag-isip nang mas mahirap kung paano implement iyon. Mayroon akong konsepto ng pagkabigo, pass, refactor (kadalasan dahil sa pag-aaral at tanong na ito.)

Ang hindi ko alam ay batay sa kakulangan ng karanasan, sa aking opinyon. Hindi ko alam kung paano mabigo mag-sign up ng isang bagong mag-aaral. Hindi ko alam kung paano mabibigo ang pag-type ng isang tao sa isang huling pangalan at ito ay nai-save sa isang database. Alam ko kung paano gumawa ng isang + 1 para sa simpleng matematika, ngunit may mga nilalang tulad ng isang tao, hindi ko alam kung sinusubok lang ako upang makita kung babalik ako ng isang database na natatanging ID o ibang bagay kapag may nagpasok sa isang pangalan sa isang database o pareho o hindi.

O, marahil ito ay nagpapakita na ako ay nalilito pa rin.

5 Comments
187 hobbs 07/25/2017
Matapos ang mga taong TDD umuwi para sa gabi.
14 Goyo 07/25/2017
Bakit sa palagay mo ang code na iyong sinulat ay hindi tunay?
2 johnny 07/26/2017
@RubberDuck Higit sa iba pang mga sagot ang ginawa. Sigurado ako ay sumangguni ako dito sa lalong madaling panahon. Ito ay uri pa rin ng mga dayuhan, ngunit hindi ko ibibigay ito. Ang sinabi mo ay may katuturan. Sinisikap kong gawin itong makatuwiran sa aking konteksto o isang regular na aplikasyon sa negosyo. Siguro isang sistema ng imbentaryo o katulad nito. Kailangan kong isaalang-alang ito. Nagpapasalamat ako sa iyong oras. Salamat.
1 Edmund Reed 07/26/2017
Ang mga sagot ay naka-hit sa kuko sa ulo, ngunit hangga't ang lahat ng iyong mga pagsusulit ay dumaraan, at hindi mo kailangan ng anumang mga bagong pagsubok / functionality, maaari itong ipagpalagay na ang code na mayroon ka ay tapos na, bar linting.
3 Borjab 07/26/2017
May isang asumption sa tanong na maaaring may problema sa "Mayroon akong isang medyo kumplikadong bagay na may isang kumplikadong pamamaraan". Sa TDD isulat mo ang iyong mga pagsubok muna upang simulan mo ang isang medyo simpleng code. Mapipilit ka nito na mag-code ng test-friendly na istraktura na kailangang maging Modular. Kaya kumplikadong pag-uugali ay malilikha sa pamamagitan ng pagsasama ng mas simpleng mga bagay. Kung nagtatapos ka sa isang medyo kumplikadong bagay o pamamaraan pagkatapos ay kapag ikaw refactor

11 Answers


RubberDuck 07/27/2017.

Kung mayroon akong isang medyo kumplikadong bagay na may isang kumplikadong pamamaraan, at isinusulat ko ang aking pagsubok at ang pinakamaliit na upang ipasa ito (pagkatapos itong unang nabigo, Pula). Kailan ako babalik at isulat ang tunay na code? At gaano karami ang tunay na code na isusulat ko bago ako muling sumulat? I'm guessing that last one is more intuition.

Hindi ka "bumalik" at isulat ang "real code". Lahat ng totoong code. Ang gagawin mo ay bumalik at magdagdag ng isa pang pagsubok na forces mong change iyong code upang maipasa ang bagong pagsubok.

Bilang para sa kung magkano ang code na isulat mo bago mo muling subukan? Wala. Isulat mo ang zero code nang walang isang hindi pagtagumpayan test na forces mong magsulat ng higit pang code.

Pansinin ang pattern?

Maglakad tayo (ibang) simpleng halimbawa sa pag-asang ito ay tumutulong.

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

Madali peazy.

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

Hindi kung ano ang tatawagan mo ang tunay na code, tama? Magdaragdag tayo ng isang pagsubok na nagpapalakas ng pagbabago.

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

Maaari naming gawin ang isang bagay hangal tulad ng if n == 1 , ngunit kami ay laktawan sa matalinong solusyon.

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

Malamig. Ito ay gagana para sa lahat ng mga di-FizzBuzz na mga numero. Ano ang susunod na input na magpipilit sa pagbabago ng code ng produksyon?

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

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

At muli. Sumulat ng isang pagsubok na hindi pa pumasa.

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

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

At nasasaklaw na natin ngayon ang lahat ng mga multiple ng tatlong (na hindi rin ang mga multiple ng limang, tatalunin natin ito at bumalik).

Hindi pa namin isinulat ang isang pagsubok para sa "Buzz" pa, kaya't isulat natin iyon.

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

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

At muli, alam natin na may isa pang kaso na kailangan nating hawakan.

 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();
} 

At ngayon maaari naming pangasiwaan ang lahat ng mga multiple ng 5 na hindi rin ang mga multiple ng 3.

Hanggang sa puntong ito, hindi namin binabalewala ang hakbang ng refactoring, ngunit nakikita ko ang ilang pagkopya. Linisin natin iyan ngayon.

 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();
} 

Malamig. Ngayon naalis na namin ang pagkopya at lumikha ng isang mahusay na pinangalanan function. Ano ang susunod na pagsubok na maaari naming isulat na magpipilit sa amin upang baguhin ang code? Buweno, iniiwasan na natin ang kaso kung saan binabahagi ang numero sa pamamagitan ng parehong 3 at 5. Isulat natin ito ngayon.

 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();
} 

Ang mga pagsusulit ay pumasa, ngunit mas maraming pagkopya. Mayroon kaming mga opsyon, ngunit ilalapat ko ang "I-extract ang Lokal na Variable" nang ilang beses upang refactoring namin sa halip na muling pagsusulat.

 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();
} 

At nasasakop namin ang lahat ng makatwirang input, ngunit ano ang tungkol sa unreasonable input? Ano ang mangyayari kung pumasa tayo ng 0 o negatibo? Isulat ang mga kaso ng pagsubok na iyon.

 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();
} 

Ay nagsisimula pa ba itong magmukhang "tunay na code"? Higit sa lahat, sa anong punto ay tumigil ito sa pagiging "di-tunay na code" at paglipat sa pagiging "tunay"? Iyan ay isang bagay na pag-isipan ...

Kaya, nagawa ko lang ito sa pamamagitan ng paghanap ng isang pagsubok na alam kong hindi makadaan sa bawat hakbang, ngunit maraming pagsasanay ako. Kapag nasa trabaho ako, hindi kailanman ang mga bagay na ito ay simple at maaaring hindi ko laging alam kung anong pagsubok ang magpipilit ng pagbabago. Kung minsan ay magsusulat ako ng isang pagsubok at mabigla upang makita na ito ay pumasa! Masidhing inirerekomenda ko na makakakuha ka ng ugali ng paglikha ng isang "Listahan ng Pagsubok" bago ka magsimula. Ang listahan ng pagsubok ay dapat maglaman ng lahat ng mga "kawili-wiling" input na maaari mong isipin. Maaari mong hindi gamitin ang lahat ng ito at malamang na magdagdag ka ng mga kaso habang ikaw ay pupunta, ngunit ang listahang ito ay nagsisilbing isang roadmap. Ang aking listahan ng pagsubok para sa FizzBuzz ay magiging ganito ang hitsura nito.

  • Negatibo
  • Zero
  • Isa
  • Dalawa
  • Tatlong
  • Apat
  • Limang
  • Anim (hindi mahalaga ang maramihang ng 3)
  • Siyam (3 squared)
  • Sampung (hindi mahalaga ang maramihang ng 5)
  • 15 (maramihang ng 3 at 5)
  • 30 (hindi mahalaga ang maramihang ng 3 at 5)
5 comments
3 maple_shaft♦ 07/27/2017
Ang mga komento ay hindi para sa pinalawak na talakayan; Ang pag-uusap na ito ay inilipat sa chat .
40 GManNickG 07/27/2017
Maliban kung hindi ko lubos na hindi maintindihan ang sagot na ito: "Maaari tayong gumawa ng isang bagay na hangal kung n == 1, ngunit laktawan natin ang maliwanag na solusyon." - ang buong bagay ay ulok. Kung alam mo sa harap na nais mo ang isang function na ginagawa ang <spec>, magsulat ng mga pagsusulit para sa <spec> at laktawan ang bahagi kung saan nagsusulat ka ng mga bersyon na malinaw na mabibigo <spec>. Kung nakakita ka ng isang bug sa <spec> pagkatapos ay sigurado: magsulat ng isang pagsubok muna upang i-verify maaari mong mag-ehersisyo ito bago ang pag-aayos at sundin ang mga pumasa sa pagsubok pagkatapos ng pag-aayos. Ngunit hindi na kailangang peke ang lahat ng mga intermediate na hakbang na ito.
15 user3791372 07/28/2017
Ang mga komento na tumutukoy sa mga pangunahing mga depekto sa sagot na ito at ang TDD sa pangkalahatan ay inilipat sa chat. Kung isinasaalang-alang mo ang paggamit ng TDD, pakibasa ang 'chat'. Sa kasamaang-palad, ang mga komento ng 'kalidad' ay nakatago sa gitna ng isang load ng chat para sa mga mag-aaral sa hinaharap upang mabasa.
nbro 07/28/2017
Gusto kong maging mas tumpak tungkol sa mga nilalaman ng "test list" na ito, kung gusto mong mapabuti ang sagot na ito. Malinaw kong pag-usapan ang tungkol sa "mga hangganan ng mga halaga" at "partitioning ng klase".
2 hvd 07/30/2017
@GManNickG Naniniwala ako na ang punto ay upang makuha ang tamang dami ng mga pagsubok. Ang pagsusulat ng mga pagsusulit muna ay madali upang makaligtaan kung anong mga espesyal na kaso ang dapat subukan, na humahantong sa alinman sa mga sitwasyon na hindi saklaw ng sapat sa mga pagsusulit, o sa mahalagang kaparehong sitwasyon na walang gaanong tinakpanang mga nagawa sa mga pagsubok. Kung maaari mong gawin iyon nang walang mga intermediate hakbang na ito, mahusay! Hindi lahat ay maaaring gawin ito kahit na, ito ay isang bagay na tumatagal ng pagsasanay.

GenericJon 07/24/2017.

Ang "real" code ay ang code na isinusulat mo upang gawin ang iyong test pass. Really . Simple lang iyan.

Kapag ang mga tao ay makipag-usap tungkol sa pagsulat ng pinakamaliit na panahon upang gawin ang pagsubok na berde, nangangahulugan iyon na dapat sundin ng iyong tunay na code ang prinsipyo ng YAGNI .

Ang ideya ng hakbang para sa refactor ay para lamang malinis ang iyong isinulat sa sandaling nalulugod ka na natutugunan nito ang mga kinakailangan.

Hangga't ang pagsusulit na isulat mo ay talagang sumasaklaw sa iyong mga kinakailangan sa produkto, sa sandaling pumasa sila pagkatapos ay kumpleto na ang code. Isipin ito, kung ang lahat ng iyong mga pangangailangan sa negosyo ay may pagsusulit at lahat ng mga pagsubok ay berde, ano pa ang naroroon upang isulat? (Okay, sa totoong buhay ay hindi tayo may posibilidad na magkaroon ng kumpletong saklaw ng pagsubok, ngunit ang teorya ay tunog.)

5 comments
44 Derek Elkins 07/24/2017
Ang mga pagsusulit ng unit ay hindi maaaring aktwal na sumaklaw sa iyong mga kinakailangan sa produkto para sa kahit na medyo walang kuwenta kinakailangan. Sa pinakamainam na paraan, sila ay nag-sample ng input-output na espasyo at ang ideya ay na ikaw (tama) pangkalahatan sa buong puwang ng input-output. Siyempre, ang iyong code ay maaaring maging isang malaking switch may isang kaso para sa bawat unit test na pumasa sa lahat ng mga pagsubok at mabibigo para sa anumang iba pang mga input.
8 Taemyr 07/25/2017
@DerekElkins TDD ay nag-utos ng mga hindi nakakagaling na pagsubok. Hindi bumabagsak ang mga pagsusulit ng yunit.
6 jonrsharpe 07/25/2017
@DekekElkins na ang dahilan kung bakit hindi mo lamang isulat ang mga pagsusulit sa yunit, at kung bakit may pangkalahatang palagay na sinusubukan mong gumawa ng isang bagay na hindi lamang pekeng ito!
35 Derek Elkins 07/25/2017
@ jonrsharpe Sa pamamagitan ng na lohika, hindi ko nais magsulat ng mga walang katuturang pagpapatupad. Halimbawa sa halimbawa ng FizzBuzz sa sagot ng RubberDuck (na gumagamit lamang ng mga pagsusulit ng yunit), ang unang pagpapatupad ay malinaw na "mga pekeng ito lang". Ang aking pag-unawa sa tanong ay ang eksaktong dichotomy na ito sa pagitan ng pagsusulat ng code na alam mo ay hindi kumpleto at ang code na tunay mong pinaniniwalaan ay magpapatupad ng kinakailangan, ang "real code". Ang aking "malaking switch " ay inilaan bilang isang lohikal na sukdulan ng "pagsusulat ng pinakamaliit na dapat gawin ang mga pagsubok na berde". Tinitingnan ko ang tanong ng OP bilang: kung saan sa TDD ang prinsipyo na nag-iwas sa malaking switch ?
2 Luaan 07/25/2017
@GenericJon Iyan ay masyadong maasahin sa aking karanasan :) Para sa isa, may mga tao na tangkilikin ang walang kahulugan na paulit-ulit na gawain. Mas masaya sila sa isang higanteng pahayag sa paglipat kaysa sa isang "kumplikadong paggawa ng desisyon". At mawawalan ng trabaho, kakailanganin nila ang alinman sa isang taong tumawag sa kanila sa pamamaraan (at mas mahusay na sila ay may magandang katibayan na talagang nawawala ang mga pagkakataon sa kumpanya / pera!), O iba pang masama. Matapos kunin ang pagpapanatili sa maraming mga naturang proyekto, maaari kong sabihin na madali para sa napaka-walang muwang na code na tatagal ng mga dekada, hangga't ginagawang masaya (at nagbabayad) ang customer.

Carl Raymond 07/24/2017.

Ang maikling sagot ay na ang "tunay na code" ay ang code na gumagawa ng test pass. Kung maaari mong gawin ang iyong test pass sa isang bagay maliban sa real code, magdagdag ng higit pang mga pagsubok!

Sumasang-ayon ako na ang maraming mga tutorial tungkol sa TDD ay simple. Nagtatrabaho laban sa kanila. Ang isang masyadong-simpleng pagsubok para sa isang paraan na, sabihin, computes 3 + 8 ay talagang walang pagpipilian ngunit upang ring kalkulahin ang 3 + 8 at ihambing ang resulta. Iyon ay ginagawang tulad ng makikita mo lamang duplicating code sa lahat ng dako, at ang pagsubok ay walang kabuluhan, error-madaling kapitan ng sakit dagdag na trabaho.

Kapag handa ka sa pagsubok, ipaalam kung paano mo istraktura ang iyong aplikasyon, at kung paano mo isulat ang iyong code. Kung nagkakaproblema ka pagdating sa matalinong, kapaki-pakinabang na mga pagsubok, dapat mong muling isipin ang iyong disenyo nang kaunti. Ang isang mahusay na dinisenyo na sistema ay madali upang subukan - ibig sabihin ng matalino pagsusulit ay madaling isipin, at upang ipatupad.

Kapag isinulat mo muna ang iyong mga pagsusulit, panoorin ang mga ito ay mabibigo, at pagkatapos ay isulat ang code na nagpapasa sa kanila, iyon ay isang disiplina upang matiyak na ang lahat ng iyong code ay may mga kaukulang pagsusulit. Hindi ko sinasadya na sundin ang patakarang iyon kapag ako ay coding; madalas magsusulat ako ng mga pagsusulit pagkatapos ng katotohanan. Ngunit ang paggawa ng mga pagsubok ay nakakatulong upang mapanatili kang tapat. Sa ilang karanasan, magsisimula kang mapansin kapag naka-coding ka sa iyong sarili sa isang sulok, kahit na hindi ka nagsusulat ng mga pagsusulit muna.

4 comments
6 Steve Jessop 07/26/2017
Sa personal, ang pagsusulit na nais kong isulat ay assertEqual(plus(3,8), 11) , hindi assertEqual(plus(3,8), my_test_implementation_of_addition(3,8)) . Para sa mga mas kumplikadong mga kaso, lagi mong hinahanap ang isang paraan ng pagpapatunay na tama ang resulta, other than magaling na pagkalkula ng tamang resulta sa pagsusulit at pagsuri ng pagkakapantay-pantay.
Steve Jessop 07/26/2017
Kaya para sa isang tunay na nakakatawa paraan ng paggawa nito para sa halimbawang ito, maaari mong patunayan na plus(3,8) ay ibinalik ang tamang resulta sa pamamagitan ng pagbawas ng 3 mula dito, pagbabawas ng 8 mula sa iyon, at pagsuri ng resulta laban sa 0. Ito ay malinaw naman katumbas sa assertEqual(plus(3,8), 3+8) bilang isang bit absurd, ngunit kung ang code sa ilalim ng pagsubok ay pagbubuo ng isang bagay na mas kumplikado kaysa sa isang integer lamang, pagkatapos ay ang pagkuha ng resulta at pagsuri sa bawat bahagi para sa kawastuhan ay madalas ang tamang paraan. Bilang kahalili, tulad ng for (i=0, j=10; i < 10; ++i, ++j) assertEqual(plus(i, 10), j)
Steve Jessop 07/26/2017
... dahil naiwasan nito ang malaking takot, na kung saan kapag nagsusulat ng pagsusulit magkakaroon kami ng parehong pagkakamali sa paksa ng "kung paano magdagdag ng 10" na ginawa namin sa live na code. Kaya maingat na maiwasan ng pagsusulit ang pagsusulat ng anumang code na nagdadagdag ng 10 sa anumang bagay, sa pagsusulit na plus() maaaring magdagdag ng 10 sa mga bagay. Namin pa rin umaasa sa programmer-verify na mga halaga ng intial loop, siyempre.
3 Warbo 07/28/2017
Nais mo lamang ituro na kahit na nagsusulat ka ng mga pagsubok pagkatapos ng katotohanan, isang magandang ideya na panoorin ang mga ito ay nabigo; hanapin ang ilang bahagi ng code na tila napakahalaga sa kahit anong ginagawa mo, mag-tweak ito nang kaunti (hal. palitan ang isang + may -, o anuman), patakbuhin ang mga pagsubok at panoorin ang mga ito ay mabigo, i-undo ang pagbabago at panoorin ang mga ito. Maraming mga beses na nagawa ko na ang pagsubok ay hindi tunay na mabibigo, ginagawa itong mas masahol pa kaysa sa walang silbi: hindi lamang ito ay hindi sinusubukan ang anumang bagay, nagbibigay ito sa akin ng maling kumpiyansa na ang isang bagay ay sinubukan!

Victor Cejudo 07/25/2017.

Kung minsan ang ilang mga halimbawa tungkol sa TDD ay maaaring maging nakaliligaw. Tulad ng itinuturo ng ibang tao, ang code na isulat mo upang makapagpasa ng mga pagsusulit ay ang tunay na code.

Ngunit huwag isipin na ang totoong code ay lilitaw tulad ng magic -ang mali. Kailangan mo ng isang mas mahusay na pag-unawa sa kung ano ang nais mong makamit at pagkatapos ay kailangan mong pumili ng pagsubok nang naaayon, simula sa pinakamadaling kaso at sulok ng mga kaso.

Halimbawa, kung kailangan mong magsulat ng isang lexer, magsisimula ka sa walang laman na string, pagkatapos ay may isang grupo ng mga whitespaces, pagkatapos ay isang numero, pagkatapos ay may isang numero na napapalibutan ng mga whitespaces, pagkatapos ay isang maling numero, atbp. Ang mga maliliit na pagbabagong ito ay hahantong sa iyo ang tamang algorithm, ngunit hindi ka tumalon mula sa pinakamadaling kaso sa isang napakasalimuot na kaso na napili nang walang kapararakan upang makuha ang totoong code.

Ipinaliwanag ito ni Bob Martin nang perpekto dito .


CandiedOrange 07/25/2017.

Ang bahagi ng refactor ay malinis kapag ikaw ay pagod at gusto mong umuwi.

Kapag handa ka nang magdagdag ng isang tampok ang bahagi ng refactor ay kung ano ang iyong binago bago ang susunod na pagsubok. Ikaw refactor ang code upang gumawa ng room para sa mga bagong tampok. Gawin mo ito kapag know mo know ano ang magiging bagong tampok na iyon. Hindi kapag nagugustuhan mo lang ito.

Ito ay maaaring kasing simple ng pagpapalit ng pangalan ng GreetImpl sa GreetWorld bago ka lumikha ng isang GreetMom class (pagkatapos magdagdag ng isang pagsubok) upang magdagdag ng isang tampok na i-print ang "Hi Mom".


graeme 07/27/2017.

Ngunit ang tunay na code ay lilitaw sa yugto ng refactor ng phase TDD. Ibig sabihin ang code na dapat maging bahagi ng huling release.

Dapat na patakbuhin ang mga pagsubok sa bawat oras na gumawa ka ng pagbabago.

Ang moto ng siklo ng buhay ng TDD ay: RED GREEN REFACTOR

RED : Isulat ang mga pagsubok

GREEN : Gumawa ng matapat na pagtatangka upang makakuha ng functional code na pumasa sa mga pagsusulit nang mabilis hangga't maaari: duplicate code, malabo na pinangalanang mga variable hacks ng pinakamataas na order, atbp.

REFACTOR : Linisin ang code, maayos na pangalanan ang mga variable. Patuyuin ang code.

5 comments
5 mcottle 07/25/2017
Alam ko kung ano ang sinasabi mo tungkol sa "Green" phase ngunit ito ay nagpapahiwatig na ang hard-kable bumalik mga halaga upang gawin ang mga pagsusulit ay maaaring maging angkop. Sa aking karanasan na "Green" ay dapat na isang matapat na pagtatangka upang gumawa ng code ng pagtatrabaho upang matugunan ang pangangailangan, maaaring hindi ito perpekto ngunit ito ay dapat na kumpleto at "shippable" bilang ang developer ay maaaring pamahalaan sa isang unang pass. Ang repactoring ay marahil ang pinakamahusay na ginawa ilang oras mamaya pagkatapos mong nagawa ang higit pang pag-unlad at ang mga problema sa unang pass maging mas maliwanag at mga pagkakataon sa dry lumabas.
graeme 07/25/2017
@mcottle ako isaalang-alang ang lahat ng bahagi ng parehong gawain. gawin ito, pagkatapos ay linisin ito. Ang karagdagang refactorings ay dapat maganap habang ang oras ay tumatakbo bilang bahagi ng iba pang mga gawain.
1 Bryan Boettcher 07/25/2017
@ mcottle: baka magulat ka kung gaano karaming mga pagpapatupad ng isang get-only repository ang maaaring hardcoded na mga halaga sa codebase. :)
6 Kaz 07/25/2017
Bakit ko kailanman isulat ang crap code at linisin ito, kapag maaari kong mag-crank out gandang, kalidad ng code ng produksyon halos kasing bilis ng maaari kong i-type? :)
1 Kaz 07/27/2017
@TimothyTruckle Ano ito kung tumatagal ng 50 minuto upang mahanap ang pinakasimpleng posibleng pagbabago, ngunit 5 lamang upang mahanap ang ikalawang pinakasimpleng posibleng pagbabago? Mayroon ba kaming pumunta sa pangalawang pinakasimpleng o panatilihing naghahanap ng pinakasimpleng?

Timothy Truckle 07/27/2017.

Kailan mo isusulat ang "real" code sa TDD?

Ang red yugto ay kung saan write ka ng code.

Sa phase refactoring ang pangunahing layunin ay upang delete code.

Sa red phase gumawa ka ng anumang bagay upang gawin ang pagsubok pass as quick as possible at at any cost . Lubos mong binabalewala kung ano ang narinig mo sa mga mahusay na coding na kasanayan o pattern ng disenyo nang magkapareho. Ang paggawa ng pagsubok na berde ay lahat na mahalaga.

Sa phase refactoring mong linisin ang gulo mo lang ginawa. Ngayon mo munang tingnan kung ang pagbabago na iyong ginawa lamang ang uri ng pinakamataas na listahan sa Listahan ng Mahalagang Pagbabago at kung mayroong anumang duplicate na code na maaari mong alisin ang malamang sa pamamagitan ng pag-aaplay ng patter na disenyo.

Sa wakas ay nagpapabuti ka sa pagiging madaling mabasa sa pamamagitan ng mga identifier ng pagpapalit ng pangalan at kunin ang mga magic numbers at / o mga literal na string sa mga constants.


Hindi ito red-refactor, ito ay red-green-refactor. - Rob Kinyon

Salamat sa pagturo sa ito.

Kaya't ito ay ang green bahagi kung saan isinusulat mo ang real code

Sa red yugto isinulat mo ang mga executable specification ...

2 comments
Rob Kinyon 07/27/2017
Hindi ito red-refactor, ito ay red-green-refactor. Ang "pula" ay kukuha ka ng iyong test suite mula sa berde (lahat ng mga pagsusulit ay pumasa) sa pula (isang pagsubok ay nabigo). Ang "luntian" ay kung saan mo dalhin ang iyong test suite mula sa pula (isang pagsubok ay nabigo) sa berde (lahat ng mga pagsusulit ay pumasa). Ang "refactor" ay kung saan mo kinukuha ang iyong code at gawin itong medyo habang pinapanatili ang lahat ng mga pagsubok na dumadaan.
Timothy Truckle 07/27/2017
@RobKinyon Salamat, na-update ang sagot.

Robert Andrzejuk 07/27/2017.

Nagsusulat ka ng Real Code sa buong oras.

Sa bawat hakbang Nagsusulat ka ng code upang bigyang-kasiyahan ang mga kondisyon na gagawin ng iyong code para sa mga tumatawag sa hinaharap ng iyong code (na maaaring Ikaw o hindi ...).

Sa palagay mo Hindi ka sumusulat ng usefull ( real ) code, dahil sa isang sandali maaari mong refactor ito.

Ang Code-Refactoring ay ang proseso ng restructuring umiiral na computer code-pagbabago ng factoring-nang hindi binabago ang panlabas na pag-uugali nito.

Ang ibig sabihin nito ay kahit na binago mo ang code, ang mga kondisyon na code satisified, ay naiwan hindi nagbabago. At ang mga tseke (mga tests ) na ipinatupad mo upang i-verify ang iyong code ay naroroon upang mapatunayan kung ang iyong mga pagbabago ay nagbago ng anumang bagay. Kaya ang code na isinulat mo ang buong oras ay nasa doon, sa ibang paraan lamang.

Ang isa pang dahilan Maaari mong isipin na hindi ito tunay na code, ay gumagawa ka ng mga halimbawa kung saan ang iyong programang pangwakas ay maaring makita mo. Ito ay napakabuti, dahil ipinakikita nito na mayroon kang kaalaman tungkol sa domain Ikaw ay programming sa.
Ngunit maraming beses na ang mga programmer ay nasa isang domain na new , unknown sa kanila. Hindi nila alam kung anong resulta ang magiging resulta at ang TDD ay isang technique upang isulat ang mga programms sa bawat hakbang, nakadokumento sa aming knowledge tungkol sa kung paano dapat magtrabaho ang system na ito at tiyakin na ang aming code ay gumagana sa ganoong paraan.

Kapag binasa ko ang Book (*) sa TDD, para sa akin ang pinakamahalagang tampok na nakatayo ay ang: listahan ng TODO. Ipinakita nito sa akin na, ang TDD ay isang pamamaraan upang tulungan ang mga nag-develop na magtuon ng pansin sa isang bagay sa isang pagkakataon. Kaya ito ay isang sagot din sa Iyong tanong aboout How much Real code to write ? Gusto kong magsabi ng sapat na code upang tumutok sa 1 bagay sa isang pagkakataon.

(*) "Test Driven Development: Sa Halimbawa" ni Kent Beck

1 comments
2 Robert Andrzejuk 07/27/2017
"Test Driven Development: By Example" ni Kent Beck

Zenilogix 07/31/2017.

Hindi ka nagsusulat ng code upang mabigo ang iyong mga pagsusulit.

Isulat mo ang iyong mga pagsubok upang tukuyin kung anong tagumpay ang dapat magmukhang, na dapat lahat ay mabigo sa simula dahil hindi mo pa isinulat ang code na ipapasa.

Ang buong punto tungkol sa pagsusulat ng mga pagsusulit sa simula pa lamang ay ang gumawa ng dalawang bagay:

  1. Takpan ang lahat ng kaso - lahat ng mga nominal na kaso, lahat ng kaso ng gilid, atbp.
  2. Patunayan ang iyong mga pagsusulit. Kung nakikita mo lamang ang mga ito, paano mo matitiyak na mapagkakatiwalaan silang mag-ulat ng kabiguan kapag naganap ang isang tao?

Ang punto sa likod ng red-green-refactor ay ang pagsusulat ng mga tamang pagsusulit ay unang nagbibigay sa iyo ng tiwala upang malaman na ang code na iyong isinulat upang pumasa sa mga pagsusulit ay tama, at pinapayagan kang refactor na may tiwala na ipaalam sa iyo ng iyong mga pagsubok sa lalong madaling panahon may sira, kaya agad mong babalik at ayusin ito.

Sa aking sariling karanasan (C # /. NET), ang dalisay na pagsubok-una ay isang bit ng isang hindi matupad na perpekto, dahil hindi mo maaaring itala ang isang tawag sa isang paraan na hindi pa umiiral. Kaya ang "test first" ay talagang tungkol sa coding up interface at stubbing pagpapatupad muna, at pagkatapos pagsusulat ng mga pagsubok laban sa stubs (na kung saan ay sa simula mabigo) hanggang sa stubs ay maayos fleshed out. Hindi ko sinulat ang "kabiguang code", na nagtatayo lamang mula sa mga stub.


Zan Lynx 07/27/2017.

Sa palagay ko ay maaaring malito ka sa pagitan ng mga pagsusulit ng yunit at pagsusulit ng pagsasama. Naniniwala ako na maaaring may mga pagsusulit na pagtanggap, ngunit depende ito sa iyong proseso.

Sa sandaling nasubukan mo ang lahat ng maliit na "unit" pagkatapos mong subukan ang lahat ng ito ay binuo, o "isinama." Karaniwang iyon ang isang buong programa o library.

Sa code na isinulat ko ang mga pagsusulit sa pagsasama ng isang library na may iba't ibang mga programang pagsubok na nagbabasa ng data at ini-feed ito sa library, pagkatapos ay suriin ang mga resulta. Pagkatapos ay ginagawa ko ito sa mga thread. Pagkatapos ay ginagawa ko ito sa mga thread at tinidor () sa gitna. Pagkatapos ay patakbuhin ko ito at patayin -9 pagkatapos ng 2 segundo, pagkatapos ay sisimulan ko ito at suriin ang mode na pagbawi nito. I-fuzz ito. Pinagsasakit ko ito sa lahat ng uri ng mga paraan.

Ang lahat ng iyon ay ALSO testing, ngunit wala akong magandang red / green display para sa mga resulta. Ito ay alinman sa magtagumpay, o humukay ako sa pamamagitan ng ilang libong linya ng error code upang malaman kung bakit.

Iyon ay kung saan mo sinubukan ang "tunay na code."

At naisip ko lang ito, pero baka hindi mo alam kung kailan ka dapat gawin pagsusulat ng pagsusulit sa yunit. Nagawa mo na pagsusulat ng mga pagsusulit sa yunit kapag ang iyong mga pagsubok ay nag-ehersisyo ang lahat ng bagay na iyong tinukoy na dapat gawin. Minsan maaari mong mawala ang track ng mga iyon sa lahat ng mga error sa paghawak at mga kaso ng gilid, kaya baka gusto mong gumawa ng isang magandang grupo ng pagsubok ng masaya mga pagsubok ng landas na lamang pumunta diretso sa pamamagitan ng mga pagtutukoy.

1 comments
Peter Mortensen 07/27/2017
(nito = nagmamay-ari, ito ay = "ito ay" o "mayroon." Tingnan ang halimbawa How to Use Its and It's .)

user3791372 07/27/2017.

Bilang sagot sa pamagat ng tanong: "Kailan mo isusulat ang" totoong "code sa TDD?", Ang sagot ay: 'halos hindi' o 'napakabagal'.

Tiyak na parang isang mag-aaral, kaya sasagutin ko na parang nagpapayo sa isang mag-aaral.

Matututunan mo ang maraming mga 'teoryang' at 'mga diskarte' ng coding. Mahusay ang mga ito para sa pagpasa ng oras sa mga overpriced na mga kurso ng mag-aaral, ngunit napakaliit na kapakinabangan sa iyo na hindi mo mabasa sa isang libro sa kalahating oras.

Ang trabaho ng isang coder ay tanging upang gumawa ng code. Ang code na gumagana talagang mahusay. Iyon ang dahilan kung bakit ka, ang tagapagkodigo ay nagplano ng code sa iyong isip, sa papel, sa angkop na aplikasyon, at iba pa, at plano mong magtrabaho sa paligid ng posibleng mga bahid / butas nang maaga sa pamamagitan ng pag-iisip nang lohikal at laterally bago coding.

Ngunit kailangan mong malaman kung paano masira ang iyong aplikasyon upang ma-disenyo ang disenteng code. Halimbawa, kung hindi mo alam ang tungkol sa Little Bobby Table (xkcd 327), malamang na hindi mo sanitizing ang iyong mga input bago magtrabaho sa database, kaya hindi mo ma-secure ang iyong data sa paligid ng konsepto na iyon.

TDD ay isang workflow na dinisenyo upang mabawasan ang mga bug sa iyong code sa pamamagitan ng paglikha ng mga pagsubok ng kung ano ang maaaring magkamali bago mo code ang iyong application dahil coding maaaring makakuha ng exponentially mahirap ang higit pang code ipakilala mo at nakalimutan mo ang mga bug na iyong naisip ng isang beses. Sa sandaling naiisip mo na natapos mo na ang iyong application na nagpapatakbo ka ng mga pagsubok at boom, sana ay nakuha ang mga bug sa iyong mga pagsubok.

TDD ay hindi - tulad ng ilang mga tao ay naniniwala - magsulat ng isang pagsubok, makakuha ng pagpasa na may minimal code, magsulat ng isa pang pagsubok, makakuha ng na pagpasa na may minimal na code, atbp Sa halip, ito ay isang paraan ng pagtulong sa iyo code confidently. Ang perpektong ito ng tuloy-tuloy na code ng pag-refresh upang magawa ito sa mga pagsusulit ay walang silbi, ngunit ito ay isang magandang konsepto sa gitna ng mga mag-aaral sapagkat ito ay ginagawang pakiramdam nila mahusay kapag nagdadagdag sila ng bagong tampok at natututo pa rin ...

Mangyaring huwag mahulog ang bitag na ito at tingnan ang iyong papel ng coding para sa kung ano ito - ang trabaho ng isang tagapagkodigo ay para lamang gumawa ng code. Ang code na gumagana talagang mahusay. Ngayon, tandaan na ikaw ay nasa orasan bilang isang propesyonal na tagapagkodigo, at ang iyong kliyente ay hindi aalagaan kung sinulat mo ang 100,000 assertions, o 0. Gusto lang nila ang code na gumagana. Talagang mahusay, sa katunayan.

5 comments
3 johnny 07/25/2017
Hindi ako malapit sa isang mag-aaral, ngunit nabasa ko at sinubukan na mag-aplay ng mga mahusay na pamamaraan at maging propesyonal. Kaya sa ganitong kahulugan, ako ay isang "mag-aaral." Nagtanong lang ako ng mga pangunahing tanong dahil iyon ang paraan ko. Gusto kong malaman eksakto kung bakit ginagawa ko ang ginagawa ko. Ang puso ng bagay. Kung hindi ko makuha iyon, hindi ko gusto ito at magsimulang magtanong. Kailangan kong malaman kung bakit, kung gagamitin ko ito. Ang TDD ay parang intuitively mabuti sa ilang mga paraan tulad ng alam kung ano ang kailangan mo upang lumikha at pag-iisip ng mga bagay sa pamamagitan ng, ngunit ang pagpapatupad ay mahirap maunawaan. Sa tingin ko mayroon akong mas mahusay na hawakang mahigpit ngayon.
4 Sean Burton 07/27/2017
Iyon ang mga patakaran ng TDD. Malaya kang magsulat ng code gayunpaman gusto mo, ngunit kung hindi mo sinunod ang tatlong patakarang hindi mo ginagawa TDD.
2 user3791372 07/27/2017
"Panuntunan" ng isang tao? Ang TDD ay isang mungkahi upang tulungan kang code, hindi isang relihiyon. Ito ay malungkot upang makita ang napakaraming mga tao na sumunod sa isang ideya kaya anally. Kahit na ang pinagmulan ng TDD ay kontrobersyal.
2 Alex 07/28/2017
@ user3791372 TDD ay isang napaka-mahigpit at malinaw na tinukoy na proseso. Kahit na marami ang nag-iisip na ang ibig sabihin ay "Gawin ang ilang pagsubok kapag ikaw ay programming", hindi. Let's subukan na hindi pagsamahin ang mga tuntunin dito, ang tanong na ito ay tungkol sa proseso TDD, hindi pangkalahatang pagsubok.

Related questions

Hot questions

Language

Popular Tags