Tecniche di verifica basate sullo stato

Una tecnica di verifica utilizzata comunemente è l'analisi dei diversi stati astratti di una classe. Lo stato di un oggetto è generalmente definito come un vincolo nei valori degli attributi. A seconda dello stato dell'oggetto, le chiamate di determinati metodi possono essere valide o non valide o il comportamento del metodo può variare.

In linea generale, l'utilizzo delle tecniche di verifica basate sullo stato prevede il seguente processo:

  1. Definire i passaggi.
  2. Definire le transizioni tra gli stati.
  3. Definire gli scenari di verifica.
  4. Definire i valori di verifica per ciascuno stato.

Per avere un'idea di questo processo, considerare la classe MoneyBag di JUnit.

class MoneyBag implements IMoney {
     private Vector fMonies= new Vector(5); 
     public IMoney add(IMoney m) {
         return m.addMoneyBag(this);
     }
     public IMoney addMoney(Money m) {
         return MoneyBag.create(m, this);
  } 
  public IMoney addMoneyBag(MoneyBag s) {
     return MoneyBag.create(s, this); 
  }
  void appendMoney(Money aMoney) {
     if (aMoney.isZero()) return;
     IMoney old= findMoney(aMoney.currency());
     if (old == null) {
           fMonies.addElement(aMoney);
           return;
     }
     fMonies.removeElement(old);
     IMoney sum= old.add(aMoney);
     if (sum.isZero())
           return;
     fMonies.addElement(sum);
  }
  private Money findMoney(String currency) {
     for (Enumeration e=fMonies.elements();e.hasMoreElements();)
     {
          Money m= (Money) e.nextElement();
          if (m.currency().equals(currency))
              return m;
     }
     return null;
  }
  private boolean contains(Money m) {
     Money found= findMoney(m.currency());
     if (found == null) return false;
     return found.amount() == m.amount();
     }
  } 

Definire degli stati

Il primo passaggio nell'utilizzo delle tecniche di verifica basate sullo stato consiste nel definire gli stati. Dalla seconda riga di codice, è possibile vedere che la classe MoneyBag può contenere da 0 a 5 oggetti Money.

private Vector fMonies= new Vector(5); 

In base a questa analisi, è possibile creare un modello di stato che prevede i seguenti stati:

In questo esempio è possibile definire i seguenti vincoli nell'attributo fMonies, come visualizzato nella tabella che segue:

Stato Vincolo
EmptyBag fMonies.size()==0
PartiallyFullBag (fMonies.size()>0) && (fMonies.size()<5)
FullBag fMonies.size()==5

Benché non sia sempre necessario definire gli stati, può risultare utile farlo in fase di definizione dei dati di verifica o se si desidera controllare lo stato dell'oggetto nell'ambito di uno specifico scenario.

Definire le transizioni tra gli stati

Il passaggio successivo consiste nella definizione delle possibili transizioni tra gli stati e nella determinazione degli elementi che attivano la transizione da uno stato all'altro. Generalmente, quando una classe viene verificata, la transizione si attiva quando viene richiamato un metodo. Ad esempio, la transazione dallo stato EmptyBag a quello PartiallyFullBag viene attivata dalla chiamata di appendMoney.

Quindi, alcune delle possibili transizioni possono essere definite come segue:

Per riassumere, è necessario elencare per ciascuno stato identificato quanto segue:

Definire gli scenari di verifica

Le verifiche generalmente consistono in scenari che utilizzano l'oggetto in un dato percorso attraverso il meccanismo dello stato. Poiché il numero dei percorsi possibili nel meccanismo dello stato è generalmente infinito, non è pratico verificare ciascun percorso possibile. È invece necessario accertarsi di svolgere le seguenti attività:

Ogni volta che è possibile, controllare lo stato dell'oggetto sottoposto a verifica nell'ambito dello scenario per assicurarsi che il modello di stato teorico definito sia effettivamente quello implementato dalla classe sottoposta a verifica. Una volta completata l'attivazione delle transizioni non valide, è possibile verificarne la robustezza richiamando il metodo in una sequenza casuale e controllando che una costante della classe non sia mai violata. Ad esempio, la classe MoneyBag dovrebbe sempre essere un insieme di oggetti Money che non presentano mai la stessa valuta.

È possibile utilizzare il modello di verifica basato sullo scenario incluso nel prodotto per creare degli scenari di verifica.

Definire i valori di verifica per ciascuno stato

Infine, è necessario scegliere i valori di verifica per ogni singolo stato. Si consiglia di scegliere valori di verifica univoci e di non riutilizzare valori utilizzati precedentemente nel contesto di altre verifiche. Tale strategia garantisce maggiore diversificazione nella suite di verifica e aumenta la probabilità di rilevare dei difetti. Per maggiori dettagli sulla definizione di valori di verifica adeguati, consultare la sezione Definizione dei dati di verifica.

Concetti correlati
Strategie di verifica
Sottosistemi Java

Attività correlate
Verifica dei metodi Java
Verifica delle classi Java

Termini di utilizzo | Feedback
(C) Copyright IBM Corporation 2000, 2004. Tutti i diritti riservati.