# Desenvolupament guiat per proves

Desenvolupament guiat per proves de programari, en anglès: Test-driven development (TDD), és una pràctica d'enginyeria de programari que involucra unes altres dues pràctiques: Escriure les proves primer (Test First Development) i Refacció (Refactoring). Per escriure les proves generalment s'utilitzen les proves unitàries (unit test en anglès). En primer lloc, s'escriu una prova i es verifica que les proves fallen. A continuació, s'implementa el codi que fa que la prova passi satisfactòriament i seguidament es refacciona el codi escrit. El propòsit del desenvolupament guiat per proves és aconseguir un codi net que funcioni. La idea és que els requisits siguin traduïts a proves, d'aquesta manera, quan les proves passin es garantirà que el programari compleix amb els requisits que s'han establert.

## Requisits

Perquè funcioni el desenvolupament guiat per proves, el sistema que es programa ha de ser prou flexible com per permetre que sigui provat automàticament. Cada prova serà suficientment petita com perquè permeti determinar unívocament si el codi provat passa o no la verificació que aquesta li imposa. El disseny es veu afavorit, ja que s'evita l'indesitjat "sobre disseny" de les aplicacions i s'aconsegueixen interfícies més clares i un codi més cohesionat. Frameworks com JUnit proveeixen d'un mecanisme per posar en pràctica conjunts de proves automatitzades.

## Cicle de desenvolupament conduït per proves

En primer lloc s'ha de definir una llista de requisits i després s'executa el següent cicle:
* Triar un requisit: Es tria d'una llista el requisit que es creu que ens donarà un millor coneixement del problema i que alhora sigui fàcilment implementable.
* Escriure una prova: Es comença escrivint una prova per al requisit. Per fer això el programador ha d'entendre clarament les especificacions i els requisits de la funcionalitat que es vol implementar. Aquest pas força al programador a veure les coses des de la perspectiva del client considerant el codi a través de les seves interfícies.
* Verificar que la prova falla: Si la prova no falla és perquè el requisit ja estava implementat o perquè la prova és errònia.
* Escriure la implementació: Escriure el codi més senzill que faci que la prova funcioni. S'usa l'expressió "Deixi-ho simple" ("Keep It Simple, Stupid!"), coneguda com a principi KISS.
* Executar les proves automatitzades: Verificar si tot el conjunt de proves funciona correctament.
* Eliminació de duplicació: El pas final és la refacció, que s'utilitzarà principalment per eliminar codi duplicat. Es fa un petit canvi cada vegada i després es tornen a correr les proves fins que funcionin.
* Actualització de la llista de requisits: S'actualitza la llista de requisits marcant com a assolit el requisit implementat. Així mateix s'agreguen requisits que s'hagin vist com a necessaris durant aquest cicle i s'agreguen requisits de disseny (P. ej que una funcionalitat estigui desacoblada d'una altra).
Tenir un únic repositori universal de proves facilita complementar TDD amb una altra pràctica recomanada pels processos àgils de desenvolupament, la "Integració Contínua". Integrar contínuament el nostre treball amb el de la resta de l'equip de desenvolupament permet executar tota la bateria de proves i així descobrir si la nostra última versió és compatible amb la resta del sistema. És recomanable i menys costós corregir petits problemes cada poques hores que enfrontar-se a problemes enormes prop de la data de lliurament fixada.

## Característiques

Una característica d'aquesta forma de desenvolupar programari és que s'evita escriure codi innecessari ("You Ain't Gonna Need It" (YAGNI)). S'intenta escriure el mínim de codi possible, i si el codi passa una prova encara que sapiguem que és incorrecte ens dona una idea que hem de modificar la nostra llista de requisits agregant-ne un de nou.
La generació de proves per a cada funcionalitat fa que el programador confiï en el codi escrit. Això permet fer modificacions profundes del codi (possiblement en una etapa de manteniment del programa) doncs sabem que si després aconseguim fer passar totes les proves tindrem un codi que funcioni correctament.
Una altra característica del Test Driven Development és que requereix que el programador primer faci fallar els casos de prova. La idea és assegurar-se que els casos de prova realment funcionin i puguin recollir un error.

## Avantatges

Els programadors que utilitzen el desenvolupament guiat per proves en un projecte verge troben que en rares ocasions tenen la necessitat d'utilitzar el depurador o debugger.
Malgrat els elevats requisits inicials d'aplicar aquesta metodologia, el desenvolupament guiat per proves (TDD) pot proporcionar un gran valor afegit en la creació de programari, produint aplicacions de més qualitat i en menys temps. Ofereix més que una simple validació del compliment dels requisits, també pot guiar el disseny d'un programa. Centrar-se en primer lloc en els casos de prova fa que un hagi d'imaginar-se com els clients utilitzaran la funcionalitat (en aquest cas, els casos de prova). Per tant, al programador només li importa la interfície i no la implementació. Aquest avantatge és similar al disseny per conveni però s'assembla a ell pels casos de prova més que per les assercions matemàtiques.
El poder del TDD radica en la capacitat d'avançar en petits passos quan es necessita. Permet que un programador se centri en la tasca actual i el primer objectiu és, sovint, fer que la prova passi. Inicialment no es consideren els casos excepcionals i el tractament d'errors. Aquests, s'implementen després que s'hagi aconseguit que funcioni la funcionalitat principal. Un altre avantatge és que, quan és utilitzada correctament, s'assegura que tot el codi escrit està cobert per una prova. Això pot donar al programador un major nivell de confiança en el codi.

## Limitacions

El desenvolupament guiat per proves requereix que les proves puguin automatitzar-se. Això resulta complex en els següents dominis:
* Interfícies Gràfica d'usuari (GUIs), encara que hi ha solucions parcials propostes.
* Objectes distribuïts, encara que els objectes simulats (MockObjects) poden ajudar.
* Bases de dades. Fer proves de codi que treballa amb base de dades és complex perquè requereix posar a la base de dades unes dades conegudes abans de fer les proves i verificar que el contingut de la base de dades és l'esperat després de la prova. Tot això fa que la prova sigui costosa de codificar, a part de tenir disponible una base de dades que es pugui modificar lliurement.

## Vegeu també

* Prova de programari
* Casos de prova
* Prova unitària

## Enllaços externs

* MockObjects i TDD en .Net Framework
* Introducció a TDD
* Notícies i articles sobre TDD i proves de programari en general
* Secció del blog d'Angel "Java" Lopez sobre TDD amb anàlisi i exemples pràctics Arxivat 2013-09-09 a Wayback Machine.