xUnit Test Deadlock

dapper linq-to-sql xunit.net

Frage

Wenn ich meine xUnit-Komponententests ausführe, erhalte ich manchmal eine Fehlermeldung wie "Transaktion (Prozess-ID 58) wurde auf Sperrressourcen mit einem anderen Prozess blockiert und wurde als zufälliges Deadlock-Opfer bei einem oder mehreren der Tests ausgewählt. Wenn ich einen fehlgeschlagenen Test eigenständig erneut durchführe, wird er bestanden.

Was soll ich tun, um dies zu verhindern? Gibt es eine Möglichkeit, die Tests nacheinander statt auf einmal durchzuführen?

(NB Ich führe die Tests über die API-Methoden in meinem ASP.Net 5 MVC-Controller unter Visual Studio 2015)

Hier ist ein Beispiel für einen meiner gelegentlich ausfallenden Tests:

[Fact]
private void TestREAD()
{
    Linq2SQLTestHelpers.SQLCommands.AddCollections(TestCollections.Select(collection => Convert.Collection2DB(collection)).ToList(), TestSettings.LocalConnectionString);
    foreach (var testCollection in TestCollections)
    {
        var testCollectionFromDB = CollectionsController.Get(testCollection.Id);
        Assert.Equal(testCollection.Description, testCollectionFromDB.Description);
        Assert.Equal(testCollection.Id, testCollectionFromDB.Id);
        Assert.Equal(testCollection.IsPublic, testCollectionFromDB.IsPublic);
        Assert.Equal(testCollection.LayoutSettings, testCollectionFromDB.LayoutSettings);
        Assert.Equal(testCollection.Name, testCollectionFromDB.Name);
        Assert.Equal(testCollection.UserId, testCollectionFromDB.UserId);
    }
}

Es gibt zwei Methoden, die der Test aufruft, hier ist die Controller-Methode:

[HttpGet("{id}")]
public Collection Get(Guid id)
{
    var sql = @"SELECT * FROM Collections WHERE id = @id";
    using (var connection = new SqlConnection(ConnectionString))
    {
        var collection = connection.Query<Collection>(sql, new { id = id }).First();
        return collection;
    }
}

und hier ist die Hilfsmethode:

public static void AddCollections(List<Collection> collections, string connectionString)
{
    using (var db = new DataClassesDataContext(connectionString))
    {
        db.Collections.InsertAllOnSubmit(collections);
        db.SubmitChanges();
    }
}

(Beachten Sie, dass ich Dapper als Micro-ORM in der Controller-Methode verwende. Um zu vermeiden, dass Fehler im Test dupliziert werden, verwende ich LINQ to SQL anstelle von Test und Testdaten .)

Es gibt auch Datenbankaufrufe im Konstruktor der Komponententests und in der Dispose-Methode. Ich kann sie bei Bedarf zum Beitrag hinzufügen.

Akzeptierte Antwort

OK, sieht also aus wie eine einfache Vanilla-Hülle von Deadlocks in Ihrer App und die Notwendigkeit, damit umzugehen - was ist Ihr Plan auf der App-Seite?

Die Tests und deren Daten-Rigging können möglicherweise der gleichen Sache zum Opfer fallen. xUnit hat nichts, um dies anzugehen, und ich würde stark argumentieren, dass es nicht sollte.

Sowohl im Test als auch in der App benötigen Sie eine Fehler- / Wiederholungsverwaltung.

Für eine Web-App, haben Sie ein Bild von einem Wal schießen und lassen Sie sie wieder versuchen Muster, aber letztlich wollen Sie eine echte Lösung.

Für einen Test wollen Sie keine Wale und wollen es unbedingt, sprich nicht brüchig sein.

Ich würde Poly verwenden, um Wiederholungsdekoration um alles in der App oder in den Tests zu verpacken, die zu erheblichen Fehlern neigen - Ihre Übung besteht darin, herauszufinden, was die wesentlichen Fehler in Ihrem Kontext sind.


Unter normalen Umständen sollte eine Datenbank mit einem einzelnen Leser / Schreiber, der synchron arbeitet, nicht blockieren. Analysieren, warum es passiert, ist eine Frage der Analyse auf der DB-Seite. Die Tools dieser Seite würden Ihnen wahrscheinlich auch schnell auffallen, wenn Sie z. B. einen Aspekt Ihres Gesamtsystems unter Test haben, der zu konkurrierender Arbeit führt.

(Offensichtlich sind Ihre Snippets unvollständig, da es eine Trennung zwischen CollectionsController.Get(testCollection.Id) und der Tatsache gibt, dass die Controller-Methode nicht static - der Punkt dieser Diskussion sollte jedoch nicht auf dieser IMO-Ebene liegen)



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum