2017-10-16 3 views
3

J'écris des tests unitaires pour un projet C# en utilisant les outils de tests unitaires intégrés de Visual Studio, et beaucoup de ces tests nécessitent l'utilisation d'un fichier TestData.xlsx.Écrire en toute sécurité des tests unitaires qui dépendent de la même ressource de fichier?

Actuellement, lorsque j'exécute mes tests, je remarque que le test précédent ne libère pas sa retenue sur le fichier à temps pour le test suivant. Cela provoque l'échec du test. Comment suis-je supposé écrire mes tests pour éviter que cela ne se produise?

Voici un exemple de ce que je fais face à:

[TestClass] 
    public class ExcelWorksheetExtensionTests 
    { 
     private ExcelPackage excelPackage; 

     private ExcelWorksheet excelWorksheet; 

     [TestInitialize] 
     [DeploymentItem(@"Assets\TestData.xlsx")] 
     public void TestInitialize() 
     { 
      FileInfo fileInfo = new FileInfo(@"Assets\TestData.xlsx"); 
      this.excelPackage = new ExcelPackage(fileInfo); 
      this.excelWorksheet = this.excelPackage.Workbook.Worksheets["Sheet1"]; 
     } 

     [TestCleanup] 
     public void TestCleanup() 
     { 
      this.excelPackage.Dispose(); 
     } 

     // This test may succeed... 
     [TestMethod] 
     public void TestGetRowIndexForExistingName() 
     { 
      Assert.AreEqual(this.excelWorksheet.GetRowIndex("Object49").Value, 6); 
     } 

     // ...But this test will fail because TestInitialize re-runs too quickly. 
     [TestMethod] 
     public void TestGetRowIndexForMissingName() 
     { 
      Assert.IsFalse(this.excelWorksheet.GetRowIndex("NonExistentName").HasValue); 
     } 
    } 
+0

Qu'est-ce que 'ExcelPackage'? Implémente-t-il 'IDisposable'? – Lee

+0

Dans ce cas, il semble que vous ayez à mettre 'excelPackage' dans une méthode de démontage de test. – Lee

+0

@Lee C'est une classe dans une bibliothèque appelée EPPlus pour interagir avec des documents Excel. Bonne prise; J'ai ajouté une méthode TestCleanup qui appelle Dispose(). Cependant, les tests échouent encore car je crois qu'ils fonctionnent en parallèle. –

Répondre

2

Je connais pas trop les EPPlus mais ce de ce que je vois est que vous avez une ressource partagée ExcelWorksheet et commençons accédé à partir de différents threads dans chaque test. Vous devez vérifier pour voir si les appels d'interrogation sont thread-safe?

Je ne sais pas quelle version de 'EPPlus' vous utilisez mais avec la dernière version (4.1.1) il n'y a pas de fonction appelée GetRowIndex mais j'ai quand même amélioré le test pour ressembler à ceci:

[TestClass] 
public class ExcelWorksheetExtensionTests 
{ 
    private FileInfo _fileInfo; 

    [TestInitialize] 
    public void TestInitialize() 
    { 
     _fileInfo = new FileInfo(@"C:\Test.xlsx"); 
    } 

    // This test may succeed... 
    [TestMethod] 
    public void TestGetRowIndexForExistingName() 
    { 
     using (var excelPackage = new ExcelPackage(_fileInfo)) 
     { 
      var excelWorksheet = excelPackage.Workbook.Worksheets["Sheet1"]; 
      Assert.AreEqual(excelWorksheet.GetValue(1, 1), 6.0); 
     } 
    } 

    // ...But this test will fail because TestInitialize re-runs too quickly. 
    [TestMethod] 
    public void TestGetRowIndexForMissingName() 
    { 
     using (var excelPackage = new ExcelPackage(_fileInfo)) 
     { 
      var excelWorksheet = excelPackage.Workbook.Worksheets["Sheet1"]; 
      Assert.IsFalse(excelWorksheet.GetValue(1, 1) == null); 
     } 
    } 
} 

maintenant, chaque test a il est maintenant instance de ExcelWorksheet et les conditions de course possibles sur la ressource partagée précédente sont éliminés avec les deux tests qui passe maintenant avec brio.

+0

Merci, cela fonctionne. Pour éviter toute confusion, 'GetRowIndex()' était une méthode d'extension que j'avais moi-même ajoutée. –