www.fabiobeta.it

« HTML Preview!
W i Repository! »

Ciao, sono Fabio.
Su queste pagine potete trovare esperienze, idee ed esperimenti di un programmatore in cerca di metodi per lavorare meglio e meno.

RSS

Questi sono i post più apprezzati del sito, dateci un'occhiata:

SFTP automatico e natalizio con ANT

La mia cassetta degli attrezzi: Il portatile

III: Tu non commenterai invano

YAGNI for Managers

Stand Up Meeting: Definizione

Eclipse: Propaganda a suon di keystroke

HtmlPreviewer

Gli altri sono qui.

Unit Testing: Testare e Ritestare
25 Maggio 2006

Più passa il tempo più mi posso dichiarare test-infected. Ieri notte ho fatto un ulteriore passo verso la dipendenza.

Un tipo di test cui non riuscivo a dare un'organizzazione armonica è il test da ripetere più volte variando semplicemente i parametri.

Facciamo un esempio stupido: un metodo che restituisce il logaritmo in base 10 dell'input. Volendolo testare in modo pignolo potrei volere verificare:

  • log(10) = > 1
  • log(1) = > 0
  • log(0.1) = > -1
potrei scrivere tre test:
public void testLog10di10() throws Exception {
  assertEquals(1,Log10.log10(10),0.1);
}

public void testLog10di1() throws Exception {
  assertEquals(0,Log10.log10(1),0.1);
}

public void testLog10di0virgola1() throws Exception {
  assertEquals(-1,Log10.log10(0.1),0.0001);
}

Ma già con tre casi di test mi sembra di aver scritto troppo codice, figuriamoci se invece di un esempio stessi scrivendo qualcosa di serio...
In alternativa potrei mettere tutti e tre i casi in un unico test

public void testLog10() throws Exception {
  assertEquals(1,Log10.log10(10),0.1);
  assertEquals(0,Log10.log10(1),0.1);
  assertEquals(-1,Log10.log10(0.1),0.0001);
}

Ma un test così è solo un contratto ad insultarmi da solo la prima volta che il primo dei tre controlli fallirà: perderei la visibilità sui controlli successivi.

Ieri sera su Java Extreme Programming Cookbook ho trovato la soluzione. Mi basta definire un testCase così:

public class Log10Test extends TestCase {
  private double parameter;
  private double expected;

  public Log10Test(String testName,double inputParameter,double expected) {
    super(testName);
    this.parameter=inputParameter;
    this.expected=expected;
  }

  public void testLog10() throws Exception {
    assertEquals(expected,Log10.log10(parameter),0.1);
  }
}

e definirmi una suite così:

public static Test suite() {

  TestSuite suite = new TestSuite();

  suite.addTest(new Log10Test("testLog10",10,1));
  suite.addTest(new Log10Test("testLog10",100,2));
  suite.addTest(new Log10Test("testLog10",1,0));
  suite.addTest(new Log10Test("testLog10",1000,3));
  suite.addTest(new Log10Test("testLog10",0.1,-1));
  suite.addTest(new Log10Test("testLog10",0.01,-2));

  return suite;
}

In parole povere definisco una classe TestCase che prende com parametri del costruttore il metodo di test e i valori che questo deve testare. Poi nella TestSuite aggiungo alla suite varie istanze della classe di TestCase, ognuno parametrizzata diversamente.

Questa soluzione, per quanto un po' più convoluta di un testCase classico supera (per i miei gusti) i limiti delle altre soluzioni:

  • La sezione di codice in cui posso modificare o aggiunger test è concentrata
  • Tutti i casi di test girano indipendenti, garantendomi maggiori dettagli quando risveglio la barra rossa.

send a feedback to fabio

« HTML Preview!
W i Repository! »

Fight Spam! Click Here!