Junit Test

di il
21 risposte

Junit Test

Salve , come potrei testare il metodo di questa classe ? il problema è nato nel momento in cui il metodo da testare non ha attributi? cosa mi consigliate ? i mock o stub ?
public class Registro {
	
	public static String[] nome;
	private double[][] voto;
	private String [] materia;
	
	public String[] migliori(){
		String[] migliore;
		
		int r = this.nome.length;
		int c = this.materia.length;
		
		migliore = new String[c];
		
		for (int j=0; j<c; j++){
			double max = this.voto[0][j]; 						
			migliore[j]= this.nome[0];
			for (int i=1; i<r; i++)
				if (this.voto[i][j] > max){
					max = this.voto[i][j];
					migliore[j] = this.nome[i];
				}
		}

		return migliore;
	}

}

21 Risposte

  • Re: Junit Test

    centurione_agrippa ha scritto:


    Salve , come potrei testare il metodo di questa classe ? il problema è nato nel momento in cui il metodo da testare non ha attributi? cosa mi consigliate ? i mock o stub ?
    Qui mock/stub non c'entrano. Il codice che hai postato non è completo, c'è sicuramente "altro" che imposta quelle due variabili di istanza (e quel String[] nome come static e oltretutto public è "brutto" in generale).

    Ma a parte questo, lo unit testing sarà così. Devi individuare le varie casistiche riguardo lo "stato" dell'oggetto cioè per quelle variabili.
    Per ciascun caso (che sarà un singolo unit-test), imposti lo stato dell'oggetto, invochi migliori() e verifichi se l'array String[] restituito corrisponde a quello che ci si aspetta per lo stato dell'oggetto.
  • Re: Junit Test

    andbin ha scritto:


    centurione_agrippa ha scritto:


    Salve , come potrei testare il metodo di questa classe ? il problema è nato nel momento in cui il metodo da testare non ha attributi? cosa mi consigliate ? i mock o stub ?
    Qui mock/stub non c'entrano. Il codice che hai postato non è completo, c'è sicuramente "altro" che imposta quelle due variabili di istanza (e quel String[] nome come static e oltretutto public è "brutto" in generale).

    Ma a parte questo, lo unit testing sarà così. Devi individuare le varie casistiche riguardo lo "stato" dell'oggetto cioè per quelle variabili.
    Per ciascun caso (che sarà un singolo unit-test), imposti lo stato dell'oggetto, invochi migliori() e verifichi se l'array String[] restituito corrisponde a quello che ci si aspetta per lo stato dell'oggetto.
    Ciao e grazie per avermi risposto. La mia difficoltà sta proprio nel testare il metodo con gli assert dato che non ho gli attributi passati nel metodo.In principio avevo solo il metodo da testare che ho inserito in una classe per poterlo compilare ed ho aggiunto
    private String[] nome;
    	private double[][] voto;
    	private String[] materia;
  • Re: Junit Test

    centurione_agrippa ha scritto:


    andbin ha scritto:


    centurione_agrippa ha scritto:


    Salve , come potrei testare il metodo di questa classe ? il problema è nato nel momento in cui il metodo da testare non ha attributi? cosa mi consigliate ? i mock o stub ?
    Qui mock/stub non c'entrano. Il codice che hai postato non è completo, c'è sicuramente "altro" che imposta quelle due variabili di istanza (e quel String[] nome come static e oltretutto public è "brutto" in generale).

    Ma a parte questo, lo unit testing sarà così. Devi individuare le varie casistiche riguardo lo "stato" dell'oggetto cioè per quelle variabili.
    Per ciascun caso (che sarà un singolo unit-test), imposti lo stato dell'oggetto, invochi migliori() e verifichi se l'array String[] restituito corrisponde a quello che ci si aspetta per lo stato dell'oggetto.
    Ciao e grazie per avermi risposto. La mia difficoltà sta proprio nel testare il metodo con gli assert dato che non ho gli attributi passati nel metodo.In principio avevo solo il metodo da testare che ho inserito in una classe per poterlo compilare ed ho aggiunto
    private String[] nome;
    	private double[][] voto;
    	private String[] materia;
    Come passo le variabili d'input al metodo ?
  • Re: Junit Test

    centurione_agrippa ha scritto:


    dato che non ho gli attributi passati nel metodo.
    Quei attributi dovrebbero essere settati in altro modo, da un costruttore e/o dei setter (o da altri metodi che fanno della logica) ... non saprei dirti ora non conoscendo il contesto.
    Non puoi avere solo quei campi private e basta. Ai fini dello unit-testing, PRIMA imposti lo stato di un oggetto, POI invochi il metodo "under test" (migliori() nel tuo caso), POI se il metodo ha un valore di ritorno lo testi verificando se corrisponde per la casistica testata.

    Se non hai un costruttore o dei setter che impostano quei campi, lo unit-testing diventerebbe più complicato (ma bene o male tecnicamente fattibile). Ma l'USO finale, normale insomma, della classe avrebbe poco/nulla senso.
  • Re: Junit Test

    andbin ha scritto:


    centurione_agrippa ha scritto:


    dato che non ho gli attributi passati nel metodo.

    Se non hai un costruttore o dei setter che impostano quei campi, lo unit-testing diventerebbe più complicato (ma bene o male tecnicamente fattibile). Ma l'USO finale, normale insomma, della classe avrebbe poco/nulla senso.
    Per questo avevo pensato di usare i mock. Per scopi didattici mi è stato detto di testare il metodo, qualche suggerimento con il metodo scritto il quel modo ?
  • Re: Junit Test

    centurione_agrippa ha scritto:


    Per questo avevo pensato di usare i mock. Per scopi didattici mi è stato detto di testare il metodo, qualche suggerimento con il metodo scritto il quel modo ?
    Ti ripeto che i mock NON c'entrano. Hai dei campi (variabili di istanza) private. Devono poter essere impostabili. Da costruttore e/o metodi setter. Punto.
  • Re: Junit Test

    andbin ha scritto:


    centurione_agrippa ha scritto:


    Per questo avevo pensato di usare i mock. Per scopi didattici mi è stato detto di testare il metodo, qualche suggerimento con il metodo scritto il quel modo ?
    Ti ripeto che i mock NON c'entrano. Hai dei campi (variabili di istanza) private. Devono poter essere impostabili. Da costruttore e/o metodi setter. Punto.
    ok, grazie mille per la pazienza.
  • Re: Junit Test

    andbin ha scritto:


    centurione_agrippa ha scritto:


    Per questo avevo pensato di usare i mock. Per scopi didattici mi è stato detto di testare il metodo, qualche suggerimento con il metodo scritto il quel modo ?
    Ti ripeto che i mock NON c'entrano. Hai dei campi (variabili di istanza) private. Devono poter essere impostabili. Da costruttore e/o metodi setter. Punto.
    Ho modificato la mia classe da testare in questo modo
    public class Registro {
    	
    	private String[] nome;
    	private double[][] voto;
    	private String[] materia;
    									
    	public  Registro(String[]nome,double[][] voto, String[] materia){
    		this.nome=nome;
    		this.voto=voto;
    		this.materia=materia;
    	}
    	
    	
    	public String[] getNome() {
    		return nome;
    	}
    
    
    	public void setNome(String[] nome) {
    		this.nome = nome;
    	}
    
    
    	public double[][] getVoto() {
    		return voto;
    	}
    
    
    	public void setVoto(double[][] voto) {
    		this.voto = voto;
    	}
    
    
    	public String[] getMateria() {
    		return materia;
    	}
    
    
    	public void setMateria(String[] materia) {
    		this.materia = materia;
    	}
    
    
    	public String[] migliori(){
    		String[] migliore;
    		
    		int r = this.nome.length;
    		int c = this.materia.length;
    		
    		migliore = new String[c];
    		
    		for (int j=0; j<c; j++){
    			double max = this.voto[0][j]; 			
    			migliore[j]= this.nome[0];
    			for (int i=1; i<r; i++)
    				if (this.voto[i][j] > max){
    					max = this.voto[i][j];
    					migliore[j] = this.nome[i];
    				}
    		}
    
    		return migliore;
    	}
    }	
    
    
    
    
    La classe di test come deve essere fatta, è giusto impostarla in questo modo :
    public class RegistroTest {
    	
    	String materia[]={"Inf","Elettr","Stor"};
    	double voto [][] ={{7,8,6.5},
    			   {4,5,7 },
    			   {9,7,6  },
    			   {3,5,6  }};
    
    	String nome[]={"Luigi","Marco","Nicola","Renato"};
    	Registro reg = new Registro(nome,voto,materia);
    	
    	@Test
    	public void testMigliori(){
    		assertEquals(nome,reg.get());
    	}
    
    }
  • Re: Junit Test

    centurione_agrippa ha scritto:


    Ho modificato la mia classe da testare in questo modo
    Ok, ora HA senso (sia il testing ma anche un qualunque suo "uso" generale).

    centurione_agrippa ha scritto:


    assertEquals(nome,reg.get());
    Qui forse volevi scrivere

    assertEquals(nome,reg.getNome());

    Ma comunque qui staresti solo testando un getter. E i getter generalmente NON si testano (troppo "banali" perché qualcosa vada storto).

    Hai identificato le varie casistiche per i test? Per farlo devi saper ragionare in maniera più "maliziosa" e pensare ai casi che davvero "mettono alla prova" il metodo.
    Quindi presumibilmente ci saranno più test con dati differenti. Il fatto che hai messo come variabile di istanza:

    Registro reg = new Registro(nome,voto,materia);

    però è poco comodo, perché presuppone di poter avere una sola configurazione.
  • Re: Junit Test

    andbin ha scritto:


    centurione_agrippa ha scritto:


    Ho modificato la mia classe da testare in questo modo
    Ok, ora HA senso (sia il testing ma anche un qualunque suo "uso" generale).

    centurione_agrippa ha scritto:


    assertEquals(nome,reg.get());
    Qui forse volevi scrivere

    assertEquals(nome,reg.getNome());

    Ma comunque qui staresti solo testando un getter. E i getter generalmente NON si testano (troppo "banali" perché qualcosa vada storto).

    Hai identificato le varie casistiche per i test? Per farlo devi saper ragionare in maniera più "maliziosa" e pensare ai casi che davvero "mettono alla prova" il metodo.
    Quindi presumibilmente ci saranno più test con dati differenti. Il fatto che hai messo come variabile di istanza:

    Registro reg = new Registro(nome,voto,materia);

    però è poco comodo, perché presuppone di poter avere una sola configurazione.
    Ha perfettamente ragione e sto cercando di migliorare il codice poco per volta. Nella classe da testare ho preferito togliere il costruttore ed ho usato solo i metodi set e get. La classe test è fatta cosi
    public class RegistroTest {
    	
    	double voto [][] ={{7,8,6.5},
    			   {4,5,7 },
    			   {9,7,6  },
    			   {3,5,6  }};
    	String nome[]={"Luigi","Marco","Nicola","Renato"};
    	@Test
    	public void testMigliori(){
    		Registro reg = new Registro();
    		reg.setNome(nome);
    		
    		assertEquals(nome,reg.migliori());
    	
    	}
    }
    }
    Non ancora ben chiaro come usare i metodi set e get nella classe test. Dov'è che sbaglio
  • Re: Junit Test

    centurione_agrippa ha scritto:


    Nella classe da testare ho preferito togliere il costruttore
    Il costruttore nella classe Registro andava bene, non è quello il problema.

    Io prima dicevo solo che non era molto utile avere un new Registro(nome,voto,materia) fisso così SOLO con quel nome, voto ecc... Perché potresti avere più scenari e quindi più oggetti Registro con dati differenti.

    centurione_agrippa ha scritto:


    Non ancora ben chiaro come usare i metodi set e get nella classe test. Dov'è che sbaglio
    Allora, innanzitutto c'è da chiarire le casistiche. E per farlo devi aver chiaro il concetto di quel migliori(). Che cosa deve fare concettualmente?
    Non dirmi cosa FA attualmente il suo codice. Potrebbe essere corretto oppure no (è anche a questo che serve uno unit-testing). Prova a dirmi il concetto.

    Poi se io volessi (non ho avuto tempo oggi, vedo stasera) potrei provare a dedurlo dal codice di migliori().
  • Re: Junit Test

    andbin ha scritto:


    centurione_agrippa ha scritto:


    Nella classe da testare ho preferito togliere il costruttore
    Il costruttore nella classe Registro andava bene, non è quello il problema.

    Io prima dicevo solo che non era molto utile avere un new Registro(nome,voto,materia) fisso così SOLO con quel nome, voto ecc... Perché potresti avere più scenari e quindi più oggetti Registro con dati differenti.

    centurione_agrippa ha scritto:


    Non ancora ben chiaro come usare i metodi set e get nella classe test. Dov'è che sbaglio
    Allora, innanzitutto c'è da chiarire le casistiche. E per farlo devi aver chiaro il concetto di quel migliori(). Che cosa deve fare concettualmente?
    Non dirmi cosa FA attualmente il suo codice. Potrebbe essere corretto oppure no (è anche a questo che serve uno unit-testing). Prova a dirmi il concetto.

    Poi se io volessi (non ho avuto tempo oggi, vedo stasera) potrei provare a dedurlo dal codice di migliori().
    Il metodo dovrebbe dare come risultato per ogni materia il nome del ragazzo col voto più alto ed avevo pensato di fare un test suite con tre test case che falliscono e tre test case che hanno successo. Cercherò di modificarlo al meglio per un confronto
  • Re: Junit Test

    centurione_agrippa ha scritto:


    Il metodo dovrebbe dare come risultato per ogni materia il nome del ragazzo col voto più alto
    Bene. Pensando ai casi di test a me, così al volo, vengono in mente questi (supponendo le tue 4 persone e 3 materie):
    - un caso in cui una sola persona è migliore in tutte le materie
    - un caso in cui una persona è migliore in 2 materie e un'altra persona è migliore nella terza materia
    - un caso in cui tre persone distinte sono migliori in ciascuna delle tre materie

    Avevi pensato a questi? Poi ci sarebbero anche i casi dei fallimenti per questioni "tecniche" di incoerenza tra i dati. Cosa ci si vuole aspettare se hai 5 nomi di persona ma l'array dei voti ha solo 4 righe? (ArrayIndexOutOfBound è quello che succederebbe con il tuo codice e si può anche testare).

    Questo in sostanza vuol dire che i nomi delle materie e delle persone possono anche restare sempre quelli. Mentre per l'array voto dovrai per forza crearne diversi con dati differenti per fare i vari casi.

    Se fai caso, i nomi delle materie NON sono importanti. Sono solo concettualmente correlati ai voti per indice. Mentre invece i nomi delle persone sono importanti perché li usi sia per impostare l'array dei nomi sia poi per testare l'array in uscita da migliori().
    Per i nomi delle persone è meglio mettere delle costanti es.

    public static final String MARIO = "Mario";

    Questo ti permette di scrivere sempre correttamente i nomi (un IDE tra l'altro ti può fare l'autocompletamento mentre scrivi) e ti evita di "cannare" un test solo perché magari nel setup hai scritto "Mario" e nel test del risultato hai testato "Marlo" per sbaglio.

    Ora prova, per dubbi, chiedi ovviamente.
  • Re: Junit Test

    andbin ha scritto:


    centurione_agrippa ha scritto:


    Il metodo dovrebbe dare come risultato per ogni materia il nome del ragazzo col voto più alto
    Bene. Pensando ai casi di test a me, così al volo, vengono in mente questi (supponendo le tue 4 persone e 3 materie):
    - un caso in cui una sola persona è migliore in tutte le materie
    - un caso in cui una persona è migliore in 2 materie e un'altra persona è migliore nella terza materia
    - un caso in cui tre persone distinte sono migliori in ciascuna delle tre materie

    Avevi pensato a questi? Poi ci sarebbero anche i casi dei fallimenti per questioni "tecniche" di incoerenza tra i dati. Cosa ci si vuole aspettare se hai 5 nomi di persona ma l'array dei voti ha solo 4 righe? (ArrayIndexOutOfBound è quello che succederebbe con il tuo codice e si può anche testare).

    Questo in sostanza vuol dire che i nomi delle materie e delle persone possono anche restare sempre quelli. Mentre per l'array voto dovrai per forza crearne diversi con dati differenti per fare i vari casi.

    Se fai caso, i nomi delle materie NON sono importanti. Sono solo concettualmente correlati ai voti per indice. Mentre invece i nomi delle persone sono importanti perché li usi sia per impostare l'array dei nomi sia poi per testare l'array in uscita da migliori().
    Per i nomi delle persone è meglio mettere delle costanti es.

    public static final String MARIO = "Mario";

    Questo ti permette di scrivere sempre correttamente i nomi (un IDE tra l'altro ti può fare l'autocompletamento mentre scrivi) e ti evita di "cannare" un test solo perché magari nel setup hai scritto "Mario" e nel test del risultato hai testato "Marlo" per sbaglio.

    Ora prova, per dubbi, chiedi ovviamente.
    Per i casi di test avevo pensato a 3 che falliscono e tre che hanno successo. I casi sono:
    1)Fallisce per un voto negativo (tipo -5,-7);
    2)Fallisce per un voto non compreso tra 0 e 10;
    3)Fallisce quando non è presente il voto della materia dell'alunno;
    4)Successo quando il voto inserito è compreso tra 0 e 10;
    5)Successo quando restituisce per ogni materia il nome dello studente con il miglior voto;
    6)Successo quando sono stati inseriti tutti i voti per tutti gli alunni e per tutte le materie;

    I suoi casi test credo che siano più incentrati al metodo e credo che sia anche giusto. Non mi è ben chiaro la questione delle costanti, ho cercato di sistemare un po di cose in questo modo:
    public class Registro {
    	
    	private String[] nome;
    	private double[][] voto;
    	private String[] materia;
    							
    	
    	public  Registro(String[]nome,double[][] voto, String[] materia){
    		this.nome=nome;
    		this.voto=voto;
    		this.materia=materia;
    	}
    	
    	
    	public String[] getNome() {
    		return nome;
    	}
    
    	public void setNome(String[] nome) {
    		this.nome = nome;
    	}
    
    	public double[][] getVoto() {
    		return voto;
    	}
    
    
    	public void setVoto(double[][] voto) {
    		this.voto = voto;
    	}
    
    
    	public String[] getMateria() {
    		return materia;
    	}
    
    
    	public void setMateria(String[] materia) {
    		this.materia = materia;
    	}
    
    
    	public String[] migliori(){
    		String[] migliore;
    		
    		int r = this.nome.length;
    		int c = this.materia.length;
    		
    		migliore = new String[c];
    		
    		for (int j=0; j<c; j++){
    			double max = this.voto[0][j]; 			
    			migliore[j]= this.nome[0];
    			for (int i=1; i<r; i++)
    				if (this.voto[i][j] > max){
    					max = this.voto[i][j];
    					migliore[j] = this.nome[i];
    				}
    		}
    
    		return migliore;
    	}
    
    	
    }	
    public class RegistroTest {
    	
    	double voto [][] ={{7,8,6.5},
    			   {4,5,7 },
    			   {9,7,6  },
    			   {3,5,6  }};
    	String nomeoutput[]={"Luigi","Marco","Nicola"};
    	String nome[]={"Luigi","Marco","Nicola","Renato"};
    	
    	String materia[]={"Inf","Elettr","Stor"};
    
    	@Test
    	public void testMigliori(){
    		Registro reg = new Registro(nome,voto,materia);
    		reg.setNome(nome);
    		reg.setMateria(materia);
    		reg.setVoto(voto);
    		assertArrayEquals(reg.migliori(),nomeoutput);
    		}
    }	
    
    Il test fallisce
Devi accedere o registrarti per scrivere nel forum
21 risposte