JavaRush /Java Blog /Random-TL /Ano ang TDD at unit testing [pagsasalin]
Dr-John Zoidberg
Antas
Марс

Ano ang TDD at unit testing [pagsasalin]

Nai-publish sa grupo
Ang artikulong ito ay isang adaptasyon ng isang kabanata mula sa aklat na The Complete Software Career Guide. Ang may-akda nito, si John Sonmez, ay sumulat nito at nag-post ng ilang mga kabanata sa kanyang website.
Ano ang TDD at unit testing [pagsasalin] - 1

Isang maikling glossary para sa mga nagsisimula

Ang unit testing o unit testing ay isang proseso sa programming na nagbibigay-daan sa iyong suriin ang mga indibidwal na module ng source code ng isang program para sa kawastuhan. Ang ideya ay sumulat ng mga pagsubok para sa bawat hindi walang kuwentang function o pamamaraan. Ang regression testing ay isang pangkalahatang pangalan para sa lahat ng uri ng software testing na naglalayong makakita ng mga error sa nasubok nang mga lugar ng source code. Ang ganitong mga error - kapag, pagkatapos gumawa ng mga pagbabago sa programa, ang isang bagay na dapat magpatuloy sa trabaho ay huminto sa paggana - ay tinatawag na mga error sa regression. Pulang resulta, nabigo - kabiguan ng pagsubok. Ang pagkakaiba sa pagitan ng inaasahang resulta at ang aktwal na resulta. Berdeng resulta, pumasa - positibong resulta ng pagsubok. Ang aktwal na resulta ay hindi naiiba sa kung ano ang nakuha. ***
Ano ang TDD at unit testing [pagsasalin] - 2
Mayroon akong napakahalo-halong relasyon sa Test Driven Development (TDD) at unit testing, mula sa pag-ibig tungo sa poot at muli. Ako ay isang masugid na tagahanga at sa parehong oras ay isang kahina-hinalang may pag-aalinlangan tungkol sa paggamit nito, at iba pang, "pinakamahuhusay na kagawian." Ang dahilan ng aking saloobin ay batay sa katotohanan na lumitaw ang isang seryosong problema sa mga proseso ng pagbuo ng software: ang mga developer, at kung minsan ang mga tagapamahala, ay gumagamit lamang ng ilang mga tool at pamamaraan dahil nabibilang sila sa "pinakamahusay na kasanayan". Ang tunay na dahilan para sa kanilang paggamit ay nananatiling hindi maliwanag. Isang araw nagsimula akong magtrabaho sa isang partikular na proyekto, at sa proseso ay sinabihan ako na babaguhin namin ang code na saklaw ng isang malaking bilang ng mga pagsubok sa yunit. Walang biro, may mga 3000 sa kanila. Karaniwan itong magandang senyales, isang senyales na ang mga developer ay gumagamit ng mga advanced na pamamaraan. Ang code na may ganitong diskarte ay kadalasang nakabalangkas, at ito ay batay sa isang pinag-isipang mabuti na arkitektura. Sa madaling salita, ang pagkakaroon ng mga pagsubok ay nagpasaya sa akin, kung dahil lamang sa ibig sabihin nito ay gawing mas madali ang aking trabaho bilang isang tagapayo ng mga programmer. Dahil mayroon na kaming mga unit test, ang kailangan ko lang gawin ay ikonekta ang development team para suportahan sila at simulan ang pagsusulat ng sarili naming code. Binuksan ko ang IDE (integrated development environment) at ni-load ang proyekto.
Ano ang TDD at unit testing [pagsasalin] - 3
Isa itong malaking proyekto! Nakakita ako ng folder na may label na "unit tests". “Great,” naisip ko. - Ilunsad natin ito at tingnan kung ano ang mangyayari. Ilang minuto lang ang itinagal, at sa aking sorpresa, lahat ng pagsusulit ay pumasa, lahat ay berde ( "berde" ay isang positibong resulta ng pagsubok. Mga senyales na ang code ay gumagana tulad ng inaasahan. Ang pula ay nagpapahiwatig ng "pagkabigo" o nabigo, pagkatapos mayroong isang kaso kapag ang code ay hindi gumagana nang tama - tala ng tagasalin ). Lahat sila nakapasa sa pagsusulit. Sa sandaling iyon, nagising ang may pag-aalinlangan sa akin. Paano na, tatlong libong mga pagsubok sa yunit, at kinuha nila ang mga ito nang sabay-sabay - at nagbigay ng isang positibong resulta? Sa aking mahabang pagsasanay, hindi ko matandaan ang isang oras kung kailan nagsimula akong magtrabaho sa isang proyekto nang walang isang negatibong pagsubok sa yunit sa code. Anong gagawin? Suriin nang manu-mano! Pumili si ChY ng isang random na pagsubok, hindi ang pinaka-nakikita, ngunit agad na malinaw kung ano ang kanyang sinusuri. Ngunit habang ginagawa ito, napansin ko ang isang bagay na walang katotohanan: ang pagsubok ay hindi naglalaman ng anumang mga paghahambing sa inaasahang resulta (iginiit)! Iyon ay, sa katotohanan ay walang nasuri ! Mayroong ilang mga hakbang sa pagsubok, natupad ang mga ito, ngunit sa pagtatapos ng pagsubok, kung saan dapat niyang ihambing ang aktwal at inaasahang resulta, walang tseke. Ang "pagsubok" ay hindi sumubok ng anuman. Binuksan ko ang isa pang pagsubok. Mas mabuti pa: ang operator ng paghahambing na may resulta ay nagkomento. Napakatalino! Ito ay isang mahusay na paraan upang gumawa ng isang test pass, ikomento lamang ang code na nagiging sanhi ng pagkabigo nito. I checked another test, then another... Wala sa kanila ang nag-check ng kahit ano. Tatlong libong pagsubok, at lahat ng mga ito ay ganap na walang silbi. Malaki ang pagkakaiba sa pagitan ng pagsusulat ng mga unit test at pag-unawa sa unit testing at test-driven development (TDD).

Ano ang unit testing?

Ano ang TDD at unit testing [pagsasalin] - 4
Ang pangunahing ideya ng pagsubok sa yunit ay ang pagsulat ng mga pagsubok na sumusubok sa pinakamaliit na "unit" ng code. Ang mga unit test ay karaniwang nakasulat sa parehong programming language bilang source code ng application. Direktang nilikha ang mga ito upang subukan ang code na ito. Ibig sabihin, ang mga unit test ay code na sumusuri sa kawastuhan ng ibang code. Ginagamit ko ang salitang "pagsubok" sa konteksto, dahil ang mga unit test sa ilang kahulugan ay hindi mga pagsubok. Wala silang nararanasan. Ang ibig kong sabihin ay kapag nagpatakbo ka ng isang unit test ay hindi mo karaniwang makikita na ang ilang code ay hindi gumagana. Natuklasan mo ito habang isinusulat ang pagsubok, dahil babaguhin mo ang code hanggang sa maging berde ang pagsubok. Oo, maaaring magbago ang code sa ibang pagkakataon at pagkatapos ay mabibigo ang iyong pagsubok. Kaya sa ganitong kahulugan, ang isang unit test ay isang regression test. Ang isang unit test ay hindi tulad ng isang normal na pagsubok kung saan mayroon kang ilang hakbang na iyong susundin at makikita mo kung gumagana nang tama ang software o hindi. Sa proseso ng pagsusulat ng unit test, matutuklasan mo kung ginagawa ng code ang dapat nitong gawin o hindi, at babaguhin mo ang code hanggang sa pumasa ang pagsubok.
Ano ang TDD at unit testing [pagsasalin] - 5
Bakit hindi sumulat ng unit test at suriin kung pumasa ito? Kung iisipin mo ito sa ganitong paraan, ang mga unit test ay magiging ilang uri ng ganap na kinakailangan para sa ilang mga module ng code sa napakababang antas. Maaari mong isipin ang isang unit test bilang isang ganap na detalye . Tinutukoy ng isang unit test na sa ilalim ng mga kundisyong ito, sa partikular na hanay ng mga input na ito, mayroong isang output na dapat mong makuha mula sa unit ng code na ito. Tinutukoy ng true unit testing ang pinakamaliit na magkakaugnay na unit ng code, na sa karamihan ng mga programming language - kahit man lang object-oriented - ay isang klase.

Ano ang tinatawag minsan na pagsubok sa yunit?

Ano ang TDD at unit testing [pagsasalin] - 6
Ang pagsubok sa yunit ay kadalasang nalilito sa pagsubok sa pagsasama. Sinusubukan ng ilang "mga unit test" ang higit sa isang klase o sumusubok ng malalaking unit ng code. Sinasabi ng maraming developer na nagsusulat sila ng mga unit test kung sa katunayan ay nagsusulat sila ng mga mababang antas ng whitebox test. Huwag makipagtalo sa mga lalaking ito. Alamin lang na talagang sumusulat sila ng mga integration test, at ang mga true unit test ay sumusubok sa pinakamaliit na unit ng code sa paghihiwalay mula sa ibang mga bahagi. Ang isa pang bagay na madalas na tinatawag na unit testing ay ang mga unit test nang hindi sinusuri ang isang inaasahang halaga. Sa madaling salita, mga unit test na hindi talaga sumusubok ng anuman. Anumang pagsubok, unitized man o hindi, ay dapat magsama ng ilang uri ng verification - tinatawag namin itong pagsuri sa aktwal na resulta laban sa inaasahang resulta. Ang pagkakasundo na ito ang nagpapasiya kung ang pagsusulit ay pumasa o nabigo. Ang pagsubok na laging dumadaan ay walang silbi. Ang pagsubok na laging nabibigo ay walang silbi.

Ang Halaga ng Unit Testing

Bakit ako isang unit testing enthusiast? Bakit nakakapinsalang tawagan ang pangkalahatang pagsubok, na nagsasangkot ng pagsubok hindi sa pinakamaliit na bloke na nakahiwalay sa ibang code, ngunit isang mas malaking piraso ng code, "pagsusuri sa yunit"? Ano ang problema kung ang ilan sa aking mga pagsubok ay hindi nagkukumpara sa natanggap at inaasahang resulta? Hindi bababa sa ini-execute nila ang code. Susubukan kong ipaliwanag.
Ano ang TDD at unit testing [pagsasalin] - 7
Mayroong dalawang pangunahing dahilan para sa pagsasagawa ng unit testing. Ang una ay upang mapabuti ang disenyo ng code. Tandaan kung paano ko sinabi na ang pagsubok sa yunit ay hindi talagang pagsubok? Kapag nagsusulat ka ng mga tamang unit test, pinipilit mo ang iyong sarili na ihiwalay ang pinakamaliit na unit ng code. Ang mga pagtatangka na ito ay magdadala sa iyo upang matuklasan ang mga problema sa istruktura ng code mismo. Maaaring napakahirap mong ihiwalay ang klase ng pagsubok at hindi isama ang mga dependency nito, at maaari nitong mapagtanto na ang iyong code ay masyadong mahigpit na pinagsama. Maaari mong makita na ang pangunahing functionality na sinusubukan mong subukan ay sumasaklaw sa maraming module, na humahantong sa iyong maniwala na ang iyong code ay hindi sapat na magkakaugnay. Kapag umupo ka para magsulat ng unit test, maaari mong biglang matuklasan (at maniwala ka sa akin, mangyayari ito!) na wala kang ideya kung ano ang dapat gawin ng code. Alinsunod dito, hindi ka makakasulat ng unit test para dito. At siyempre, maaari kang makakita ng totoong bug sa pagpapatupad ng code, dahil pinipilit ka ng unit test na mag-isip sa labas ng kahon at subukan ang iba't ibang hanay ng mga input na maaaring hindi mo naisip.
Ano ang TDD at unit testing [pagsasalin] - 8
Kung mahigpit mong susundin ang panuntunan ng "subukan ang pinakamaliit na yunit ng code sa paghihiwalay mula sa iba" kapag gumagawa ng mga pagsubok sa yunit, tiyak na mahahanap mo ang lahat ng uri ng mga problema sa code na iyon at sa disenyo ng mga module na iyon. Sa ikot ng buhay ng pagbuo ng software, ang pagsubok sa yunit ay higit na isang aktibidad sa pagsusuri kaysa sa isang aktibidad sa pagsubok. Ang pangalawang pangunahing layunin ng unit testing ay ang lumikha ng isang automated na set ng mga regression test na maaaring kumilos bilang isang mababang antas na detalye ng pag-uugali ng software. Ano ang ibig sabihin nito? Kapag minasa mo ang kuwarta, hindi mo ito masira. Mula sa puntong ito ng view, ang mga unit test ay mga pagsubok, mas partikular na mga regression test. Gayunpaman, ang layunin ng pagsubok sa yunit ay hindi lamang upang bumuo ng mga pagsubok sa pagbabalik. Sa pagsasagawa, ang mga unit test ay bihirang makakuha ng mga regression, dahil ang isang pagbabago sa unit ng code na iyong sinusubok ay halos palaging naglalaman ng mga pagbabago sa unit test mismo. Ang pagsubok ng regression ay mas epektibo sa mas mataas na antas, kapag ang code ay nasubok bilang isang "itim na kahon", dahil sa antas na ito ang panloob na istraktura ng code ay maaaring baguhin, habang ang panlabas na pag-uugali ay inaasahang mananatiling pareho. Sinusuri naman ng mga unit test ang panloob na istraktura, upang kapag nagbago ang istrukturang iyon, hindi mabibigo ang mga pagsubok sa yunit. Nagiging hindi na magamit ang mga ito at ngayon ay kailangang baguhin, itapon o muling isulat. Mas alam mo na ngayon ang tungkol sa tunay na layunin ng pagsubok ng unit kaysa sa maraming beteranong software developer.

Ano ang Test Driven Development (TDD)?

Ano ang TDD at unit testing [pagsasalin] - 9
Sa proseso ng pagbuo ng software, ang isang mahusay na detalye ay katumbas ng timbang nito sa ginto. Ang diskarte ng TDD ay bago ka magsulat ng anumang code, sumulat ka muna ng isang pagsubok na magsisilbing isang detalye, iyon ay, tukuyin kung ano ang dapat gawin ng code. Ito ay isang napakalakas na konsepto ng pag-develop ng software, ngunit madalas itong maling ginagamit. Karaniwan, ang ibig sabihin ng pag-develop na hinimok ng pagsubok ay ang paggamit ng mga unit test upang gabayan ang paglikha ng code ng application. Ngunit sa katunayan, ang diskarte na ito ay maaaring ilapat sa anumang antas. Gayunpaman, sa artikulong ito ay ipagpalagay namin na gumagamit kami ng pagsubok sa yunit para sa aming aplikasyon. Ang diskarte ng TDD ay ibinabalik ang lahat sa ulo nito, at sa halip na magsulat muna ng code at pagkatapos ay magsulat ng mga pagsubok sa yunit upang subukan ang code na iyon, sumulat ka muna ng isang pagsubok sa yunit at pagkatapos ay sumulat ng code upang gawing berde ang pagsubok na iyon. Sa ganitong paraan, ang pagsubok ng unit ay "nagtutulak" sa pagbuo ng code. Ang prosesong ito ay paulit-ulit. Sumulat ka ng isa pang pagsubok na tumutukoy sa higit pang paggana kung ano ang dapat gawin ng code. Pagkatapos ay isulat at baguhin mo ang code upang matiyak na matagumpay na nakumpleto ang pagsubok. Kapag mayroon kang berdeng resulta, sisimulan mong i-refactor ang code, iyon ay, refactoring o linisin ito upang gawin itong mas maigsi. Ang hanay ng mga prosesong ito ay madalas na tinatawag na "Red-Green-Refactoring" dahil una ay nabigo ang unit test (pula), pagkatapos ay isinulat ang code upang umangkop sa pagsubok, tinitiyak na ito ay magtagumpay (berde), at sa wakas ang code ay na-optimize ( refactoring). .

Ano ang layunin ng TDD?

Ano ang TDD at unit testing [pagsasalin] - 10
Maaaring gamitin nang hindi tama ang test-driven development (TDD), tulad ng unit testing. Napakadaling tawagin ang iyong ginagawa na "TDD" at kahit na sundin ang pagsasanay nang hindi nauunawaan kung bakit mo ito ginagawa sa ganoong paraan. Ang pinakamalaking halaga ng TDD ay ang mga pagsubok ay isinasagawa upang makagawa ng mga detalye ng kalidad. Ang TDD ay mahalagang kasanayan sa pagsulat ng mga tumpak na detalye na maaaring awtomatikong suriin bago isulat ang coding. Ang mga pagsubok ay ang pinakamahusay na mga detalye dahil hindi sila nagsisinungaling. Hindi nila sasabihin sa iyo pagkatapos ng dalawang linggong pagdurusa kasama ang code na "hindi iyon ang ibig kong sabihin." Ang mga pagsusulit, kapag naisulat nang tama, maaaring pumasa o mabibigo. Ang mga pagsusulit ay malinaw na nagpapahiwatig kung ano ang dapat mangyari sa ilalim ng ilang mga pangyayari. Kaya, ang layunin ng TDD ay bigyan tayo ng kumpletong pag-unawa sa kung ano ang kailangan nating ipatupad bago natin simulan ang pagpapatupad nito. Kung nagsisimula ka sa TDD at hindi mo malaman kung ano ang dapat subukan ng pagsubok, kailangan mong magtanong ng higit pang mga tanong. Ang isa pang mahalagang papel ng TDD ay upang mapanatili at i-optimize ang code. Mahal ang pagpapanatili ng code. Madalas kong biro na ang pinakamahusay na programmer ay ang nagsusulat ng pinakamaikling code na lumulutas ng ilang problema. O kahit na ang nagpapatunay na ang problemang ito ay hindi kailangang malutas, at sa gayon ay ganap na tinanggal ang code, dahil ang programmer na ito ang nakahanap ng tamang paraan upang bawasan ang bilang ng mga error at bawasan ang gastos ng pagpapanatili ng application. Sa pamamagitan ng paggamit ng TDD, maaari kang maging ganap na sigurado na hindi ka nagsusulat ng anumang hindi kinakailangang code, dahil magsusulat ka lamang ng code upang makapasa sa mga pagsusulit. Mayroong isang prinsipyo ng pagbuo ng software na tinatawag na YAGNI (hindi mo ito kakailanganin). Pinipigilan ng TDD ang YAGNI.

Karaniwang Test Driven Development (TDD) Workflow

Ano ang TDD at unit testing [pagsasalin] - 11
Ang pag-unawa sa kahulugan ng TDD mula sa isang purong akademikong pananaw ay mahirap. Kaya tingnan natin ang isang halimbawa ng session ng TDD. Isipin na nakaupo sa iyong desk at mabilis na nag-sketch ng kung ano sa tingin mo ay isang mataas na antas na disenyo para sa isang tampok na nagbibigay-daan sa isang user na mag-log in sa isang application at baguhin ang kanilang password kung makalimutan nila ito. Magpasya ka na magsisimula ka sa unang pagpapatupad ng function ng pag-login, na lumilikha ng isang klase na hahawak sa lahat ng lohika para sa proseso ng pag-login. Binuksan mo ang iyong paboritong editor at lumikha ng isang pagsubok sa yunit na tinatawag na "Pinipigilan ng walang laman na pag-log in ang user na mag-log in." Sumulat ka ng unit test code na unang lumilikha ng isang instance ng klase sa Pag-login (na hindi mo pa nagagawa). Sumusulat ka pagkatapos ng code upang tumawag sa isang paraan sa klase sa Pag-login na nagpapasa ng walang laman na username at password. Sa wakas, sumulat ka ng tseke laban sa inaasahang resulta, tinitingnan na ang user na may walang laman na pag-login ay talagang hindi naka-log in. Sinusubukan mong magpatakbo ng isang pagsubok, ngunit hindi ito nag-compile dahil wala kang klase sa Pag-login. Inaayos mo ang sitwasyong ito at lumikha ng isang klase sa Pag-login kasama ang isang paraan sa klase na iyon upang mag-log in at isa pa upang suriin ang katayuan ng gumagamit upang makita kung sila ay naka-log in. Sa ngayon ay hindi mo pa ipinatupad ang functionality ng klase na ito at ang pamamaraan na kailangan namin. Pinapatakbo mo ang pagsubok sa puntong ito. Ngayon ay nag-compile ito, ngunit agad na nabigo.
Ano ang TDD at unit testing [pagsasalin] - 12
Ngayon ay babalik ka sa code at ipatupad ang functionality upang makapasa sa pagsubok. Sa aming kaso, nangangahulugan ito na dapat naming makuha ang resulta: "ang user ay hindi naka-log in." Patakbuhin mo muli ang pagsubok at ngayon ay pumasa ito. Lumipat tayo sa susunod na pagsubok. Ngayon isipin natin na kailangan mong magsulat ng isang pagsubok na tinatawag na "Ang user ay naka-log in kung nagpasok sila ng wastong username at password." Sumulat ka ng isang unit test na nagpapakilala sa klase sa Pag-login at sumusubok na mag-log in gamit ang isang username at password. Sa isang unit test, sumulat ka ng isang pahayag na ang klase sa Pag-login ay dapat sumagot ng oo sa tanong kung ang user ay naka-log in. Pinapatakbo mo ang bagong pagsubok na ito at siyempre nabigo ito dahil ang iyong klase sa Pag-login ay palaging nagbabalik na ang gumagamit ay hindi naka-log in. Bumalik ka sa iyong klase sa Pag-login at nagpapatupad ng ilang code para i-verify na naka-log in ang user. Sa kasong ito, kakailanganin mong malaman kung paano ihiwalay ang modyul na ito. Sa ngayon, ang pinakamadaling paraan upang gawin ito ay i-hardcode ang username at password na ginamit mo sa iyong pagsubok, at kung magkatugma ang mga ito, ibalik ang resulta na "naka-log in ang user." Gagawin mo ang pagbabagong ito, patakbuhin ang parehong pagsubok, at pareho silang pumasa. Lumipat tayo sa huling hakbang: titingnan mo ang nabuong code, at maghanap ng paraan upang muling ayusin at pasimplehin ito. Kaya ang TDD algorithm ay:
  1. Nakagawa ng pagsubok.
  2. Sumulat kami ng code para sa pagsubok na ito.
  3. Ni-refactor ang code.

mga konklusyon

Ano ang TDD at unit testing [pagsasalin] - 13
Iyon lang ang gusto kong sabihin sa iyo tungkol sa unit testing at TDD sa yugtong ito. Sa katunayan, maraming mga paghihirap na nauugnay sa pagsubok na ihiwalay ang mga module ng code, dahil ang code ay maaaring maging napaka-kumplikado at nakakalito. Napakakaunting mga klase ang umiiral sa kumpletong paghihiwalay. Sa halip, mayroon silang mga dependency, at ang mga dependency ay may mga dependency, at iba pa. Para harapin ang mga ganitong sitwasyon, gumagamit ang beterano ng TDD ng mga pangungutya, na tumutulong na ihiwalay ang mga indibidwal na klase sa pamamagitan ng pagpapalit ng mga bagay sa mga nakadependeng module. Ang artikulong ito ay isang pangkalahatang-ideya lamang at medyo pinasimple na panimula sa pagsubok ng yunit at TDD, hindi na kami magdedetalye tungkol sa mga dummy module at iba pang pamamaraan ng TDD. Ang ideya ay ibigay sa iyo ang mga pangunahing konsepto at prinsipyo ng TDD at unit testing na sana ay mayroon ka na ngayon. Orihinal - https://simpleprogrammer.com/2017/01/30/tdd-unit-testing/
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION