Testimisel põhinev arendus

Testimisel põhinev arendus (inglise keeles "test-driven development", lühend "TDD") on tarkvaraarenduse meetod, kus testid kirjutatakse enne tarkvara ennast. Arendusprotsess koosneb lühikestest iteratsioonidest, kus esmalt kirjutatakse ebaõnnestuv test ning seejärel minimaalne kood, et see test läbi läheks. Selline arendus tagab olukorra, kus kogu kood on alati testitud. Sellisel viisil kirjutatud koodi on kergem refaktoreerida ning testid aitavad ka programmi eeldatavat käitumist dokumenteerida. Testimisel põhinevat arendust rakendatakse ka olemasoleva koodi täiustamisel ja silumisel.
Testimisel põhineva arenduse loojaks või taasavastajaks peetakse USA tarkvaraarendajat Kent Becki. Ta väidab, et testimisel põhinev arendus aitab luua lihtsa disainiga tarkvara ja tõstab selle usaldusväärsust. Testimisel põhinev arendus on muutunud populaarsemaks ning selle vastu tuntakse üha enam huvi ka suurtes ettevõtetes.
Testimisel põhineva arenduse tsükkel.
Järgnev tsükkel põhineb raamatul "Test-Driven Development by Example".
Testimisel põhinev arendus algab uue testi kirjutamisega. Test peab defineerima ühe funktsiooni või mõnda funktsiooni täiustama. Testi kirjutajal peab olema selge arusaam nõuetest testitavale funktsionaalsusele. Testimisel põhinev arendus sunnib seega arendajat tutvuma rakenduse nõudmistega enne koodi kirjutamist.
Selle sammu eesmärk on veenduda, et testid töötavad nii, nagu ette nähtud. Oluline on, et lisatud uus test ei lähe läbi. See näitab, et testitavat funktsiooni veel ei eksisteeri ning seega on vaja koodi kirjutades see implementeerida. Arendaja saab olla kindel, et test ebaõnnestus eeldataval põhjusel. Lisaks välistab see samm võimaluse, et uus test läheb alati läbi.
Eesmärk on kirjutada kood nii, et test läbi läheks. Kirjutatav kood ei pea olema veel lõplik ja rahuldav. Seda koodi täiustatakse viienda sammu juures. Testi õnnestumine on selles sammus kirjutatava koodi ainuke eesmärk. See kood ei tohi teha midagi muud.
Kui kõik testid koos uue testiga läbi lähevad, võib arendaja kindel olla, et kirjutatud kood vastab testitavatele nõuetele ega muuda olemasolevat koodi. Kui kõik testid läbi ei lähe, peab muutma lisatud koodi seni, kuni testid jälle läbi lähevad.
Kuna nüüd on olemas test, mis kontrollib õiget käitumist, saab pärast koodi muutmist veenduda, et kogu kood endiselt töötab. Uus kood tuleb nüüd korrastada, et parandada koodi loetavust ja hallatavust.
Testimisel põhinev arendus koosneb selliste tsüklite kordamisest. Igas sammus tehtud muudatuste hulk peaks olema väike, koosnedes 1–10 muudatusest. Sellisel juhul on testide läbikukkumise korral arendajal kerge vigu leida ja parandada. Väliseid teeke kasutades peab veenduma, et testi ei testiks teegi funktsionaalsust, välja arvatud juhul, kui teegi usaldusväärsus on kaheldav.
Eelised.
2005. aastal tehtud uuringu käigus leiti, et testimisel põhinev arendus suurendas programmeerijate produktiivsust, kuna nad kirjutasid rohkem teste. Testimisel põhinev arendus aitab lisaks valideerimisele ka tarkvara disainida. Kuna arendajad kirjutavad teste enne koodi, siis peavad nad enne läbi mõtlema, kuidas arendatavat funktsionaalsust kasutatakse. Seega keskendutakse enne liidesele ja alles siis implementatsioonile.
Testimisel põhineva arenduse käigus kirjutatakse kood väikeste osade kaupa. See aitab arendajal keskenduda ühele eesmärgile, erindid ja vigadega tegelemine tuleb implementatsioonile juurde alles siis, kui mõni test neid nõuab. Sellisel viisil kirjutatud kood on alati kaetud vähemalt ühe testiga, mis tõstab koodi usaldusväärsust.
Testimisel põhinev arendus nõuab suurema hulga koodi kirjutamist, kuna testide arv on kõrge. Müller ja Padberg väidavad, et sellest hoolimata võib kogu koodi kirjutamiseks kuluv aeg olla lühem. Suur kogus teste aitab piirata vigade arvu koodis. Varases staadiumis leitud vigu on kergem ja odavam parandada ning see võimaldab vältida keerulisi silumisprotsesse.
Kuna testimisel põhinev arendus nõuab, et arendajad teeksid korraga väikseid muudatusi, tagab see modulaarsema ja paindlikuma koodi, mida on kerge edasi arendada. Tekkivad klassid, funktsioonid ja liidesed on väiksemad, loetavamad ja konkreetsemad.
Puudused.
Testimisel põhinev arendus ei pruugi alati piisavalt funktsionaalsust testida, kuna kasutatakse ainult ühikteste. Selline olukord tekib, kui on vaja testida kasutajaliideseid, tööd andmebaasidega või kindlaid võrgukonfiguratsioone. Kuna testid ja kood on enamasti sama arendaja kirjutatud, võivad ühe arendaja vead koodi sisse jääda. Üks arendaja võib unustada mõne olukorra testimise. Samuti võib olla arusaamatusi nõudmiste osas, mis võib viia testideni, mis lähevad läbi, aga ei testi eeldatavat käitumist.
Testide haldamine võib muutuda kulukaks ja aeganõudvaks, kui need on halvasti implementeeritud või vigased.