0

Also habe ich zwei Klassen, jede besteht aus Datenbank-Integrationstests. In jedem Konstruktor Klassen ich eine Methode setzte die Datenbank zurück:Deadlock auf xUnit Test bei der Verarbeitung von Daten auf der Datenbank

public class FirstClassSpec { 
    public FirstClassSpec() { 
     var dataSetup = new DataSetup(); 
     dataSetup.CleanTables(); 
    } 

    [Fact] 
    public async Task FirstTest() { 
     using(var conn = new SqlConnection("connStringHere")){ 
      var result = await conn.ExecuteAsync("someSqlCommand"); 
      Assert.True(result > 0); 
     } 
    } 
} 

public class SecondClassSpec { 
    public SecondClassSpec() { 
     var dataSetup = new DataSetup(); 
     dataSetup.CleanTables(); 
    } 

    [Fact] 
    public async Task SecondTest() { 
     using(var conn = new SqlConnection("connStringHere")){ 
      var result = await conn.ExecuteAsync("someSqlCommand"); 
      Assert.True(result > 0); 
     } 
    } 
} 

public class DataSetup { 
    public void CleanTables() { 
     using(var conn = new SqlConnection("connStringHere")){ 
      await conn.Execute("someSqlCommandToCleanTables"); 
     } 
    } 
} 

Um die Tests von Visual Studio 2015 zu laufen, ich benutze Run All Tests in Test Explorer. Ich habe die Nachricht von

Transaktion (Prozess-ID {someID}) wurde auf Sperre Ressourcen Deadlock mit einem anderen Prozess

Dieses Problem tritt nur, wenn ich alle Tests laufen. Wenn ich jeden Test einzeln oder mit mehreren Tests, aber aus derselben Klasse, ausfühle, tritt der Deadlock nicht auf. Ich fand heraus, dass die CleanTables() Methode, die im Konstruktor der Klassen aufgerufen wird, dies verursacht. Ich nehme an, die Tests laufen parallel, und CleanTables() wurde gleichzeitig von den beiden Klassen aufgerufen. So dann habe ich versucht CleanTables() in eine Asynchron-Methode zu machen:

public async Task<int> CleanTables() { 
    using(var conn = new SqlConnection("connStringHere")){ 
     return await conn.Execute("someSqlCommandToCleanTables"); 
    } 
} 

und dann auf den Klassen-Konstruktor ich es so nennen:

Aber jetzt, wenn ich zu Run All Tests versuchen, die Tests Sie liefen, aber sie werden nie fertig und ich bekomme nie das Ergebnis.

Meine Frage ist, warum der Deadlock auftritt? und warum wurde die CleanTables()-Methode in async geändert, damit die laufenden Tests nie ausgeführt werden? Ich muss wirklich die Tabellen vor jedem Testlauf säubern.

----------------- UPDATE -----------------------

ich habe versucht, alle Testklassen dekoriert mit [Collection["CollectionName"]], mit jeder Klasse hat verschiedene Namen:

[Collection["FirstSpec"]] 
public class FirstClassSpec { 
    //.... 
} 

[Collection["SecondSpec"]] 
public class FirstClassSpec { 
    //.... 
} 

Aber die Deadlock auftritt ..

---------- ------- UPDATE 2 -----------------------

Stellt fest, dass Klassen, die den gleichen Auflistungsnamen aufweisen, sequenziell ausgeführt werden und dadurch das Deadlock-Problem gelöst wird.

+0

Haben Sie versucht, mit Hilfe von [SQL Server Profiler, um die Analyse der Sackgasse] (https://docs.microsoft.com/ de-de/sql/tools/sql-server-profiler/analysieren-deadlocks-with-sql-server-profiler)? Es hat mir in der Vergangenheit geholfen. –

Antwort

1

Ihre Schätzung ist korrekt, da der Test parallel ausgeführt wird. Standardmäßig führt xUnit keine Tests in derselben Klasse parallel durch. Um Ihr Problem zu beheben, können Sie alle Ihre Tests in eine Klasse verschieben. Alternativ könnten Sie Ihre Klassen mit [Collection("My Collection")] dekorieren, um anzuzeigen, dass die Tests in beiden Klassen nicht parallel ausgeführt werden sollten.

erfahren Sie mehr darüber, wie xUnit entscheidet, wie Tests parallel laufen hier: https://xunit.github.io/docs/running-tests-in-parallel.html

+0

Danke für Ihre Lösungen! Aber nein, ich möchte nicht alle meine Tests in eine Klasse verschieben (es wird schwer zu pflegen). Ich werde versuchen, meine Klasse später mit '[Collection [" My Collection "]] zu dekorieren.Wenn das funktioniert, markiere ich deine Antwort als Antwort! :) – samAlvin

+0

Ich habe versucht alle Testklassen mit [Collection ["CollectionName"]] zu dekorieren, wobei jede Klasse einen anderen Namen hat .. Aber der Deadlock tritt immer noch auf .. Ich habe meine Frage aktualisiert. – samAlvin

+0

Jede Klasse sollte haben den gleichen Sammlungsnamen. –

Verwandte Themen