Les proves unitàries són una tècnica de verificació de programari que s'utilitza
per assegurar que cada part ("unitat") del programa funciona correctament.
Aquesta tècnica es basa en la idea de dividir el programa en parts més xicotetes i
escriure proves per a cada part per comprovar que totes elles funcionen correctament.
Això és útil perquè, quan es produeixen canvis en un programa, és més fàcil determinar què ha anat malament
si es poden comprovar les parts individuals del programa. Això també pot ajudar a detectar errors més ràpidament
i a prevenir la introducció de nous errors durant el manteniment del programa.
Java té diverses eines per escriure i executar les proves.
Anem a crear unes proves unitàries per comprovar que el programa
DebugRockPaperScissors
funciona correctament.
Per poder provar aquest codi, s'ha creat una nova versió del programa
que incorpora el mètode int guanya(String jugador1, String jugador2),
que determina quin jugador ha guanyat la partida:
DebugRockPaperScissors.java
packageud4.examples;importjava.util.Locale;importjava.util.Scanner;publicclassDebugRockPaperScissors{/** * Determina quin jugador ha guanyat la partida de pedra paper i tisores. * <p> * Aquest mètode retorna 0 si hi ha hagut un empat, 1 si el jugador1 ha guanyat la partida, * i 2 si el jugador2 ha guanyat. * * @param jugador1 Jugada del jugador1 (pedra, paper o tisores) * @param jugador2 Jugada del jugador1 (pedra, paper o tisores) * @return 0 si hi ha un empat; 1 si guanya jugador1; 2 si guanya jugador 2. */publicstaticintguanya(Stringjugador1,Stringjugador2){if(jugador1.equals(jugador2))return0;elseif(jugador1.equals("paper")){returnjugador2.equals("pedra")?2:1;}elseif(jugador1.equals("pedra")){returnjugador2.equals("paper")?1:2;}else{returnjugador2.equals("paper")?1:2;}}publicstaticvoidmain(String[]args){Scannerin=newScanner(System.in).useLocale(Locale.US);System.out.print("Introdueix l'elecció del jugador 2 (pedra/paper/tisores): ");Stringp1=in.nextLine();System.out.print("Introdueix l'elecció del jugador 2 (pedra/paper/tisores): ");Stringp2=in.nextLine();intguanyador=guanya(p1,p2);if(guanyador==0)System.out.println("Empat");elseSystem.out.printf("Guanya el jugador %d\n",guanyador);}}
Anem a comprovar si el mètode està ben implementat utilitzant proves unitàries:
Situat sobre el nom de la classe DebugRockPaperScissors, prem Alt+Ins
i selecciona Test.
També pots prémer Alt+Enter o clicar el botó dret i selecciona Show Context Actions.
Des del menú, selecciona Create Test.
Selecciona els mètodes que vols provar en el diàleg i prem OK.
L'acció anterior crearà un nou fixer en src/test/java,
la carpeta designada on guardar les proves del projecte.
El nou fitxer es troba en la mateixa estructura de paquets que el codi font: ud5.examples.
Dissenyem proves per comprovar si el mètode guanya() funciona correctament
en tots els casos.
Jugador 1
Jugador 2
Resultat
Pedra
Pedra
Empat
Pedra
Paper
Jugador 2 guanya
Pedra
Tisores
Jugador 1 guanya
Paper
Pedra
Jugador 1 guanya
Paper
Paper
Empat
Paper
Tisores
Jugador 2 guanya
Tisores
Pedra
Jugador 2 guanya
Tisores
Paper
Jugador 1 guanya
Tisores
Tisores
Empat
Modifiquem el fitxer amb les proves per incloure els casos anteriors. S'han organitzat
les proves en classes internes @Nested per millorar la organització de les proves.
DebugRockPaperScissorsTest.java
packageud4.examples;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Nested;importorg.junit.jupiter.api.Test;import staticorg.junit.jupiter.api.Assertions.*;classDebugRockPaperScissorsTest{@NestedclassEmpat{@Test@DisplayName("Empat: Pedra vs Pedra")voidtestEmpatPedraPedra(){intexpected=0;intactual=DebugRockPaperScissors.guanya("pedra","pedra");assertEquals(expected,actual);}@Test@DisplayName("Empat: Paper vs Paper")voidtestEmpatPaperPaper(){intexpected=0;intactual=DebugRockPaperScissors.guanya("paper","paper");assertEquals(expected,actual);}@Test@DisplayName("Empat: Tisores vs Tisora")voidtestEmpatTisoresTisora(){intexpected=0;intactual=DebugRockPaperScissors.guanya("tisores","tisores");assertEquals(expected,actual);}}@NestedclassJugador1{@Test@DisplayName("Jugador 1 guanya: Pedra vs Tisores")voidtestJugador1GuanyaPedraTisores(){intexpected=1;intactual=DebugRockPaperScissors.guanya("pedra","tisores");assertEquals(expected,actual);}@Test@DisplayName("Jugador 1 guanya: Paper vs Pedra")voidtestJugador1GuanyaPaperPedra(){intexpected=1;intactual=DebugRockPaperScissors.guanya("paper","pedra");assertEquals(expected,actual);}@Test@DisplayName("Jugador 1 guanya: Tisores vs Paper")voidtestJugador1GuanyaTisoresPaper(){intexpected=1;intactual=DebugRockPaperScissors.guanya("tisores","paper");assertEquals(expected,actual);}}@NestedclassJugador2{@Test@DisplayName("Jugador 2 guanya: Tisores vs Pedra")voidtestJugador2GuanyaTisoresPedra(){intexpected=2;intactual=DebugRockPaperScissors.guanya("tisores","pedra");assertEquals(expected,actual);}@Test@DisplayName("Jugador 2 guanya: Pedra vs Paper")voidtestJugador2GuanyaPedraPaper(){intexpected=2;intactual=DebugRockPaperScissors.guanya("pedra","paper");assertEquals(expected,actual);}@Test@DisplayName("Jugador 2 guanya: Paper vs Tisores")voidtestJugador2GuanyaPaperTisores(){intexpected=2;intactual=DebugRockPaperScissors.guanya("paper","tisores");assertEquals(expected,actual);}}}
Una vegada s'han implementat les proves, anem a executar-les per veure
si el mètode int guanya(String jugador1, String jugador2) funciona
correctament.
Per executar-les, s'ha de clicar el botó Run.
Una vegada executats, podem consultar els resultats:
Es poden observar els resultats de cada prova per separat.
En aquest cas han fallat algunes de les proves, per tant,
que caldrà revisar els errors i corregir el codi.