2010-06-07 7 views
5

Ho problemi con alcuni test dell'unità MSTest che passano quando li eseguo individualmente ma esito negativo quando eseguo l'intera classe di test dell'unità. I test provano il codice SLaks helped me with earlier e mi ha avvertito che quello che stavo facendo non era thread-safe. Tuttavia, ora il mio codice è più complicato e non so come fare per renderlo thread-safe. Ecco quello che ho:Il test dell'unità MSTest passa da solo, non riesce quando si eseguono altri test

public static class DLLConfig 
{ 
    private static string _domain; 

    public static string Domain 
    { 
     get 
     { 
      return _domain = AlwaysReadFromFile 
       ? readCredentialFromFile(DOMAIN_TAG) 
       : _domain ?? readCredentialFromFile(DOMAIN_TAG); 
     } 
    } 
} 

E il mio test è semplice:

string expected = "the value I know exists in the file"; 
string actual = DLLConfig.Domain; 
Assert.AreEqual(expected, actual); 

Quando ho eseguito questo test da solo, esso passa. Quando lo eseguo insieme a tutti gli altri test nella classe di test (che eseguono controlli simili su proprietà diverse), actual è null e il test ha esito negativo. Prendo atto che questo non è un problema con una proprietà il cui tipo è un tipo personalizzato Enum; forse sto avendo questo problema con la proprietà Domain perché è un string? O forse è un problema multi-thread con come funziona MSTest?

+0

In che modo (se non lo siete) state creando/abbattendo tra un test e l'altro? – Paddyslacker

+0

@Paddyslacker: nessuno. Non ho metodi '[TestCleanup]' o '[TestInitialize]'. –

+1

I buoni test unitari sono indipendenti, quindi guarderei i veri test unitari aggiungendo alcune impostazioni e teardown per ottenere ogni volta il codice in uno stato noto. Se esiste un vero caso di test per chiamare il metodo contemporaneamente o chiamarlo due volte, quindi scrivere uno specifico caso di test in errore e farlo passare. – Paddyslacker

risposta

6

Sospetto che gli altri test stiano modificando un valore nella classe DLLConfig che causa la modifica del risultato del getter. I test unitari devono sempre essere eseguiti da uno stato iniziale noto, quindi è necessario impostarlo nel metodo di prova o in un metodo contrassegnato con l'attributo TestInitialize eseguito prima di ogni test.

5

Il test è in base a un file esterno. Invece di chiamare una funzione che accede direttamente al file, è necessario che DLLConfig.Domain chiami un metodo in un'altra classe.

public static string Domain 
{ 
    get 
    { 
     return _domain = AlwaysReadFromFile 
      ? CredentialReader.Read(DOMAIN_TAG) 
      : _domain ?? CredentialReader.Read(DOMAIN_TAG); 
    } 
} 

Poi è possibile inizializzare DllConfig con un/falso CredentialReader finto/stub in cui è possibile controllare il suo valore di ritorno. Ricordare che si sta verificando che DLLConfig.Domain restituisca il valore corretto in base alla condizione AlwaysReadFromFile. Non dovresti testare da dove proviene quel valore (o se esiste anche) allo stesso tempo.

Rendere la classe DLLConfig più "testabile" ha il vantaggio aggiuntivo di separare i problemi. Quando stai pensando a una classe e non puoi fare a meno di dire "Questo classe fa questoEche" (astrarre i dati di configurazione e leggere quei dati da un file) è una buona scommessa che la classe sta mescolando preoccupazioni e provando a fare molto. Se DLLConfig è un'astrazione di dati di configurazione, dovrebbe concentrarsi solo su quello e lasciare dove i dati provengono da un'altra classe.

1

Se nessuna delle risposte precedenti lavorato per voi, ho risolto questo problema aggiungendo Thread.Sleep(1) prima che l'affermazione nella prova in mancanza ...

Sembra che i test di sincronizzazione è mancato qualche parte ... Si prega di notare che i miei test non dipendono dall'ordine, non ho alcun membro statico né dipendenza esterna.

+0

Ho trascorso un'intera giornata lavorativa cercando di trovare una soluzione. Grazie mille, funziona perfettamente! – wrager