Steuern der Ausführungsreihenfolge von Komponententests in Visual Studio

78

Okay, ich bin fertig mit der Suche nach guten Informationen dazu. Ich habe eine Reihe von Komponententests, die eine statische Klasse aufrufen, die nach der Initialisierung Eigenschaften festlegt, die sich nicht ändern können (oder möchten).

Mein Problem ist, dass ich keine festgelegte Reihenfolge für die Ausführung der Tests erzwingen kann. Wenn ich könnte, könnte ich sie so ausführen, dass die statischen Eigenschaften zuverlässig festgelegt würden, und ich könnte sie bestätigen, aber leider führt das Microsoft.VisualStudio.TestTools.UnitTesting-Framework sie nur in einer scheinbar zufälligen Reihenfolge aus .

Also fand ich diese http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.priorityattribute.aspx, die im Abschnitt "Bemerkungen" lautet: "Dieses Attribut wird vom Testsystem nicht verwendet. Es wird dem Benutzer für benutzerdefinierte Zwecke zur Verfügung gestellt. " Huh? Was nützt es dann? Erwarten sie, dass ich meinen eigenen Test-Wrapper schreibe, um dieses fabelhafte Attribut zu nutzen (von dem ich mich leicht selbst schreiben könnte, wenn ich mich so anstrengen wollte ...)?

Also genug von der Schimpfe; Gibt es unter dem Strich eine Möglichkeit, die Reihenfolge zu steuern, in der meine Komponententests ausgeführt werden?

[TestMethod]
[Priority(0)]

usw. scheint NICHT zu funktionieren, was Sinn macht, da Microsoft sagt, dass dies nicht der Fall ist.

Bitte auch keine Kommentare zu "Verletzung der Isolation". Die Testklasse isoliert, was ich teste, nicht die einzelnen Testmethoden. Unabhängig davon kann jeder Test unabhängig und problemlos ausgeführt werden. Sie können nur nicht in zufälliger Reihenfolge zusammen ausgeführt werden, da die statische Klasse nicht heruntergerissen werden kann.

Oh, ich weiß auch über "Ordered Test" Bescheid.

iGanja
quelle
3
Können Sie erklären, warum Ihre Tests auftragsabhängig sind? Ich nehme an, die Tests testen die statische Klasse im Wesentlichen schrittweise.
Todd Bowles
13
Ihre Unit-Tests sollten nicht von der Bestellung abhängen. Diese hirntote statische Klasse macht Ihren Code nicht testbar. Wenn Sie es nicht "abreißen" können, ist dies nicht das einzige Problem, das Sie beim Testen von Einheiten haben werden.
John Saunders
4
Die statische Klasse gehört nicht mir - ja, sie sollte als Singleton geschrieben worden sein. Leider muss man manchmal einfach die (beschissenen) Karten spielen, die man bekommt. Ich benutze Fakes so oft wie möglich, um es aus der Gleichung zu entfernen, aber ich kann es nicht beseitigen.
iGanja
3
Sie können den statischen Klassenkontext nicht jedes Mal in einer TestInitialize zurücksetzen? Einer der Grundprinzipien des Unit-Tests ist die Unabhängigkeit. Versuchen Sie nicht, die Ausführungsreihenfolge zu steuern. Sie verletzen nicht die Isolation, sondern die Grundprinzipien, die einen Test zu einem Komponententest machen.
Pierre-Luc Pineault
6
Man kann viele Gründe haben, geordnete Tests durchzuführen. Und wenn man geordnete Tests durchführen muss, braucht man wirklich keine Kommentare, die wirklich nicht helfen, wie zum Beispiel zu sagen, dass man das nicht tun sollte usw. Ich frage das nächste Mal höflich, bitte überspringe diese Art von Kommentaren und versuche hilfreich zu sein. Oder überspringen Sie einfach den Thread insgesamt. Ich werde meine Antwort in einer Minute hinzufügen.
Tiago Freitas Leal

Antworten:

55

Führen Sie Ihre Tests zu einem riesigen Test zusammen. Um die Testmethode besser lesbar zu machen, können Sie so etwas tun

[TestMethod]
public void MyIntegratonTestLikeUnitTest()
{
    AssertScenarioA();

    AssertScenarioB();

    ....
}

private void AssertScenarioA()
{
     // Assert
}

private void AssertScenarioB()
{
     // Assert
}

Tatsächlich schlägt das Problem vor, dass Sie wahrscheinlich die Testbarkeit der Implementierung verbessern sollten.

Gang Gao
quelle
2
Das Zusammenführen der Tests ist ein fairer Ansatz. Wenn jedoch die erste Testmethode in der Liste eine Bestätigung nicht besteht, wird keine der anderen ausgeführt. In Anbetracht der Ordnungsabhängigkeit, die der Teststrategie des OP innewohnt, ist dies möglicherweise kein Problem.
Todd Bowles
1
Einverstanden @ToddBowles Dies könnte der richtige Weg sein. Und natürlich verlieren Sie, wie Sie sagten, bei einem großen Riesentest mit einer Menge Asserts etwas an Granularität, wenn einer fehlschlägt. +1
iGanja
Dies ist möglicherweise nicht die beste Lösung (das Re-Factoring der statischen Klasse ist), aber es ist sicherlich am einfachsten zu implementieren und bringt mich dazu, wieder an anderen Dingen zu arbeiten.
iGanja
Siehe meinen Kommentar unten zum ClassInitialize-Attribut. Ich glaube auch, dass OrderedTests ziemlich einfach zu implementieren sind und von MS akzeptiert werden.
MattyMerrix
3
Dies mag funktionieren, macht aber den Zweck des Unit-Tests zunichte. Die Idee des Unit-Tests ist es, Teile für schnelle Tests in Stücke zu zerlegen - nicht zusammenzuschlagen
Christian Findlay
115

Sie können die Wiedergabeliste verwenden

Klicken Sie mit der rechten Maustaste auf die Testmethode -> Zur Wiedergabeliste hinzufügen -> Neue Wiedergabeliste

Die Ausführungsreihenfolge wird so sein, wie Sie sie zur Wiedergabeliste hinzufügen. Wenn Sie sie jedoch ändern möchten, haben Sie die Datei

Geben Sie hier die Bildbeschreibung ein

HB MAAM
quelle
20
Ich habe es gerade in VS2015 versucht und es scheint, dass die Wiedergabeliste die Ausführungsreihenfolge nicht beeinflusst. Sie werden vielmehr in der Reihenfolge ausgeführt, in der die Methoden deklariert sind.
30.
28
@Jrd In Visual Studio 2015 haben sich die Dinge etwas geändert. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Komponententestprojekt und klicken Sie auf Hinzufügen> Bestellter Test. Dadurch wird dem Projekt eine neue Datei hinzugefügt. Wenn Sie diese Datei öffnen, können Sie auf Testmethoden in Ihrem Projekt klicken und diese mindestens einmal zu diesem Test hinzufügen.
Zee
Siehe meinen Kommentar unten zum ClassInitialize-Attribut. Ich glaube auch, dass OrderedTests ziemlich einfach zu implementieren sind und von MS akzeptiert werden.
MattyMerrix
Kann die Wiedergabeliste über die Befehlszeile aufgerufen werden, damit ich sie auf dem Build-Server verwenden kann?
Red888
1
@EA Sie sollten das Datum und die Uhrzeit berücksichtigt haben, auf die der Autor geantwortet hat. Interessant -> Er hatte 2013 geantwortet, Sie hatten 2015 kommentiert und ich habe 2017 kommentiert. Großartig; P :);)
RajeshKdev
15

Wie Sie inzwischen wissen sollten, sagen Puristen, es sei verboten, geordnete Tests durchzuführen. Dies könnte für Unit-Tests zutreffen. MSTest und andere Unit-Test-Frameworks werden verwendet, um reine Unit-Tests durchzuführen, aber auch UI-Tests, vollständige Integrationstests, wie Sie es nennen. Vielleicht sollten wir sie nicht Unit Test Frameworks nennen, oder vielleicht sollten wir sie entsprechend unseren Bedürfnissen verwenden. Das machen die meisten Leute sowieso.

Ich führe VS2015 aus und MUSS Tests in einer bestimmten Reihenfolge ausführen, da ich UI-Tests (Selenium) ausführe.

Priorität - Tut überhaupt nichts Dieses Attribut wird vom Testsystem nicht verwendet. Es wird dem Benutzer für benutzerdefinierte Zwecke zur Verfügung gestellt.

bestellter Test - es funktioniert, aber ich empfehle es nicht, weil:

  1. Ein geordneter Test Eine Textdatei, in der Ihre Tests in der Reihenfolge aufgelistet sind, in der sie ausgeführt werden sollen. Wenn Sie einen Methodennamen ändern, müssen Sie die Datei reparieren.
  2. Die Testausführungsreihenfolge wird innerhalb einer Klasse eingehalten. Sie können nicht bestellen, welche Klasse ihre Tests zuerst ausführt.
  3. Eine bestellte Testdatei ist an eine Konfiguration gebunden, entweder Debug oder Release
  4. Sie können mehrere geordnete Testdateien haben , aber eine bestimmte Methode kann nicht in verschiedenen geordneten Testdateien wiederholt werden. Sie können also nicht eine bestellte Testdatei für Debug und eine andere für Release haben.

Andere Vorschläge in diesem Thread sind interessant, aber Sie verlieren die Möglichkeit, den Testfortschritt im Test Explorer zu verfolgen.

Sie haben die Lösung, von der Purist abraten wird, aber tatsächlich funktioniert die Lösung: Sortieren nach Deklarationsreihenfolge .

Der MSTest-Executor verwendet ein Interop, das es schafft, die Deklarationsreihenfolge abzurufen. Dieser Trick funktioniert so lange, bis Microsoft den Test-Executor-Code ändert.

Dies bedeutet, dass die an erster Stelle deklarierte Testmethode vor der an zweiter Stelle deklarierten ausgeführt wird.

Um Ihnen das Leben zu erleichtern, sollte die Deklarationsreihenfolge mit der alphabetischen Reihenfolge übereinstimmen, die im Test-Explorer angezeigt wird.

  • A010_FirstTest
  • A020_SecondTest
  • etc
  • A100_TenthTest

Ich empfehle dringend einige alte und getestete Regeln:

  • Verwenden Sie einen Schritt von 10, da Sie später eine Testmethode einfügen müssen
  • Vermeiden Sie die Notwendigkeit, Ihre Tests neu zu nummerieren, indem Sie einen großzügigen Schritt zwischen den Testnummern verwenden
  • Verwenden Sie 3 Ziffern, um Ihre Tests zu nummerieren, wenn Sie mehr als 10 Tests ausführen
  • Verwenden Sie 4 Ziffern, um Ihre Tests zu nummerieren, wenn Sie mehr als 100 Tests ausführen

SEHR WICHTIG

Um die Tests in der Deklarationsreihenfolge auszuführen, müssen Sie im Test-Explorer Alle ausführen verwenden .

Angenommen, Sie haben 3 Testklassen (in meinem Fall Tests für Chrome, Firefox und Edge). Wenn Sie eine bestimmte Klasse auswählen und mit der rechten Maustaste auf Ausgewählte Tests ausführen klicken , wird normalerweise die zuletzt deklarierte Methode ausgeführt.

Wie ich bereits sagte, sollten die deklarierte Bestellung und die angegebene Bestellung übereinstimmen, da Sie sonst in kürzester Zeit große Probleme haben.

Tiago Freitas Leal
quelle
Durchführen einer Reihe von Funktionstests, die in die Datenbank schreiben. Es ist mir egal, ob sie wirklich in Ordnung laufen. Aber wenn sie passieren, ist der letzte der vollständigste Test. Sei nett, wenn es angedeutet wurde, zuletzt zu laufen. Ja. Ich verspotte auch. Unit Tests werden von Funktionstests getrennt gehalten. FTs werden im Rahmen meiner Hauptbereitstellung nur manuell für die lokale / Testumgebung ausgeführt. Ich führe keine Funktionstests für geringfügige Änderungen und Hotfixes durch. Das hat perfekt funktioniert!
TamusJRoyce
Ich verwende VS2019 und die Tests werden in alphabetischer Reihenfolge ausgeführt, ohne dass ich eingreifen muss. Genau das brauche ich. Ich habe Ihre Antwort aufgrund Ihres Ratschlags, Tests um zehn zu benennen, abgelehnt, damit später etwas eingefügt werden kann, ohne alles umzubenennen, was bereits getan wurde.
MsTapp
12

Ich sehe niemanden, der die ClassInitializeAttributmethode erwähnt. Die Attribute sind ziemlich einfach.

Erstellen Sie Methoden, die entweder mit dem Attribut [ClassInitialize()]oder gekennzeichnet sind [TestInitialize()], um Aspekte der Umgebung vorzubereiten, in der Ihr Komponententest ausgeführt wird. Damit soll ein bekannter Status für die Ausführung Ihres Komponententests festgelegt werden. Beispielsweise können Sie [ClassInitialize()]die [TestInitialize()]Methode oder verwenden, um bestimmte Datendateien zu kopieren, zu ändern oder zu erstellen, die Ihr Test verwenden wird.

Erstellen Sie Methoden, die entweder mit dem Attribut [ClassCleanup()]oder gekennzeichnet sind [TestCleanUp{}], um die Umgebung nach dem Ausführen eines Tests in einen bekannten Zustand zurückzusetzen. Dies kann das Löschen von Dateien in Ordnern oder die Rückkehr einer Datenbank in einen bekannten Zustand bedeuten. Ein Beispiel hierfür ist das Zurücksetzen einer Inventardatenbank auf einen Anfangszustand nach dem Testen einer Methode, die in einer Auftragserfassungsanwendung verwendet wird.

  • [ClassInitialize()]Verwenden ClassInitializeSie diese Option , um Code auszuführen, bevor Sie den ersten Test in der Klasse ausführen.

  • [ClassCleanUp()]Verwenden Sie ClassCleanupdiese Option , um Code auszuführen, nachdem alle Tests in einer Klasse ausgeführt wurden.

  • [TestInitialize()]Verwenden TestInitializeSie diese Option , um Code auszuführen, bevor Sie jeden Test ausführen.

  • [TestCleanUp()]Verwenden Sie TestCleanupdiese Option , um Code nach jedem Test auszuführen.

MattyMerrix
quelle
3
Es gibt auch AssemblyInitialize und AssemblyCleanup, die zu Beginn bzw. am Ende jedes Testlaufs ausgeführt werden.
MattyMerrix
6

Da Sie bereits die Funktionalität für geordnete Tests erwähnt haben, die das Visual Studio-Testframework bereitstellt, werde ich dies ignorieren. Sie scheinen sich auch bewusst zu sein, dass das, was Sie erreichen möchten, um diese statische Klasse zu testen, eine "schlechte Idee" ist, also werde ich das ignorieren.

Konzentrieren wir uns stattdessen darauf, wie Sie möglicherweise tatsächlich sicherstellen können, dass Ihre Tests in der gewünschten Reihenfolge ausgeführt werden. Eine Option (wie von @gaog bereitgestellt) ist "eine Testmethode, viele Testfunktionen", bei der Ihre Testfunktionen in der gewünschten Reihenfolge innerhalb einer einzelnen mit dem TestMethodAttribut gekennzeichneten Funktion aufgerufen werden. Dies ist der einfachste Weg, und der einzige Nachteil besteht darin, dass die erste fehlgeschlagene Testfunktion die Ausführung einer der verbleibenden Testfunktionen verhindert .

Mit Ihrer Beschreibung der Situation ist dies die Lösung, die ich Ihnen empfehlen würde.

Wenn der fettgedruckte Teil ein Problem für Sie darstellt, können Sie eine geordnete Ausführung isolierter Tests durchführen, indem Sie die integrierten datengesteuerten Testfunktionen nutzen. Es ist komplizierter und fühlt sich ein bisschen schmutzig an, aber es erledigt den Job.

Kurz gesagt, Sie definieren eine Datenquelle (wie eine CSV-Datei oder eine Datenbanktabelle), die die Reihenfolge steuert, in der Sie Ihre Tests ausführen müssen, sowie die Namen der Funktionen, die die Testfunktionalität tatsächlich enthalten. Anschließend binden Sie diese Datenquelle in einen datengesteuerten Test ein, verwenden die Option für sequentielles Lesen und führen Ihre Funktionen in der gewünschten Reihenfolge als einzelne Tests aus.

[TestClass]
public class OrderedTests
{
    public TestContext TestContext { get; set; }

    private const string _OrderedTestFilename = "TestList.csv";

    [TestMethod]
    [DeploymentItem(_OrderedTestFilename)]
    [DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", _OrderedTestFilename, _OrderedTestFilename, DataAccessMethod.Sequential)]
    public void OrderedTests()
    {
        var methodName = (string)TestContext.DataRow[0];
        var method = GetType().GetMethod(methodName);
        method.Invoke(this, new object[] { });
    }

    public void Method_01()
    {
        Assert.IsTrue(true);
    }

    public void Method_02()
    {
        Assert.IsTrue(false);
    }

    public void Method_03()
    {
        Assert.IsTrue(true);
    }
}

In meinem Beispiel habe ich eine unterstützende Datei namens TestList.csv, die in die Ausgabe kopiert wird. Es sieht aus wie das:

TestName
Method_01
Method_02
Method_03

Ihre Tests werden in der von Ihnen angegebenen Reihenfolge und in normaler Testisolation ausgeführt (dh wenn einer fehlschlägt, wird der Rest weiterhin ausgeführt, wobei jedoch statische Klassen gemeinsam genutzt werden).

Das Obige ist eigentlich nur die Grundidee. Wenn ich es in der Produktion verwenden würde, würde ich die Namen der Testfunktionen und deren Reihenfolge dynamisch generieren, bevor der Test ausgeführt wird. Vielleicht können Sie mithilfe von PriorityAttribute und einem einfachen Reflektionscode die Testmethoden in der Klasse extrahieren und entsprechend sortieren und diese Reihenfolge dann in die Datenquelle schreiben.

Todd Bowles
quelle
4

Hier ist eine Klasse, die zum Einrichten und Ausführen geordneter Tests unabhängig vom MS Ordered Tests-Framework verwendet werden kann, z. B. um die Argumente mstest.exe auf einer Build-Maschine nicht anpassen oder geordnete mit nicht geordneten in einer Klasse mischen zu müssen.

Das ursprüngliche Testframework sieht die Liste der geordneten Tests nur als einen einzelnen Test an, sodass Init / Cleanup wie [TestInitalize ()] Init () nur vor und nach dem gesamten Satz aufgerufen wird.

Verwendung:

        [TestMethod] // place only on the list--not the individuals
        public void OrderedStepsTest()
        {
            OrderedTest.Run(TestContext, new List<OrderedTest>
            {
                new OrderedTest ( T10_Reset_Database, false ),
                new OrderedTest ( T20_LoginUser1, false ),
                new OrderedTest ( T30_DoLoginUser1Task1, true ), // continue on failure
                new OrderedTest ( T40_DoLoginUser1Task2, true ), // continue on failure
                // ...
            });                
        }

Implementierung:

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace UnitTests.Utility
{    
    /// <summary>
    /// Define and Run a list of ordered tests. 
    /// 2016/08/25: Posted to SO by crokusek 
    /// </summary>    
    public class OrderedTest
    {
        /// <summary>Test Method to run</summary>
        public Action TestMethod { get; private set; }

        /// <summary>Flag indicating whether testing should continue with the next test if the current one fails</summary>
        public bool ContinueOnFailure { get; private set; }

        /// <summary>Any Exception thrown by the test</summary>
        public Exception ExceptionResult;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="testMethod"></param>
        /// <param name="continueOnFailure">True to continue with the next test if this test fails</param>
        public OrderedTest(Action testMethod, bool continueOnFailure = false)
        {
            TestMethod = testMethod;
            ContinueOnFailure = continueOnFailure;
        }

        /// <summary>
        /// Run the test saving any exception within ExceptionResult
        /// Throw to the caller only if ContinueOnFailure == false
        /// </summary>
        /// <param name="testContextOpt"></param>
        public void Run()
        {
            try
            {
                TestMethod();
            }
            catch (Exception ex)
            {
                ExceptionResult = ex;
                throw;
            }
        }

        /// <summary>
        /// Run a list of OrderedTest's
        /// </summary>
        static public void Run(TestContext testContext, List<OrderedTest> tests)
        {
            Stopwatch overallStopWatch = new Stopwatch();
            overallStopWatch.Start();

            List<Exception> exceptions = new List<Exception>();

            int testsAttempted = 0;
            for (int i = 0; i < tests.Count; i++)
            {
                OrderedTest test = tests[i];

                Stopwatch stopWatch = new Stopwatch();
                stopWatch.Start();

                testContext.WriteLine("Starting ordered test step ({0} of {1}) '{2}' at {3}...\n",
                    i + 1,
                    tests.Count,
                    test.TestMethod.Method,
                    DateTime.Now.ToString("G"));

                try
                {
                    testsAttempted++;
                    test.Run();
                }
                catch
                {
                    if (!test.ContinueOnFailure)
                        break;
                }
                finally
                {
                    Exception testEx = test.ExceptionResult;

                    if (testEx != null)  // capture any "continue on fail" exception
                        exceptions.Add(testEx);

                    testContext.WriteLine("\n{0} ordered test step {1} of {2} '{3}' in {4} at {5}{6}\n",
                        testEx != null ? "Error:  Failed" : "Successfully completed",
                        i + 1,
                        tests.Count,
                        test.TestMethod.Method,
                        stopWatch.ElapsedMilliseconds > 1000
                            ? (stopWatch.ElapsedMilliseconds * .001) + "s"
                            : stopWatch.ElapsedMilliseconds + "ms",
                        DateTime.Now.ToString("G"),
                        testEx != null
                            ? "\nException:  " + testEx.Message +
                                "\nStackTrace:  " + testEx.StackTrace +
                                "\nContinueOnFailure:  " + test.ContinueOnFailure
                            : "");
                }
            }

            testContext.WriteLine("Completed running {0} of {1} ordered tests with a total of {2} error(s) at {3} in {4}",
                testsAttempted,
                tests.Count,
                exceptions.Count,
                DateTime.Now.ToString("G"),
                overallStopWatch.ElapsedMilliseconds > 1000
                    ? (overallStopWatch.ElapsedMilliseconds * .001) + "s"
                    : overallStopWatch.ElapsedMilliseconds + "ms");

            if (exceptions.Any())
            {
                // Test Explorer prints better msgs with this hierarchy rather than using 1 AggregateException().
                throw new Exception(String.Join("; ", exceptions.Select(e => e.Message), new AggregateException(exceptions)));
            }
        }
    }
}
crokusek
quelle
2

Ich werde die Reihenfolge der Tests leider nicht ansprechen. Andere haben es bereits getan. Wenn Sie über "bestellte Tests" Bescheid wissen, ist dies die Antwort von MS VS auf das Problem. Ich weiß, dass diese bestellten Tests keinen Spaß machen. Aber sie dachten, es wird "es" sein und es gibt wirklich nichts mehr in MSTest.

Ich schreibe über eine Ihrer Annahmen:

da es keine Möglichkeit gibt, die statische Klasse abzureißen.

Sofern Ihre statische Klasse keinen prozessweiten externen Status außerhalb Ihres Codes darstellt (z. B. den Status einer nicht verwalteten nativen DLL-Bibliothek, die vom Rest Ihres Codes aufgerufen wird), ist Ihre Annahme there is no waynicht wahr.

Wenn sich Ihre statische Klasse darauf bezieht, dann haben Sie leider vollkommen recht, der Rest dieser Antwort ist irrelevant. Da Sie das nicht gesagt haben, gehe ich davon aus, dass Ihr Code "verwaltet" ist.

Denken Sie nach und überprüfen Sie die AppDomain Ding. Es wird selten benötigt, aber genau dies ist der Fall, wenn Sie sie wahrscheinlich verwenden möchten.

Sie können eine neue AppDomain erstellen, den Test dort instanziieren und dort die Testmethode ausführen. Statische Daten, die vom verwalteten Code verwendet werden, werden dort isoliert. Nach Abschluss können Sie die AppDomain entladen und alle Daten, einschließlich der statischen Daten, werden verdampft. Dann würde der nächste Test eine andere Appdomain initialisieren und so weiter.

Dies funktioniert nur, wenn Sie einen externen Status haben, den Sie verfolgen müssen. AppDomains isolieren nur den verwalteten Speicher. Jede native DLL wird weiterhin pro Prozess geladen und ihr Status wird von allen AppDomains gemeinsam genutzt.

Außerdem verlangsamt das Erstellen / Herunterfahren der Appdomains die Tests. Möglicherweise haben Sie auch Probleme mit der Assemblyauflösung in der untergeordneten Appdomain, diese können jedoch mit einer angemessenen Menge wiederverwendbaren Codes gelöst werden.

Außerdem können kleine Probleme beim Übergeben von Testdaten an die untergeordnete AppDomain und von dieser zurück auftreten. Übergebene Objekte müssen entweder auf irgendeine Weise serialisierbar sein oder sein MarshalByRefoder usw. Das domänenübergreifende Sprechen ist fast wie IPC.

Achten Sie hier jedoch darauf, dass das Sprechen zu 100% verwaltet wird. Wenn Sie besonders vorsichtig sind und dem AppDomain-Setup ein wenig Arbeit hinzufügen, können Sie sogar Delegaten übergeben und in der Zieldomäne ausführen. Anstatt einige haarige domänenübergreifende Einstellungen vorzunehmen, können Sie Ihre Tests mit folgenden Elementen abschließen:

void testmethod()
{
    TestAppDomainHelper.Run( () =>
    {
        // your test code
    });
}

oder auch

[IsolatedAppDomain]
void testmethod()
{
    // your test code
}

wenn Ihr Testframework das Erstellen solcher Wrapper / Erweiterungen unterstützt. Nach anfänglichen Forschungen und Arbeiten ist ihre Verwendung fast trivial.

quetzalcoatl
quelle
Ich werde das untersuchen. Vielleicht aber heute nicht. :)
iGanja
0

Ich sehe, dass dieses Thema fast 6 Jahre alt ist und wir jetzt eine neue Version von Visual Studio haben, aber ich werde trotzdem antworten. Ich hatte dieses Ordnungsproblem in Visual Studio 19 und habe es herausgefunden, indem ich vor Ihrem Methodennamen einen Großbuchstaben (Sie können auch einen Kleinbuchstaben hinzufügen) und in alphabetischer Reihenfolge wie folgt hinzugefügt habe:

[TestMethod]
        public void AName1()
        {}
[TestMethod]
        public void BName2()
        {}

Und so weiter. Ich weiß, dass dies nicht ansprechend aussieht, aber es sieht so aus, als würde Visual Ihre Tests im Test Explorer in alphabetischer Reihenfolge sortieren, unabhängig davon, wie Sie sie in Ihren Code schreiben. Die Wiedergabeliste hat in diesem Fall bei mir nicht funktioniert.

Hoffe das wird helfen.

Taverne Joe
quelle
Es wird schön sein, wenn das funktioniert. Ich werde es versuchen müssen. Vielen Dank!
iGanja
1
Dies scheint in VS 2019 zu funktionieren, aber ich mag es nicht. Wer möchte alle seine Testmethoden so umbenennen? Es ist hässlich und nicht intuitiv. Sie müssen wirklich eine Möglichkeit bieten, die Reihenfolge der Testausführung festzulegen.
Mike Lowery
-2

Sie können einfach nicht in zufälliger Reihenfolge zusammen ausgeführt werden, da es keine Möglichkeit gibt, die statische Klasse abzureißen

Sie können Namespaces und Klassen in alphabetischer Reihenfolge benennen. z.B.:

  • MyApp.Test. Stage01 _Setup. Schritt 01 _BuildDB
  • MyApp.Test. Stage01 _Setup. Schritt 02 _UpgradeDB
  • MyApp.Test. Stage02 _Domain. Step01 _TestMyStaff
  • MyApp.Test. Stage03 _Integration. Step01 _TestMyStaff

Dabei MyApp.Test.Stage01_Setuphandelt es sich um einen Namespace und Step01_BuildDBeinen Klassennamen.

EINGESTEHEN
quelle
Die Ausführungsreihenfolge erfolgt nach Methodendeklarationsreihenfolge und nicht nach alphabetischer Reihenfolge.
Tiago Freitas Leal
1
@TiagoFreitasLeal Nicht wahr in VS 2019! Microsoft ändert ständig, wie dies funktioniert.
Mike Lowery