2010-06-07 5 views
5

Je rencontre des problèmes avec certains tests unitaires MSTest qui passent lorsque je les exécute individuellement mais qui échouent lorsque j'exécute toute la classe de test unitaire. Les tests testent du code SLaks helped me with earlier, et il m'a prévenu que ce que je faisais n'était pas sûr pour les threads. Cependant, maintenant mon code est plus compliqué et je ne sais pas comment le rendre thread-safe. Voici ce que j'ai:MSTest passe le test unitaire, échoue lorsque d'autres tests sont exécutés

public static class DLLConfig 
{ 
    private static string _domain; 

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

Et mon test est simple:

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

Quand je lance ce test en lui-même, il passe. Lorsque je l'exécute avec tous les autres tests de la classe de test (qui effectuent des vérifications similaires sur différentes propriétés), actual est null et le test échoue. Je note que ce n'est pas un problème avec une propriété dont le type est un type personnalisé Enum; peut-être que j'ai ce problème avec la propriété Domain parce que c'est un string? Ou peut-être est-ce un problème multi-thread avec comment fonctionne MSTest?

+0

Comment (le cas échéant) configurez-vous/arrêtez-vous entre les tests? – Paddyslacker

+0

@Paddyslacker: pas du tout. Je n'ai pas de méthodes [TestCleanup] ou [TestInitialize] '. –

+1

Les bons tests unitaires sont indépendants, donc je regarderais faire ces vrais tests unitaires en ajoutant un peu d'installation et de démontage pour obtenir votre code dans un état connu à chaque fois. S'il y a un vrai cas de test pour appeler la méthode simultanément ou l'appeler deux fois, alors écrivez un cas de test spécifique qui échoue pour cela, puis faites le passer. – Paddyslacker

Répondre

6

Je soupçonne que les autres tests modifient une certaine valeur dans la classe DLLConfig qui provoque le changement du résultat du getter. Les tests unitaires doivent toujours être exécutés à partir d'un état initial connu. Vous devez donc le configurer dans la méthode de test elle-même ou dans une méthode marquée avec l'attribut TestInitialize exécuté avant chaque test.

5

Votre test dépend d'un fichier externe. Au lieu d'appeler une fonction qui accède directement au fichier, vous devriez avoir DLLConfig.Domain appeler une méthode dans une autre classe.

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

Ensuite, vous pouvez initialiser DllConfig avec une maquette/faux/stub CredentialReader où vous pouvez contrôler sa valeur de retour. N'oubliez pas que vous testez que DLLConfig.Domain renvoie la valeur correcte en fonction de la condition AlwaysReadFromFile. Vous ne devriez pas tester d'où vient cette valeur (ou si elle existe même) en même temps. Rendre votre classe DLLConfig plus «testable» a l'avantage supplémentaire de séparer les problèmes. Quand vous pensez à une classe et ne peux pas m'empêcher de dire "Cette classe ne ceetque" "(abstraction des données de configuration et de lire ces données à partir d'un fichier) c'est un bon pari que la classe mélange préoccupations et essayer de faire beaucoup. Si DLLConfig est une abstraction de données de configuration, il devrait se concentrer uniquement sur cela et laisser d'où les données proviennent d'une autre classe.

1

Si aucune des réponses ci-dessus travaillé pour vous, je l'ai résolu ce problème en ajoutant Thread.Sleep(1) avant l'affirmation contenue dans le test ne ...

Ressemble synchronisation des tests est quelque part ... S'il vous plaît manqué noter que mes tests n'étaient pas dépendants de l'ordre, que je n'ai pas de membre statique ni de dépendance externe.

+0

J'ai passé toute une journée de travail à essayer de trouver une solution. Merci beaucoup, cela fonctionne parfaitement! – wrager