Domanda

Per esempio, questo li introduce.

Qual è il vantaggio?

Analisi statica sembra fresco, ma allo stesso tempo che impedirebbe la possibilità di passare null come parametro in unit test. (Se avete seguito l'esempio in questo articolo che è)

Mentre sul tema della unit testing - dato come stanno le cose ora sicuramente non v'è alcun punto per i contratti di codice se già pratica test automatizzati?

Aggiorna

Dopo aver giocato con Code Contracts Sono un po 'deluso. Ad esempio, in base al codice nella risposta accettata:

public double CalculateTotal(Order order)
{
    Contract.Requires(order != null);
    Contract.Ensures(Contract.Result<double>() >= 0);
    return 2.0;
}

Per unit testing, è ancora deve scrivere i test per garantire che nulla non può essere passato, e il risultato è maggiore o uguale a zero se i contratti sono logica di business . In altre parole, se mi è stato di rimuovere il primo contratto, nessun test si rompono, a meno che non avevo espressamente avuto un test per questa funzione. Questo si basa sulla non si utilizza l'analisi statica integrata nel migliore (ultimo ecc ...) edizioni di Visual Studio però.

Essenzialmente tutte si riducono ad un modo alternativo di scrivere tradizionale if. La mia esperienza in realtà utilizzando TDD, con Code Contracts mostra perché, e come sono andato su di esso.

È stato utile?

Soluzione

Non credo unit testing e contratti di interferire con l'altro più di tanto, e se i contratti qualcosa dovesse aiutare unit testing in quanto elimina la necessità di aggiungere i test ripetitivi noiosi per gli argomenti non validi. Contratti specificano il minimo si può aspettare dalla funzione, mentre i test unitari cercano di validare il comportamento effettivo per un particolare insieme di ingressi. Considerate questo esempio inventato:


public class Order
{
    public IEnumerable Items { get; }
}

public class OrderCalculator
{
    public double CalculateTotal(Order order)
    {
        Contract.Requires(order != null);
        Contract.Ensures(Contract.Result<double>() >= 0);

        return 2.0;
    }
}

Chiaramente il codice soddisfa il contratto, ma si sarebbe ancora bisogno di unità di test per validare in realtà si comporta come ci si aspetterebbe.

Altri suggerimenti

  

Qual è il vantaggio?

Diciamo che si vuole fare in modo che un metodo non ritorna mai null. Ora, con test di unità, è necessario scrivere un mucchio di casi di test in cui si chiama il metodo con ingressi diversi e verificare che l'uscita non è nullo. Il problema è che non si possono testare tutti gli input possibili.

Con i contratti di codice, basta dichiarare che il metodo non restituisce mai null. L'analizzatore statica poi si lamentano se non è possibile dimostrare che. Se non si lamenta, sai che la tua affermazione è corretta per tutti i possibili ingressi.

Meno lavoro, perfetti garanzie di correttezza. Cosa c'è che non va?

I contratti consentono di dire quale sia il vero scopo del codice è, al contrario di lasciare che qualunque sia il codice fa con tutto ciò che gli argomenti a caso vengono consegnati in piedi come la definizione dal punto di vista del compilatore, o il prossimo lettore del codice. Questo permette di ottimizzare l'analisi e il codice significativamente migliore statica.

Per esempio, se dichiaro un parametro intero (usando la notazione contratto) sia nell'intervallo da 1 a 10, e ho una matrice locale nella mia funzione dichiarata la stessa dimensione, che è indicizzato dal parametro, la compilatore può dire che non v'è alcuna possibilità di errore pedice, producendo così un codice migliore.

Si può affermare che nulla è valore valido in un contratto.

Lo scopo del test dell'unità è verificare dinamicamente che il codice raggiunge qualunque scopo dichiarato che ha. Solo perché hai scritto un contratto per una funzione, non significa che il codice lo fa, o che l'analisi statica può verificare il codice lo fa. Unit testing non andrà via.

Beh, non interferirà con l'unità-test in generale. Ma come ho visto lei ha detto qualcosa a proposito TDD.

Se ci penso da questo punto di vista credo che potrebbe / può cambiare la procedura da quella standard

  • creare metodo (solo la firma)
  • creare test di Unità -> implementare il test
  • eseguire il test: lasciate fallire
  • implementare il metodo, hack fino alla fine solo per renderlo lavorare
  • eseguire il test: vedere passare
  • refactoring del (forse disordinato) Metodo corpo
  • (ri-eseguire il test solo per vedere che non hai rotto nulla)

Questa sarebbe la procedura davvero difficile-full-optional unit test. In tale contesto Credo che si potrebbe inserire i contratti di codice tra il 1 ° e 2 ° punto come

  • creare metodo (solo la firma)
  • contratti Codice Inserisci per i parametri di metodi di input
  • creare test di Unità -> implementare il test
  • ...

Il vantaggio che vedo in questo momento è che si può scrivere unit test più facile nel senso che non avrebbe dovuto controllare ogni possibile percorso dal momento che alcuni è già preso in considerazione dai vostri contratti definiti. E 'appena ti dà una verifica supplementare, ma non sarebbe sostituire unità di test dal momento che ci sarà sempre più la logica all'interno del codice, più il percorso che devono essere testati con prove di unità, come al solito.

Modifica

Un'altra possibilità non ho considerato prima sarebbe quella di aggiungere i contratti di codice nella parte refactoring. Fondamentalmente come ulteriore modo di assicurare cose. Ma che sarebbe in qualche modo ridondante e dal momento che la gente non piace fare cose ridondanti ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top