NUnit Test Run Order

109

Standardmäßig werden Nunit-Tests alphabetisch ausgeführt. Kennt jemand eine Möglichkeit, die Ausführungsreihenfolge festzulegen? Gibt es dafür ein Attribut?

Riain McAtamney
quelle
7
Warum willst du das tun? Es hört sich so an, als ob Sie von der Ausführungsreihenfolge abhängig sind, was eine schlechte Sache ist. Sie müssen sich überlegen, warum Sie das wollen. Unit-Tests sollten isoliert und völlig unabhängig von anderen durchgeführt werden. Es hört sich so an, als würden Sie Kandidaten für den Testgeruch erstellen .
RichardOD
Dies sieht aus wie ein Duplikat, aber Sie können meine Antwort darauf hier sehen
Johnno Nolan
12
@RichardOD - sollte! = Muss. Und es ist wirklich kein Ereignis, denn eigentlich werden fast alle Integrationstests in der richtigen Reihenfolge ausgeführt. Fragen Sie Ihr QA-Team, ob sie die Reihenfolge ihrer Tests zufällig festlegen.
Tymtam
4
Ich habe derzeit einige Tests, deren Reihenfolge wichtig zu sein scheint, obwohl dies nicht der Fall sein sollte. Persönlich möchte ich eine Möglichkeit haben, die Testreihenfolge speziell zu randomisieren, um sicherzustellen, dass meine Tests nicht irgendwie auftragsabhängig sind. Was ich WIRKLICH möchte, wäre natürlich ein Testläufer, der alle meine Tests in zufälliger Reihenfolge ausführt, bis er ein Problem findet, oder ich sage Stopp. Wenn ich das über Nacht laufen ließ und morgens alles noch grün war, konnte ich sicher sein, dass ich die letzten unbeabsichtigten Nebenwirkungen beseitigt habe.
Mel
1
Diese Frage würde relevanter werden, wenn die Frage aktualisiert würde, um anzugeben, dass es sich hier um Integrationstests handelt ... Wir alle kennen die Regeln für Komponententests, zumindest wenn Sie XUnit-Testmuster gelesen und Onkel Bob usw. gefolgt sind. Sie tun es .. aber Frameworks wie NUnit sind auch sehr nützlich, um Integrationstests schnell zum Laufen zu bringen .. und Sie möchten definitiv nicht, dass diese zufällig sind, insbesondere wenn ein teures Datenbank-Setup
erforderlich

Antworten:

51

Ihre Unit-Tests sollten jeweils unabhängig und eigenständig ausgeführt werden können. Wenn sie dieses Kriterium erfüllen, spielt die Reihenfolge keine Rolle.

Es gibt jedoch Fälle, in denen Sie zuerst bestimmte Tests ausführen möchten. Ein typisches Beispiel ist eine Situation mit kontinuierlicher Integration, in der einige Tests länger ausgeführt werden als andere. Wir verwenden das Attribut category, damit wir die Tests, bei denen Mocking verwendet wird, vor den Tests ausführen können, bei denen die Datenbank verwendet wird.

dh setzen Sie dies zu Beginn Ihrer Schnelltests

[Category("QuickTests")]

Berücksichtigen Sie bei Tests, die von bestimmten Umgebungsbedingungen abhängen , die Attribute TestFixtureSetUp und TestFixtureTearDown , mit denen Sie Methoden markieren können, die vor und nach Ihren Tests ausgeführt werden sollen.

NeedHack
quelle
2
@ Chris, ich neige dazu, diese Attribute nicht zu verwenden. Dies ist ein interessanter Blog- Beitrag jamesnewkirk.typepad.com/posts/2007/09/why-you-should-.html . Netter Punkt über Kategorietests.
RichardOD
29
Ein weiteres Beispiel für auftragsabhängige Tests ist, wenn Sie Ihr Nunit-Framework verwenden möchten, um einen Integrationstest auszuführen ...
Byron Ross
1
@ByronRoss: Ich neige dazu, Tests zu vergrößern, wenn ich das mache, und stütze mich so weit wie möglich auf die vorhandenen Komponententests, damit ich weniger Tests schreiben kann. Dann kann jeder vollständige Durchlauf separat fehlschlagen. Ich versuche auch, meine Daten so zu gestalten, dass sie getrennt von vorhandenen Daten leben können, anstatt von vorhandenen Daten abhängig zu sein.
Merlyn Morgan-Graham
1
Wenn Sie Ihre Tests nicht in zufälliger Reihenfolge ausführen, wie können Sie überprüfen, ob sie tatsächlich funktionieren, wenn sie nicht in der richtigen Reihenfolge ausgeführt werden? Was Sie sagen, ist analog zu "Wenn Ihre Software keine Fehler aufweist, ist das Testen nicht erforderlich".
Jforberg
@jforberg: Wenn Sie einen Fehler haben, der zufällig auftritt, wie sagen Sie, wenn Sie ihn behoben haben?
NeedHack
175

Ich möchte nur darauf hinweisen, dass die meisten Befragten zwar davon ausgegangen sind, dass es sich um Komponententests handelt, in der Frage jedoch nicht angegeben wurde, dass dies der Fall ist.

nUnit ist ein großartiges Tool, das für eine Vielzahl von Testsituationen verwendet werden kann. Ich kann geeignete Gründe dafür sehen, die Testreihenfolge kontrollieren zu wollen.

In solchen Situationen musste ich darauf zurückgreifen, eine Ausführungsreihenfolge in den Testnamen aufzunehmen. Es wäre großartig, die Ausführungsreihenfolge mithilfe eines Attributs angeben zu können.

Les
quelle
Sie meinen, Sie haben zum Beispiel Ihre Tests angerufen 001_first_test 002_second_testund so weiter?
Asche999
Ja, das ist richtig, obwohl ich normalerweise ein Muster verwende, mit dem ich bei Bedarf problemlos Tests einfügen kann, also vielleicht 010_first_test, 020_second_test usw.
Les
83
Vielen Dank für die einzig vernünftige Antwort hier. Dies ist eine spezifische Frage, aber irgendwie werden vage pedantische Antworten positiv bewertet. Ja, wir alle wissen, was Unit-Tests sein sollten, aber das ist nicht die Frage.
Egor Pavlikhin
1
Sie sollten sich nicht darauf verlassen, dass die Ausführungsreihenfolge alphabetisch ist. Viele Testläufer führen Ihre Tests gleichzeitig in vielen Threads oder Prozessen aus und nicht unbedingt in alphabetischer Reihenfolge. Zum Beispiel priorisiert NCrunch Tests basierend auf dem von Ihnen geänderten Code (betroffene Tests), danach, ob sie beim letzten Mal fehlgeschlagen sind und ob sie schnell oder langsam ausgeführt werden. Wenn Sie eine definierte Reihenfolge wünschen , erstellen Sie einfach einen Meta-Runner für diese Tests und schließen Sie sie von den regulären Läufen aus.
Abel
3
Ein weiterer guter Grund, die Reihenfolge anzugeben, besteht darin, zuerst bestimmte Probleme zu erkennen, bevor Sie mit dem Rest der Testsuite fortfahren. Mit anderen Worten, wenn mein Test zum Erstellen eines Benutzers fehlschlägt, muss nicht alles andere ausgeführt werden, bevor ich dieses Ergebnis herausfinde. In meinem anderen Test verspotte ich wahrscheinlich den Benutzer, aber es ist mir wichtig, dass dies der erste Test ist, der fehlschlägt - insbesondere wenn die Testsuite groß ist.
Bron Davies
123

NUnit 3.2.0 hat eine hinzugefügt OrderAttribute, siehe:

https://github.com/nunit/docs/wiki/Order-Attribute

Beispiel:

public class MyFixture
{
    [Test, Order(1)]
    public void TestA() { ... }


    [Test, Order(2)]
    public void TestB() { ... }

    [Test]
    public void TestC() { ... }
}
Răzvan Flavius ​​Panda
quelle
5
Danke, genau auf den Punkt, wonach ich gesucht habe - und keine Diskussionen, warum es gut oder schlecht ist :)
aknoepfel
1
Und dann machen sie es zu einer Ganzzahl anstelle einer Dezimalzahl. Wenn also ein Test eingefügt werden muss, müssen alle Tests neu nummeriert werden.
Epitka
Sie könnten immer mit sehr großen Zahlen wie Millionen oder so etwas beginnen, wenn Sie mittlere Elemente auf diese Weise einführen möchten - nur mehr Tippen. Imo sollte es eine einfachere Möglichkeit geben, Dinge zu ordnen, als Zahlen für die Priorität wie einen Methodenabhängigkeitsbaum zu verwenden, aber jede hat ihre eigenen Nachteile.
Răzvan Flavius ​​Panda
9
Gute Antwort, aber Vorsicht, die Dokumentation besagt, dass Tests nicht auf den Abschluss vorheriger Tests warten.
ROX
Interessanterweise gibt es meiner Erfahrung nach keine Garantie für die Bestellung von Tests, wenn wir die Attribute Test und Order separat hinzufügen.
AT
22

Wenn die Tests in einer bestimmten Reihenfolge ausgeführt werden sollen, bedeutet dies nicht, dass die Tests voneinander abhängig sind. Ich arbeite derzeit an einem TDD-Projekt und bin ein guter TDDer. Ich habe alles verspottet / gestoppt, aber es würde funktionieren Es ist besser lesbar, wenn ich die Reihenfolge angeben könnte, in der die Testergebnisse angezeigt werden - thematisch statt alphabetisch. Bisher kann ich mir nur vorstellen, a_ b_ c_ Klassen Klassen, Namespaces und Methoden voranzustellen. (Nicht schön) Ich denke, ein [TestOrderAttribute] -Attribut wäre schön - nicht streng gefolgt vom Framework, sondern ein Hinweis, damit wir dies erreichen können

Wilhelm
quelle
10

Unabhängig davon, ob Tests auftragsabhängig sind oder nicht ... einige von uns möchten einfach alles auf geordnete Weise kontrollieren.

Unit-Tests werden normalerweise in der Reihenfolge ihrer Komplexität erstellt. Warum sollten sie nicht auch in der Reihenfolge ihrer Komplexität oder der Reihenfolge, in der sie erstellt wurden, ausgeführt werden?

Persönlich möchte ich, dass die Tests in der Reihenfolge ausgeführt werden, in der ich sie erstellt habe. In TDD wird jeder nachfolgende Test natürlich komplexer und benötigt mehr Zeit zum Ausführen. Ich würde es vorziehen, wenn der einfachere Test zuerst fehlschlägt, da er ein besserer Indikator für die Ursache des Fehlers ist.

Ich kann aber auch den Vorteil erkennen, dass sie in zufälliger Reihenfolge ausgeführt werden, insbesondere wenn Sie testen möchten, dass Ihre Tests keine Abhängigkeiten von anderen Tests aufweisen. Wie wäre es mit einer Option zum Testen von Läufern zu "Tests nach dem Zufallsprinzip ausführen, bis sie gestoppt werden"?

Mont Pierce
quelle
9

Ich teste mit Selenium auf einer ziemlich komplexen Website und die gesamte Testsuite kann länger als eine halbe Stunde dauern, und ich bin noch nicht in der Nähe, die gesamte Anwendung abzudecken. Wenn ich sicherstellen muss, dass alle vorherigen Formulare für jeden Test korrekt ausgefüllt werden, wird dem Gesamttest viel Zeit und nicht nur wenig Zeit hinzugefügt. Wenn das Ausführen der Tests zu viel Aufwand bedeutet, werden sie nicht so oft ausgeführt, wie sie sollten.

Also ordne ich sie und verlasse mich auf frühere Tests, um Textfelder und dergleichen auszufüllen. Ich verwende Assert.Ignore (), wenn die Voraussetzungen nicht gültig sind, aber ich muss sie in der richtigen Reihenfolge ausführen.

Anthony Biagioli
quelle
1
Total. Ich bin hier im selben Boot.
Sleeper Smith
Ich auch! Genau, warum ich auf diese Frage gelandet bin!
Niklas Wulff
@NiklasRingdahl Wenn Sie Visual Studio mit Nunit verwenden, Dump Nunit und MS-Tests verwenden. Dann können Sie die bestellte Testdatei von Visual Studio verwenden, um Testfälle in der Reihenfolge anzuordnen, in der sie ausgeführt werden sollen
Rahul Lodha
@ RahulLodha Danke! Ich werde das untersuchen.
Niklas Wulff
9

Die vorherige Antwort gefällt mir sehr gut.

Ich habe es ein wenig geändert, um ein Attribut zum Festlegen des Bestellbereichs verwenden zu können:

namespace SmiMobile.Web.Selenium.Tests
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using NUnit.Framework;

    public class OrderedTestAttribute : Attribute
    {
        public int Order { get; set; }


        public OrderedTestAttribute(int order)
        {
            Order = order;
        }
    }

    public class TestStructure
    {
        public Action Test;
    }

    class Int
    {
        public int I;
    }

    [TestFixture]
    public class ControllingTestOrder
    {
        private static readonly Int MyInt = new Int();

        [TestFixtureSetUp]
        public void SetUp()
        {
            MyInt.I = 0;
        }

        [OrderedTest(0)]
        public void Test0()
        {
            Console.WriteLine("This is test zero");
            Assert.That(MyInt.I, Is.EqualTo(0));
        }

        [OrderedTest(2)]
        public void ATest0()
        {
            Console.WriteLine("This is test two");
            MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(2));
        }


        [OrderedTest(1)]
        public void BTest0()
        {
            Console.WriteLine("This is test one");
            MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(1));
        }

        [OrderedTest(3)]
        public void AAA()
        {
            Console.WriteLine("This is test three");
            MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(3));
        }


        [TestCaseSource(sourceName: "TestSource")]
        public void MyTest(TestStructure test)
        {
            test.Test();
        }

        public IEnumerable<TestCaseData> TestSource
        {
            get
            {
                var assembly =Assembly.GetExecutingAssembly();
                Dictionary<int, List<MethodInfo>> methods = assembly
                    .GetTypes()
                    .SelectMany(x => x.GetMethods())
                    .Where(y => y.GetCustomAttributes().OfType<OrderedTestAttribute>().Any())
                    .GroupBy(z => z.GetCustomAttribute<OrderedTestAttribute>().Order)
                    .ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());

                foreach (var order in methods.Keys.OrderBy(x => x))
                {
                    foreach (var methodInfo in methods[order])
                    {
                        MethodInfo info = methodInfo;
                        yield return new TestCaseData(
                            new TestStructure
                                {
                                    Test = () =>
                                        {
                                            object classInstance = Activator.CreateInstance(info.DeclaringType, null);
                                            info.Invoke(classInstance, null);
                                        }
                                }).SetName(methodInfo.Name);
                    }
                }

            }
        }
    }
}
PvtVandals
quelle
Ich finde diesen Ansatz großartig. Beachten Sie jedoch, dass der Reflection-Code alle Methoden mit dem Attribut abruft. Wenn Sie also versuchen, ein bestimmtes Testgerät auszuführen, werden Sie möglicherweise überrascht sein, dass es mehr ausführt, als Sie gedacht haben. Sie können die LINQ-Abfrage leicht ändern, wenn dies nicht das gewünschte Verhalten ist. Siehe die Links in meiner Antwort für weitere Informationen.
Chrispy
OrderedTestwird in NUnit 3 nicht mehr unterstützt.
Conrad
7

Ich weiß, dass dies ein relativ alter Beitrag ist, aber hier ist eine andere Möglichkeit, Ihren Test in Ordnung zu halten, ohne die Testnamen umständlich zu machen. Wenn Sie das TestCaseSource-Attribut verwenden und das übergebene Objekt über einen Delegaten (Aktion) verfügt, können Sie nicht nur die Reihenfolge steuern, sondern auch den Test so benennen, wie er ist.

Dies funktioniert, da gemäß der Dokumentation die von der Testquelle zurückgegebenen Elemente in der Sammlung immer in der Reihenfolge ausgeführt werden, in der sie aufgelistet sind.

Hier ist eine Demo von einer Präsentation, die ich morgen gebe:

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

namespace NUnitTest
{
    public class TestStructure
    {
        public Action Test;
    }

    class Int
    {
        public int I;
    }

    [TestFixture]
    public class ControllingTestOrder
    {
        private static readonly Int MyInt= new Int();

        [TestFixtureSetUp]
        public void SetUp()
        {
            MyInt.I = 0;
        }

        [TestCaseSource(sourceName: "TestSource")]
        public void MyTest(TestStructure test)
        {
            test.Test();
        }

        public IEnumerable<TestCaseData> TestSource
        {
            get
            {
                yield return new TestCaseData(
                    new TestStructure
                    {
                        Test = () =>
                        {
                            Console.WriteLine("This is test one");
                            MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(1));
                        }
                    }).SetName(@"Test One");
                yield return new TestCaseData(
                    new TestStructure
                    {
                        Test = () =>
                        {
                            Console.WriteLine("This is test two");
                            MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(2));
                        }
                    }).SetName(@"Test Two");
                yield return new TestCaseData(
                    new TestStructure
                    {
                        Test = () =>
                        {
                            Console.WriteLine("This is test three");
                            MyInt.I++; Assert.That(MyInt.I, Is.EqualTo(3));
                        }
                    }).SetName(@"Test Three");
            }
        }
    }
}
Dave Bush
quelle
Ich verwende dieses Muster für parallele Integrationstests, die zu zeitaufwändig wären, um linear ausgeführt zu werden. Alle Tests beziehen sich auf einen Typ, daher verwende ich eine Aktion <T in>, und jede Aktion hat einen Schlüssel, der besagt, was "ShouldBeFoo" bedeutet. Auf diese Weise wird die Testfunktion im Testnamen angezeigt, und die TestCaseSource kann gefiltert werden, sodass verschiedene Testtypen zusammengefasst werden. Ironischerweise interessiert mich die Ausführungsreihenfolge nicht, aber ich stimme zu, dass es funktionieren würde.
Novaterata
Die Verwendung von TestCaseSourcegeordneten Tests ist ein Geniestreich. Gut gemacht. Ich habe diesen Ansatz zusammen mit dem folgenden gewählt und einige zusätzliche Modifikationen hinzugefügt, um die Verwendung zu vereinfachen. Weitere Informationen finden Sie unter den Links in meiner Antwort. Die zugrunde liegende Idee stammt jedoch aus dieser großartigen Antwort!
Chrispy
Leider muss bei NUnit 3 die Quelle von TestCaseSourcestatisch sein, was die Verwendung von Mustern ausschließt. Schade.
Conrad
@ Conrad. Ich sehe nicht, welchen Unterschied die Methode statisch macht oder nicht. Der Test kehrt immer noch in der richtigen Reihenfolge zurück.
Dave Bush
Es ist nicht die Methode, die statisch sein muss - die Quelle (Variable oder Eigenschaft) von TestCaseSourcemuss ein statisches Objekt in NUnit 3 sein, sonst werden die Tests nicht ausgeführt. Und Sie können keine dynamischen Objekte innerhalb eines statischen Objekts erstellen. Deshalb wird es in V. 3 nicht funktionieren.
Conrad
5

Ich arbeite mit in C # geschriebenen End-to-End-UI-Testfällen von Selenium WebDriver, die mit dem NUnit-Framework ausgeführt werden. (Nicht Einheitsfälle als solche)

Diese UI-Tests hängen sicherlich von der Ausführungsreihenfolge ab, da andere Tests als Voraussetzung einige Daten hinzufügen müssen. (Es ist nicht möglich, die Schritte in jedem Test durchzuführen.)

Nachdem ich den 10. Testfall hinzugefügt habe, sehe ich, dass NUnit in dieser Reihenfolge ausgeführt werden möchte: Test_1 Test_10 Test_2 Test_3 ..

Ich denke, ich muss die Namen der Testfälle vorerst zu alphabetisch sortieren, aber es wäre gut, wenn diese kleine Funktion zur Steuerung der Ausführungsreihenfolge zu NUnit hinzugefügt würde.

Hexa
quelle
9
Nicht einverstanden mit Arran: UI-Tests sind von Natur aus Sequenzen kleiner Schritte. Jeder Schritt sollte ein Test sein (Grund - wenn er fehlschlägt, muss ich wissen, welcher Schritt). Sequenzen können unabhängig sein, aber innerhalb einer Sequenz sind Reihenfolge und Stopp bei einem Fehler erforderlich.
Zasz
3

Normalerweise sollte Unit Test unabhängig sein, aber wenn Sie müssen, können Sie Ihre Methoden in alphabetischer Reihenfolge benennen, z.

[Test]
public void Add_Users(){}

[Test]
public void Add_UsersB(){}

[Test]
public void Process_Users(){}

oder du kannst tun ..

        private void Add_Users(){}

        private void Add_UsersB(){}

        [Test]
        public void Process_Users()
        {
           Add_Users();
           Add_UsersB();
           // more code
        }
Sebastian Castaldi
quelle
2
Außer jetzt müssen die Namen alphabetisch gemacht werden, was eine schreckliche Lösung ist. :(
@ user166390 - nicht es ist nicht schrecklich. Es funktioniert und hängt vom dokumentierten Verhalten von NUnit ab.
Tymtam
➕1 gut genug für mich, viel einfacher , wenn Sie beginnen Ihre Tests mit a_ b_ t1_, t2_statt oder auf diese angewiesen leicht nachfolgende Zeichen zu verpassen
Chris Marisic
3

Es gibt sehr gute Gründe, einen Testbestellungsmechanismus zu verwenden. Die meisten meiner eigenen Tests verwenden bewährte Methoden wie Einrichten / Herunterfahren. Andere erfordern große Datenmengen, mit denen dann eine Reihe von Funktionen getestet werden können. Bisher habe ich große Tests verwendet, um diese Integrationstests (Selenium Webdriver) durchzuführen. Ich denke jedoch, dass der oben vorgeschlagene Beitrag auf https://github.com/nunit/docs/wiki/Order-Attribute viel Verdienst hat. Hier ist ein Beispiel, warum eine Bestellung äußerst wertvoll wäre:

  • Verwenden von Selenium Webdriver zum Ausführen eines Tests zum Herunterladen eines Berichts
  • Der Status des Berichts (unabhängig davon, ob er heruntergeladen werden kann oder nicht) wird 10 Minuten lang zwischengespeichert
  • Das heißt, vor jedem Test muss ich den Berichtsstatus zurücksetzen und dann bis zu 10 Minuten warten, bis bestätigt wird, dass sich der Status geändert hat, und dann überprüfen, ob der Bericht korrekt heruntergeladen wurde.
  • Die Berichte können aufgrund ihrer Komplexität nicht auf praktische / zeitnahe Weise durch Verspottung oder einen anderen Mechanismus innerhalb des Testrahmens erstellt werden.

Diese Wartezeit von 10 Minuten verlangsamt die Testsuite. Wenn Sie ähnliche Caching-Verzögerungen über eine Vielzahl von Tests hinweg multiplizieren, nimmt dies viel Zeit in Anspruch. Durch das Bestellen von Tests kann die Dateneinrichtung direkt zu Beginn der Testsuite als "Test" durchgeführt werden, wobei Tests, die darauf beruhen, dass der Cache gegen Ende des Testlaufs kaputt geht.

user2986256
quelle
2

Diese Frage ist jetzt wirklich alt, aber für Leute, die dies durch Suchen erreichen können, habe ich die hervorragenden Antworten von user3275462 und PvtVandals / Rico genommen und sie zusammen mit einigen meiner eigenen Updates einem GitHub-Repository hinzugefügt . Ich habe auch einen zugehörigen Blog-Beitrag mit einigen zusätzlichen Informationen erstellt, die Sie für weitere Informationen einsehen können.

Hoffe das ist hilfreich für euch alle. Außerdem verwende ich häufig das Attribut "Kategorie", um meine Integrationstests oder andere End-to-End-Tests von meinen tatsächlichen Komponententests zu unterscheiden. Andere haben darauf hingewiesen, dass Komponententests keine Auftragsabhängigkeit haben sollten, andere Testtypen jedoch häufig. Dies bietet eine gute Möglichkeit, nur die gewünschte Testkategorie auszuführen und auch diese End-to-End-Tests zu bestellen.

Chrispy
quelle
Können
Morgan Soren
1

Ich bin überrascht, dass sich die NUnit-Community nichts ausgedacht hat, also habe ich selbst so etwas erstellt.

Ich entwickle derzeit eine Open-Source-Bibliothek , mit der Sie Ihre Tests bei NUnit bestellen können. Sie können Testvorrichtungen und "bestellte Testspezifikationen" gleichermaßen bestellen.

Die Bibliothek bietet folgende Funktionen:

  • Erstellen Sie komplexe Hierarchien für Testreihenfolgen
  • Überspringen Sie nachfolgende Tests, wenn ein Test in der richtigen Reihenfolge fehlschlägt
  • Ordnen Sie Ihre Testmethoden nach Abhängigkeit statt nach ganzzahliger Reihenfolge
  • Unterstützt die Verwendung neben ungeordneten Tests. Ungeordnete Tests werden zuerst ausgeführt.

Die Bibliothek ist tatsächlich davon inspiriert, wie MSTest die Bestellung mit .orderedtestDateien testet . Bitte schauen Sie sich ein Beispiel unten an.

[OrderedTestFixture]
public sealed class MyOrderedTestFixture : TestOrderingSpecification {
    protected override void DefineTestOrdering() {
        TestFixture<Fixture1>();

        OrderedTestSpecification<MyOtherOrderedTestFixture>();

        TestFixture<Fixture2>();
        TestFixture<Fixture3>();
    }

    protected override bool ContinueOnError => false; // Or true, if you want to continue even if a child test fails
}
Sebazzz
quelle
1

Wenn Sie verwenden [TestCase], gibt das Argument TestNameeinen Namen für den Test an.

Wenn nicht angegeben, wird ein Name basierend auf dem Methodennamen und den angegebenen Argumenten generiert.

Sie können die Reihenfolge der Testausführung wie folgt steuern:

                    [Test]
            [TestCase("value1", TestName = "ExpressionTest_1")]
            [TestCase("value2", TestName = "ExpressionTest_2")]
            [TestCase("value3", TestName = "ExpressionTest_3")]
            public void ExpressionTest(string  v)
            {
                //do your stuff
            }

Hier habe ich das Methodennamensuffix "ExpressionTest"mit einer Nummer verwendet.

Sie können alle alphabetisch geordneten Namen verwenden, siehe TestCase-Attribut

M. Hassan
quelle
0

Sie sollten nicht von der Reihenfolge abhängen, in der das Testframework Tests zur Ausführung auswählt. Tests sollten isoliert und unabhängig sein. Insofern sollten sie nicht von einem anderen Test abhängig sein, der die Bühne für sie bereitet oder nach ihnen aufräumt. Sie sollten auch unabhängig von der Reihenfolge der Testdurchführung (für einen bestimmten Schnappschuss des SUT) das gleiche Ergebnis liefern.

Ich habe ein bisschen gegoogelt. Wie üblich haben einige Leute auf hinterhältige Tricks zurückgegriffen (anstatt das zugrunde liegende Testbarkeits- / Designproblem zu lösen

  • Benennen Sie die Tests in alphabetischer Reihenfolge, sodass die Tests in der Reihenfolge angezeigt werden, in der sie ausgeführt werden müssen. NUnit kann dieses Verhalten jedoch mit einer späteren Version ändern, und dann werden Ihre Tests abgespritzt. Überprüfen Sie besser die aktuellen NUnit-Binärdateien für die Quellcodeverwaltung.
  • VS (IMHO, das mit seinen "agilen Tools" das falsche Verhalten fördert) hat in seinem MS-Test-Framework so genannte "geordnete Tests". Ich habe keine Zeit mit dem Lesen verschwendet, aber es scheint auf dasselbe Publikum ausgerichtet zu sein

Siehe auch: Eigenschaften eines guten Tests

Gishu
quelle
Es gibt Fälle, in denen schnellere Tests vor langen Tests ausgeführt werden sollen, insbesondere bei Integrations- und Abnahmetests. Beispiel: In einer Blogging-App: Sie testen zuerst die Anmeldung. Wenn diese Funktion nicht funktioniert, funktioniert das Posten auch nicht. Daher macht es keinen Sinn, diesen Test auszuführen (Sie können den Läufer manuell stoppen). Wenn Sie jedoch versuchen, weiterhin Tests durchzuführen, dauert es länger.
Marcel Valdez Orozco
@MarcelValdezOrozco - Sie können dieses Ziel erreichen, indem Sie Ihre Tests entweder über eine andere physische DLL oder mithilfe von Tags / Kategorien partitionieren. Sie können Ihre Build-Skripte erstellen, um DLLs / Kategorien der Reihe nach auszuführen. Im Allgemeinen führt das Zulassen der Reihenfolge von Tests normalerweise zu gekoppelten Tests, die Abhängigkeiten von den benachbarten Tests entwickeln (natürlich im Laufe der Zeit). AFAIR in der nächsten großen Version von NUnit wird es unterschiedliche Reihenfolge der Tests unterstützen, z. B. zufällig usw.
Gishu
2
Die weitere Partitionierung derselben Art von Tests (z. B. Abnahmetests) macht keinen Sinn, und die Trennung in eine andere DLL erhöht die Komplexität überall unnötig: Quellcode, Build-Skripte, Testskripte, Projektstruktur usw. Nur um eine einfache Neuordnung vorzunehmen Die Tests.
Marcel Valdez Orozco
Das Emittieren (also im Grunde alle spöttischen Bibliotheken) ist ein Grund, warum Ordnung wichtig wäre. Sie können Ihre App-Domäne nicht entladen, und der Nunit Runner (wenn alle Tests in einer Assembly ausgeführt werden) behält diese Domäne für alle Tests in mindestens dieser "Korrektur". Wenn ein Test einen Typ erstellt, um etwas zu testen, und ein anderer Test aufgrund der Reihenfolge mit diesem erstellten Typ in Konflikt steht, ist dies kein fehlerhafter Test. Sie sind logisch isoliert, es ist nur so, dass nUnit keine ordnungsgemäße Isolierung zwischen jedem 'Test' selbst bietet.
Kelly Elton
6
Dies ist eine ziemlich bevormundende Antwort und macht es lustig, weil sie wirklich nur für Unit-Tests gilt und es völlig ignoriert, pragmatisch zu sein.
Tymtam
0

Im Falle der Verwendung TestCaseSourcedes Schlüssels ist override string ToStringMethode, wie das funktioniert:

Angenommen, Sie haben eine TestCase-Klasse

public class TestCase
{
    public string Name { get; set; }
    public int Input { get; set; }
    public int Expected { get; set; }
}

Und eine Liste von Testfällen:

private static IEnumerable<TestCase> TestSource()
{
    return new List<TestCase>
    {
        new TestCase()
        {
           Name = "Test 1",
           Input = 2,
           Expected = 4
        },
        new TestCase()
        {
            Name = "Test 2",
            Input = 4,
            Expected = 16
        },
        new TestCase()
        {
            Name = "Test 3",
            Input = 10,
            Expected = 100
        }
    };
}

Verwenden wir es jetzt mit einer Testmethode und sehen, was passiert:

[TestCaseSource(nameof(TestSource))]
public void MethodXTest(TestCase testCase)
{
    var x = Power(testCase.Input);
    x.ShouldBe(testCase.Expected);
}

Dies wird nicht in der richtigen Reihenfolge getestet und die Ausgabe sieht folgendermaßen aus:

Geben Sie hier die Bildbeschreibung ein

Wenn wir also override string ToStringunserer Klasse Folgendes hinzufügen :

public class TestCase
{
    public string Name { get; set; }
    public int Input { get; set; }
    public int Expected { get; set; }

    public override string ToString()
    {
        return Name;
    }
}

Das Ergebnis ändert sich und wir erhalten die Reihenfolge und den Namen des Tests wie folgt:

Geben Sie hier die Bildbeschreibung ein

Hinweis:

  1. Dies ist nur ein Beispiel, um zu veranschaulichen, wie Name und Reihenfolge im Test ermittelt werden. Die Reihenfolge wird numerisch / alphabetisch festgelegt. Wenn Sie also mehr als zehn Tests haben, empfehle ich, Test 01, Test 02 ... Test 10, Test 11 usw. durchzuführen, da wenn Sie machen Test 1 und irgendwann wird Test 10 als die Reihenfolge Test 1, Test 10, Test 2 usw. sein.
  2. Die Eingabe und Erwartet kann ein beliebiger Typ, eine Zeichenfolge, ein Objekt oder eine benutzerdefinierte Klasse sein.
  3. Neben der Bestellung ist das Gute hier, dass Sie den Testnamen sehen, der wichtiger ist.
Maytham-ɯɐɥʇʎɐɯ
quelle