Frage

Ich bin gebeten worden, eine Testanwendung zu schreiben, die eine neue gespeicherte Prozedur auf mehreren Zeilen in einer Datenbank testen, muss im Grunde mag ich, so etwas tun:


[Test]
public void TestSelect()
{
    foreach(id in ids)
    {
        DataTable old = Database.call("old_stored_proc",id);
        DataTable new_ = Database.call("new_stored_proc",id);

        Assert.AreEqual(old.Rows[0]["column"],ne_.Rows[0]["column"]);
    }
}

Wenn ich diesen Test ausführen, wenn 1 Zeile das andere nicht überein, wird die gesamte Test nicht besteht; stattdessen würde ich zählen, wie viele Male die Behauptung übergeben wurde und wie oft es versagt hat. Gibt es eine Möglichkeit, dies mit NUnit zu tun?

Ich weiß, dass NUnit treibt sein könnte, und dies ist eine einfache Aufgabe, ohne es ... Ich wollte nur, es lernen. ;)

War es hilfreich?

Lösung

1) Wenn die IDs sind konstant und nicht bei Testlaufzeit nachgeschlagen, eine separate Einheit Prüfvorrichtung für jede ID erstellen. Auf diese Weise werden Sie wissen, welche ids scheitern tatsächlich. Siehe hier für eine aufzuschreiben auf die Probleme mit den Daten getrieben Tests:
http://googletesting.blogspot.com/2008/09/tott -Daten-driven-traps.html

2) Wenn Sie benötigen, um dynamisch die ids macht es unmöglich, eine Halterung für jede ID, mit einer Änderung Verwendung Akmads Vorschlag zu erstellen nachschlagen. Halten Sie eine Liste von IDs, wo die Werte nicht gleich sind und die Liste der Fehlermeldung hinzufügen. Es wird extrem schwierig sein, einen Fehler Test zu diagnostizieren, die nur die Anzahl der Fehler erklärt, wie Sie nicht wissen, was ids die Fehler verursachen.

3) Ich weiß nicht, wie schwierig es in NUnit zu tun sei, aber in PyUnit, wenn wir Tests auf dynamisch generierten Daten laufen müssen, wir dynamisch Tests Vorrichtungen erstellen und sie in die Klasse Testcase zu befestigen, so dass wir hat einen fehlgeschlagenen Test für jedes Stück von Daten, die nicht passieren. Obwohl ich das vorstellen würde ohne dynamische Fähigkeiten Python viel schwieriger sein.

Andere Tipps

Scheint, wie Sie gerade die falsche Sache Geltendmachung werden. Wenn Sie alle Werte überprüfen wollen, und dann behaupten, dass es keine Fehler gibt (oder die Anzahl der Fehler zeigen), dann versuchen Sie dies:

[Test]
public void TestSelect()
{
    int errors = 0;
    foreach(id in ids)
    {
        DataTable old = Database.call("old_stored_proc",id);
        DataTable new_ = Database.call("new_stored_proc",id);

        if (old.Rows[0]["column"] != new_.Rows[0]["column"])
        {
            errors++;
        }            
    }

    Assert.AreEqual(0, errors, "There were " + errors + " errors.");
}

Ich weiß, dass die Frage speziell über NUnit, aber interessanterweise Gallio / MbUnit verfügt über eine Funktion, die ermöglicht, laufen und einige Behauptungen auf einmal fangen.

[Test]
public void MultipleTest()
{
    Assert.Multiple(() =>
    {
       Assert.IsTrue(blabla);
       Assert.AreEqual(pik, pok);
       // etc.
    }
}

Die Assert.Multiple holt alle die versagenden Behauptungen und wird sie am Ende des Tests melden.

würde ich die Anzahl der Zeilen zählen, die nicht zusammenpassen und dann eine Assertion schreiben würde, die diese Zahl mit 0 vergleicht und würde die Anzahl der nicht passenden Zeichenfolgen in der Nachricht zurück.

Sie auch Assert.Greater für diese nutzen könnten.

P. S. Grundsätzlich sollten Sie versuchen, eine Behauptung pro Unit-Test zu tun. Das ist der Kern von ihm.

Nun, Sie einen Zähler erklären könnten und dann den Wert des Zählers behaupten Pass zu bestimmen / Fail

Auch könnten Sie den Großteil der Arbeit in dem Testaufbau tun, und dann einfach mehrere Tests erstellen.

Ich bin mir nicht klar, warum Sie benötigen, um alle assert stmts im gleichen Test.

Basierend auf dem Ziel Sie angelegt, den gesamten Test sollte fehlschlagen, wenn eine Zeile eines anderen nicht übereinstimmt. Zählen der Anzahl, wie oft eine Behauptung bestanden oder nicht bestanden haben Sie weniger Informationen als ein Vergleich der Ergebnisse Sie mit dem Ergebnis erwartet man tatsächlich bekam.

Vor kurzem hatte ich das gleiche Problem. Ich kombinierte die Idee von Fehlern mit Yann Trevin Erwähnung von Assert.Multiple in eine Erweiterungsmethode für IEnumberable zählen, die mich wie Dinge tun können:

[Test]
public void TestEvenNumbers()
{
    int[] numbers = new int[] { 2, 4, 12, 22, 13, 42 };
    numbers.AssertAll((num) => Assert.That((num % 2) == 0, "{0} is an odd number", num));
}

Welche Ergebnisse in dem NUnit-Ausgang:

TestEvenNumbers:
  5 of 6 tests passed; 0 inconclusive
FAILED: 13:   13 is an odd number
  Expected: True
  But was:  False

  Expected: 6
  But was:  5

Und die Lösung für das Problem des OP sei:

[Test]
public void TestSelect()
{
    ids.AssertAll(CheckStoredProcedures);
}

private void CheckStoredProcedures(Id id)
{
    DataTable old = Database.call("old_stored_proc",id);
    DataTable new_ = Database.call("new_stored_proc",id);

    Assert.AreEqual(old.Rows[0]["column"], new_.Rows[0]["column"]);
}

Hier ist die Extension-Methode (beachten Sie, dass ich „All“ anstelle von „Multiple“ für Konsistenz mit Linq verwendete Terminologie):

using System;
using System.Text;
using System.Collections.Generic;
using NUnit.Framework;

public static class NUnitExtensions
{
    public static void AssertAll<T>(this IEnumerable<T> objects, Action<T> test)
    {
        int total = 0;
        int passed = 0;
        int failed = 0;
        int inconclusive = 0;
        var sb = new StringBuilder();
        foreach (var obj in objects)
        {
            total++;
            try
            {
                test(obj);
                passed++;
            }
            catch (InconclusiveException assertion)
            {
                inconclusive++;
                string message = string.Format("INCONCLUSIVE: {0}: {1}", obj.ToString(), assertion.Message);
                Console.WriteLine(message);
                sb.AppendLine(message);
            }
            catch (AssertionException assertion)
            {
                failed++;
                string message = string.Format("FAILED: {0}: {1}", obj.ToString(), assertion.Message);
                Console.WriteLine(message);
                sb.AppendLine(message);
            }
        }

        if (passed != total)
        {
            string details = sb.ToString();
            string message = string.Format("{0} of {1} tests passed; {2} inconclusive\n{3}", passed, total, inconclusive, details);
            if (failed == 0)
            {
                Assert.Inconclusive(message);
            }
            else
            {
                Assert.AreEqual(total, passed, message);
            }
        }
    }
}

Sie können mit [TestCase()] Attribute wenn eine einfache hart codierte Liste von IDs .

[Test]
[TestCase(1234)]
[TestCase(5678)]
[TestCase(7654)]
public void TestSelect(int id)
{
    DataTable old = Database.call("old_stored_proc", id);
    DataTable new_ = Database.call("new_stored_proc", id);

    Assert.AreEqual(old.Rows[0]["column"], new_.Rows[0]["column"]);
}

Dies wird für jede ID drei separate Tests erzeugen und was auch immer nunit Test Runner Sie verwenden Pass Anzeige / Fail zählt.

Wenn die Notwendigkeit, eine dynamische Liste von IDs zu erzeugen, dann empfiehlt die Verwendung von [TestCaseSource()] Attribute .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top