Nunit: Testmethoden innerhalb einer Vorrichtung parallel ausführen

Erstellt am 5. Aug. 2014  ·  76Kommentare  ·  Quelle: nunit/nunit

Derzeit haben wir die parallele Ausführung nur auf Fixture-Ebene implementiert. Es sollen sowohl einzelne Methoden eines Fixtures parallel als auch einzelne Testfälle für eine parametrisierte Methode laufen können.

Wir sollten in der Lage sein, den genauen Grad der Parallelität der Vorrichtung oder Methode anzugeben.

Dieses Problem war zuvor Teil von #66

done hardfix feature high

Hilfreichster Kommentar

Ich könnte zwar so tun, als würde ich die Zukunft vorhersagen, aber das würde Sie nur bis September zufriedenstellen. :-)

Lassen Sie mich antworten, indem Sie erklären, wie wir Funktionen "planen".

Wir versuchen derzeit (seit Anfang des Jahres) einen Ansatz, bei dem es einmal pro Quartal Releases gibt. Wenn wir beim Release besser werden, können wir das Tempo erhöhen. Irgendwann können wir möglicherweise eine kontinuierliche Bereitstellung durchführen.

In einem ehrenamtlichen Open Source Projekt steht kein fester Aufwand pro Monat zur Verfügung. Wir können den "Wetter von gestern"-Ansatz verwenden, aber es stellt sich heraus, dass die Zeit, die die Menschen für NUnit aufwenden müssen, sowie die Anzahl der Menschen, die sich freiwillig engagieren, sehr unterschiedlich ist.

Als Kompromiss wählen wir eine kleine Anzahl von Themen aus, die für ein Release entscheidend sind und fügen sie dem Meilenstein im Voraus hinzu. Ich bevorzuge es, nicht mehr als etwa 25 % von dem hinzuzufügen, was wir zu erreichen hoffen. Die meisten Probleme in einem Release werden diesem Meilenstein erst hinzugefügt, nachdem sie fertig sind oder bestenfalls, wenn sich jemand dazu verpflichtet, daran zu arbeiten. Im Allgemeinen werden Sie in unserem 3.5-Meilenstein keine offenen Probleme finden, ohne dass ihnen jemand zugewiesen wurde, obwohl ich es gelegentlich tue, wenn es so aussieht, als würde etwas andere Arbeit blockieren.

Die positive Seite dessen, was wir tun, ist also, dass wir praktisch garantieren können, dass die Veröffentlichung pünktlich erscheint. Die negative Seite ist, dass wir Ihnen nicht sagen können, was darin enthalten ist. :-(

Für dieses spezielle Thema... habe ich ihm hohe Priorität eingeräumt, um unseren Entwicklern mitzuteilen, dass es wichtig ist. Jemand muss die Freiheit haben, daran zu arbeiten und genügend Hintergrund für ein Projekt dieser Größenordnung und Schwierigkeit mitbringen. Wenn jemand mit dem richtigen Hintergrund dies in den nächsten Wochen aufgreift, würde ich vermuten, dass dies bis zum Release getan werden kann. Als Richtlinie denke ich, dass ich ungefähr einen Monat brauchen würde, während ich auch an einigen anderen Dingen arbeite, um mich durchzuarbeiten.

Tut mir leid, es gibt keine definitivere Antwort, aber eine solche Antwort wäre unbedingt eine Lüge!

Alle 76 Kommentare

Update: Sowohl dieser Kommentar als auch der folgende waren eine Antwort auf eine Person, die anscheinend ihre eigenen Kommentare entfernt hat. Ich hinterlasse meine Antworten.

Nun, es ist in der Spezifikation und für die Implementierung nach 3.0 geplant. Wenn es so einfach wäre, hätten wir es wahrscheinlich gemacht. Ich bin mir nicht sicher, welche Verbindung Sie mit mbunit sehen. Die Tatsache, dass sie es hatten, hilft uns nicht.

Das wird etwas mühsam. Ein paar Punkte, schon genannt, aber anscheinend übersehen...

  1. Es gibt einen Plan, um das, was Sie verlangen, umzusetzen.
  2. Wir haben uns als Team entschieden, es zu einem bestimmten Zeitpunkt zu planen.
  3. Wann es geplant wird, hat in erster Linie mit unserer Einschätzung des Wertes des Features im Vergleich zu anderen Features zu tun.
  4. Es gibt mehrere Leute im NUnit-Team, die die Funktion implementieren könnten.
  5. Sie könnten es je nach Prioritäten aus dem Kopf heraus umsetzen und müssten es nirgendwo kopieren.

Ich finde Ihre Rede von "Reverse Engineering" sehr beunruhigend. Open Source ist nur in einem Kontext möglich, in dem das Urheberrecht respektiert wird. Wenn Sie also vorschlagen, dass wir die Lizenzbedingungen von mbunit ignorieren könnten, liegen Sie weit daneben.

Während ich viele Patches zu MbUnit beigesteuert und jahrelang verwendet habe, war ich
nie ein wichtiger Mitwirkender. Ich möchte nicht, dass mein Status falsch dargestellt wird :)

Was Reverse Engineering angeht, so nützt es hier nicht wirklich etwas. NUnit funktioniert
ganz anders als MbUnit. Wir werden uns zu gegebener Zeit mit diesem Thema befassen,
gehen aber vorsichtig vor, da sich andere ähnliche Probleme ändern könnten
die Art und Weise, wie wir dies umsetzen müssen, oder sogar Konflikte.
Am 19. April 2015 um 02:45 Uhr schrieb "CharliePoole" [email protected] :

Das wird etwas mühsam. Ein paar Punkte, schon genannt aber
anscheinend verpasst...

1.

Es gibt einen Plan, um das, was Sie verlangen, umzusetzen.
2.

Wir haben uns als Team entschieden, es zu einem bestimmten Zeitpunkt zu planen.
3.

Wann es geplant ist, hat in erster Linie mit unserer Einschätzung der
Wert des Merkmals im Vergleich zu anderen Merkmalen.
4.

Es gibt mehrere Leute im NUnit-Team, die das implementieren könnten
Besonderheit.
5.

Sie könnten es je nach Prioritäten aus
ihre Köpfe und müssten es nirgendwo kopieren.

Ich finde Ihre Rede von "Reverse Engineering" sehr beunruhigend. Open Source ist
nur in einem Kontext möglich, in dem das Urheberrecht respektiert wird. Also wenn du es bist
was darauf hindeutet, dass wir die Lizenzbedingungen von mbunit ignorieren könnten, sind Sie weit weg
Base.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/nunit/nunit/issues/164#issuecomment -94244650.

Ein viel taktvollerer Kommentar als meiner!

Unsere aktuellen Prioritäten in der Welt der parallelen Ausführung sind:

  1. Parallele Prozessausführung
  2. Ausschlussgruppen
  3. Ausführung der parallelen Methode (in einem Gerät).

Dies scheint die Reihenfolge mit dem größten Nutzen für die Benutzer darzustellen.

Ich erwähne auch, dass das Markieren von etwas als Post-3.0 nicht unbedingt bedeutet, dass das Feature zu einem späteren Zeitpunkt kommt, als wenn wir es zu einem Teil von 3.0 machen würden. Es kann vielmehr bedeuten, dass 3.0 zu einem früheren Zeitpunkt kommt.

Wenn wir dies tun, müssen wir entscheiden, wie wir mit Setup- und Teardown-Befehlen umgehen. Die einfachste Option wäre wahrscheinlich, die Testklasse für jeden Test so zu konstruieren, dass keine Datenkonkurrenz besteht.

Ich würde es ohnehin bevorzugen, dies irgendwann zu einer Option zu machen, aber ich bin mir nicht sicher, ob es eine Run-Option oder eine Fixture-by-Fixture-Option (attributiert) oder beides ist.

Hi!
Das Hinzufügen dieser Funktion zur nächsten Version von NUnit wäre großartig, da es das einzige ist, was mich daran hindert, zu NUnit zu wechseln. Ist diese Funktion noch für 3.4 geplant?

@julianhaslinger NUnit 3.4 wird Ende des Monats erscheinen, also nein, diese Funktion wird nicht enthalten sein.

Zu Ihrer Information, dieses Problem ist in unserem Backlog-Meilenstein (oder Pseudo-Meilenstein) und nicht in 3.4 enthalten, da wir der Praxis folgen, jedem nummerierten Meilenstein im Voraus nur eine kleine Anzahl von wichtigen definierenden Problemen hinzuzufügen.

Der nächste Meilenstein, 3.6, soll in 3 weiteren Monaten erscheinen, was für Sie wahrscheinlich entmutigend klingt. :-( Wenn Sie jedoch feststellen, dass dieses Problem mit dem Master zusammengeführt wird, können Sie einen früheren Drop aus unserem MyGet-Feed erhalten.

@julianhaslinger das wird nicht in 3.4 sein, was wahrscheinlich in etwas mehr als einer Woche herauskommt, aber es ist eines, das ich gerne bald fertig sehen würde, also hilft deine Stimme: +1:

Abgesehen davon, welches Testframework verwenden Sie, das die parallele Methodenausführung unterstützt? Ich dachte, XUnit erlaubt nur das parallele Ausführen von Tests bis auf die Klassenebene . Liege ich falsch? Ich benutze XUnit nicht viel :smile:

@CharliePoole Danke für die Antwort! Ok, das klingt allerdings etwas entmutigend. Ich werde jedoch auf die nächsten Releases (oder frühere Drops) warten. Bitte berücksichtigen Sie dieses Feature (noch) in der nächsten Version (3.6).

@rprouse Ich verwende gerade MbUnit/Gallio. Das Projekt ist so gut wie gestorben und jetzt werde ich zu NUnit wechseln.

@julianhaslinger Ist es für dich eine Frage der Laufzeit? Haben Sie Zahlen zur Verteilung von Testfällen innerhalb von Fixtures? Ich frage, weil ich davon ausgegangen bin, dass die Funktion den Benutzern wenig bietet, außer dem, was sie von parallelen Geräten erhalten. Wenn das falsch ist, könnte es seine relative Priorität ändern.

@CharliePoole Genau, unser eigentliches Problem ist die Laufzeit der Testfälle. Wir möchten NUnit für unsere automatisierten / Regressionstests (einschließlich Selenium / WebDriver) verwenden und da einige unserer Testklassen über 200 Testfälle haben, ist es derzeit eine echte Qual, die gesamte Testsuite mit NUnit auszuführen.

Vergleiche (innerhalb eines kleineren Testsets unserer Regressionstests) haben gezeigt, dass eine mögliche NUnit-Lösung in etwa 1,5 Stunden ausgeführt wird, während die aktuelle MBunit-Lösung in 0,5 Stunden (gleiches Testset) ausgeführt wird.

@CharliePoole , ich bin mir jedoch der Tatsache bewusst, dass wir die Ausführungszeit möglicherweise reduzieren können, indem wir größere Testklassenhierarchie irgendwie untergraben.

@julianhaslinger - Nur zur Bestätigung, sind Sie sicher, dass die Laufzeit an die CPU und nicht an den Speicher gebunden ist?

Wir hatten das gleiche Problem, als wir zum ersten Mal versuchten, auf NUnit 3 umzustellen - die Laufzeit wurde erheblich länger. Dies lag jedoch daran, dass NUnit den verfügbaren Speicher ausgereizt hat - es gibt ein Problem mit der aktuellen Version, das alle Testobjekte behält, bis der Testlauf abgeschlossen ist. Wir führen derzeit intern eine gepatchte Version aus - ich wollte eine PR für 3.4 einholen, bin mir aber nicht sicher, ob ich zu diesem Zeitpunkt Zeit habe. :-(

Entschuldigung, wenn dies nicht der Fall ist, aber ich dachte, es wäre eine Erwähnung wert, da Selenium seinen angemessenen Anteil an Speicher nutzen kann. :-)

@ChrisMaddock Danke für den Input! :+1: Wir werden uns das demnächst anschauen und ich komme dann auf dich zurück.

@ChrisMaddock Ich würde gerne sehen, dass Ihr Speicher in 3.4 repariert wird. Wenn Sie eine PR erstellen möchten, können wir Ihnen helfen, sie zu bereinigen, wenn sie noch nicht produktionsreif ist :+1:

@rprouse - Dieser erste Commit https://github.com/nunit/nunit/pull/1367/commits/5f98ae51025f7af8244abd4367d1f47260874dfc in PR #1367 macht die Dinge für uns in einer gepatchten v3.0.1 richtig frei.

Sie werden in der PR sehen, dass es vor dem Zusammenführen nach OneTimeTearDown verschoben wurde - ich weiß noch nicht, ob es dadurch in v3.2.1 nicht funktionierte oder ob eine andere Änderung funktionierte, die das Retention - Ich habe nach dem Umzug möglicherweise keinen erneuten Test gemacht.

Werde es morgen versuchen und erneut testen und hochwerfen, wäre toll für uns, auch zu den Kernversionen zurückzukehren. :-)

@ChrisMaddock Ich habe mir den Speicherverbrauch während eines Regressionstestlaufs angesehen und festgestellt, dass die Ausführung von Testläufen nicht speichergebunden ist. Ich denke, wir müssen wirklich auf eine Version von NUnit warten, die die parallele Ausführung einzelner Methoden innerhalb jeder Klasse handhaben kann.

nur um das hinzuzufügen, was @julianhaslinger gesagt hat, ich habe genau das gleiche Problem bei der Verwendung von NUnit mit Selenium-Tests gesehen. Ich musste einen benutzerdefinierten Wrapper schreiben, der einzelne Instanzen von nunit-console.exe für einen einzelnen Test ausführt, der aus einer bestandenen Assembly abgekratzt wurde, damit ich vorerst parallele Tests ausführen konnte. Dies ist jedoch nicht ideal, da es dazu führt, dass viele .xml-Ausgabedateien generiert werden (eine für jeden Testlauf) und nicht eine einzelne .xml-Ausgabe, und es bedeutet auch, dass ich _OneTimeSetUp_- und Teardown-Methoden nicht verwenden kann und stattdessen auf externe Semaphoren angewiesen bin und Umgebungsvariablen, um den Ausführungsfluss zu steuern, wo ich Dinge nur einmal ausführen möchte. Ich verfolge das Versprechen, parallele Ausführung in NUnit zu haben, seit langem (Jahren) und war sehr enttäuscht darüber, wie das Feature in 3.0 eingeführt wurde (nur teilweise unterstützt und erfordert einige echte Recherchen in den Issues und Versionshinweisen) entdecken, dass nicht alles tatsächlich unterstützt wurde). Ich bin sogar so weit gegangen, selbst zu untersuchen, was dazu gehört, dies voranzutreiben, aber leider scheint es, dass das Design von NUnit gegen die Implementierung der parallelen Ausführung auf der Ebene der Testmethoden arbeitet. Ich habe keine Ahnung, wie Sie es eigentlich möchten um das Potenzial für nicht-threadsicheren Code zu handhaben (dh sollte es der Person überlassen werden, die NUnit parallel verwendet, um sicherzustellen, dass alle Testmethoden ordnungsgemäß auf externe Elemente auf threadsichere Weise verweisen, oder sollte NUnit selbst die Ausführung jeder Methode in seiner eigenen Domäne verarbeiten, während irgendwie Ich versuche immer noch, die einmaligen Setup- und Teardown-Methoden nur einmal auszuführen) und da ich bereits eine Problemumgehung habe, konnte ich die Zeit für die Implementierung dieser Funktion selbst nicht rechtfertigen (was wahrscheinlich das Beste ist, da ich schon einmal verbrannt wurde, wenn) Zusammenarbeit mit Teams auf GitHub, um sie bei der Implementierung der parallelen Ausführung zu unterstützen). Wie auch immer ... sorry fürs Geschwafel ... Ich verstehe, dass die Priorität für Unit-Tests von C#-Code wahrscheinlich nicht so sehr von der Parallelität auf Methodenebene abhängt, aber bitte wissen Sie, dass für diejenigen von uns, die NUnit für Selenium-basierte Tests verwenden es wäre eine RIESIGE Verbesserung. Danke im Voraus! :Lächeln:

Danke für deine Kommentare. Ich denke, ich werde hier selbst ein bisschen herumschweifen...

Es hilft zu verstehen, was Menschen brauchen und warum sie es brauchen. Da ich selbst kein Webentwickler bin, habe ich versucht, den Selenium-Benutzern zuzuhören und mich auf das zu konzentrieren, was sie wollten. Was das zu sein schien, waren parallele Fixtures mit Ordnung zwischen den Testfällen. Ich verstehe voll und ganz, dass unterschiedliche Leute unterschiedliche Dinge wollen, aber wenn beide Gruppen sich so präsentieren, dass sie ausdrücken, "was Selenium-Benutzer brauchen", ist das ein bisschen verwirrend. Können Sie mir skizzieren, welche Arten von Webtests Parallelität auf Methodenebene wünschen, im Gegensatz zu denen, die Methoden in einer vordefinierten Reihenfolge ausführen möchten? Ich denke, ich könnte es erraten, aber ich hätte es lieber von einem Benutzer.

Bezüglich Ihrer Problemumgehung... haben Sie in Erwägung gezogen, separate Testbaugruppen zu verwenden? NUnit würde gerne jeden einzelnen parallel in einem separaten Prozess betreiben. Das beseitigt natürlich nicht die Notwendigkeit, den Zugriff auf Dinge wie Dateien zu synchronisieren.

Was die Thread-Sicherheit angeht - wir haben nie geplant, dass unsere parallele Implementierung die Verantwortung für die Thread-Sicherheit übernimmt. Das einzige , was ich zu erwarten Garantie ist , dass NUnit werden keine Thread-Sicherheit Probleme schaffen , wenn Ihre Methoden bereits Thread-sicher sind. Das an sich stellt sich als nicht trivial heraus.

Danke für die Antwort. Ich verstehe deine Kommentare zu voll und ganz
Anordnung der Testausführung in einer Vorrichtung und Aufteilung der Tests in separate
Versammlungen.

Ich bin bereits NUnit-Benutzer und schon seit Jahren (und JUnit davor)
Die Idee, sich auf die Reihenfolge der Tests in einer Vorrichtung zu verlassen, war also nicht einmal ein
Berücksichtigung in meinem Testdesign. Jeder Test versucht, vollständig gekapselt zu sein
Aktion oder eine Reihe von Aktionen innerhalb der Site ohne Erwartung in der Reihenfolge von
Hinrichtung. Das Design der Website, die ich teste, bedeutet auch, dass viele Tests
kann bis zu 20 Minuten dauern (die meiste Zeit wird mit Warten verbracht .)
damit etwas auf der Website passiert) und die Art der Prüfung ist deckend
mehrere ähnliche Szenarien, sodass Basistestklassen verwendet werden, um Code zu reduzieren
Duplizierung und Erhöhung der Wartbarkeit durch Verwendung einer gemeinsamen Basisklasse
Methoden. Die Tests sind basierend auf der Entwicklung in separate Projekte organisiert
Teambesitz für diesen Bereich (also verwenden wir separate Assemblys, aber es gibt
sind viele Tests pro Assembly und mein Test-Wrapper übernimmt die Ausführung von
alle Tests in allen parallel in Baugruppen bestanden, wie es zuvor erstellt wurde
die erste offizielle Veröffentlichung von NUnit 3 und ich wollte sicherstellen, dass alle Tests durchgeführt wurden
das Potenzial, gleichzeitig ausgeführt zu werden, wenn genügend Threads vorhanden sind
erhältlich).

Im Wesentlichen können Sie sich vorstellen, dass eine Baugruppe 10 Tests hat und
weitere 100 Tests, aber die Baugruppe mit 10 hat Tests, die 10 Minuten dauern
jeder, während die Baugruppe mit 100 Tests hat, die jeweils 1 Minute dauern. Wenn ich
eine Maschine haben, die 110 parallele Threads ausführen kann (was eigentlich ist
Teil unseres Infrastrukturdesigns), dann würde ich erwarten, dass die Tests abgeschlossen sind
in 10 Minuten, nicht in 100 Minuten.

Hoffentlich hilft das bei der Erklärung ... Entschuldigung, wenn die Dinge immer noch nicht ganz klar sind,
Aber der Gesamtpunkt ist, dass ich auf Methodenebene Parallelismus habe
in anderen Testbibliotheken fehlt (prspec zum Beispiel in Ruby) und wann
Analyse der zu erzielenden Leistungsverbesserungen durch Hinzufügen i
festgestellt, dass es eine große positive Veränderung sein kann. Sehen Sie sich Folgendes als Beispiel an:
https://github.com/bicarbon8/rspec-parallel/wiki/Beispiele
Am 1. Juli 2016 um 00:45 Uhr schrieb "CharliePoole" [email protected] :

Danke für deine Kommentare. Ich denke, ich werde hier selbst ein bisschen herumschweifen...

Es hilft zu verstehen, was Menschen brauchen und warum sie es brauchen. Nicht sein
Webentwickler selbst, ich habe versucht, den Selenium-Benutzern zuzuhören und mich auf das zu konzentrieren, was
Sie wollten. Was das zu sein schien, waren parallele Befestigungen mit Bestellung
unter den Testfällen. Ich verstehe voll und ganz, dass verschiedene Leute wollen
verschiedene Dinge, aber wenn sich beide Gruppen als Ausdrucksformen präsentieren
"was Selenium-Benutzer brauchen" ist etwas verwirrend. Kannst du für mich skizzieren?
welche Arten von Webtests könnten Parallelität auf Methodenebene im Gegensatz zu?
die Leute, die Methoden in einer vordefinierten Reihenfolge ausführen möchten? ich denke ich könnte
schätze, aber ich hätte es lieber von einem Benutzer.

Bezüglich Ihrer Problemumgehung ... haben Sie in Betracht gezogen, einen separaten Test zu verwenden?
Baugruppen? NUnit würde gerne jeden parallel in einem separaten laufen lassen
Prozess. Das macht es natürlich nicht nötig, den Zugriff auf zu synchronisieren
Dinge wie Dateien.

In Bezug auf Thread-Sicherheit - wir haben nie eine parallele Implementierung geplant
Verantwortung für die Fadensicherheit zu übernehmen. Das einzige was ich erwartet habe
Garantie ist, dass NUnit keine Thread-Sicherheitsprobleme _erzeugt_, wenn Ihr
Methoden sind bereits Thread-sicher. Das an sich stellt sich als nicht trivial heraus.


Sie erhalten dies, weil Sie einen Kommentar abgegeben haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/nunit/nunit/issues/164#issuecomment -229819324 oder stumm
der Faden
https://github.com/notifications/unsubscribe/ACNsyoczCUV9L7kbF2SHB7lLsyBKlrv9ks5qRFUJgaJpZM4CUZ8r
.

Danke für die Info... es ist hilfreich, verschiedene Perspektiven zu sehen.

Meine 5 Cent.

In unserem Projekt haben wir ~25 Testaufbauten und die parallele Testdurchführung von Tests pro Baugruppe und pro Spannvorrichtung bereits stark verkürzt. Die parallele Ausführung von Tests innerhalb des Fixtures wird es noch weiter verbessern. Jetzt haben wir sogar die meisten zeitaufwendigen Fixtures in mehrere Fixtures aufgeteilt, um die Ausführung zu beschleunigen, aber es wird viel besser sein, wenn nunit Fixture-Tests parallel durchführt.

Was ich in nunit wirklich sehen möchte, ist eine Testparallelisierung auf Testfallebene, da das Aufteilen solcher Tests in Fixtures nicht immer bequem ist und zu Codeduplizierungen führt. Wir haben mehrere Tests, die bis zu mehreren Tausend Testfälle erfordern können (jede Ausführung ist schnell, aber insgesamt dauert es Minuten) oder nur Dutzende von Fällen (aber jeder Fall ist langsam) und im Moment sind solche Tests die wichtigsten Showstopper für uns.

Danke für den Input... das ist ein Bereich, den wir in der nächsten Version zusammen mit dem konkurrierenden, aber sich ergänzenden Problem ansprechen werden, um sicherzustellen, dass einige Tests nicht parallel laufen!

Meine frühere Frage bezog sich mehr darauf, wie Leute Tests schreiben, insbesondere wenn sie eine Webanwendung steuern. Einige Leute bestehen darauf, dass jede Methode ein sequenzierter Schritt ist und das Gerät eine Reihe solcher Schritte darstellt. Dies ist natürlich per Definition nicht parallel. Andere Leute scheinen sehr ähnliche Tests zu schreiben, ohne die Tests zu sequenzieren. Ich vermute, dass die letztere Gruppe größere Testmethoden schreibt, mit einer Reihe von Aktionen und Behauptungen in jeder einzelnen.

@CharliePoole Tolle Neuigkeiten! Ich danke dir sehr!

Meiner Meinung nach sollten Testfälle isoliert sein und nicht von anderen Testfällen oder der Ausführungsreihenfolge abhängen. Wenn die Leute dennoch einige Tests in Einzelthread ausführen möchten, können sie immer noch [Parallelizable(ParallelScope.None)] und/oder OrderAttribute verwenden.

Dieses implementierte Problem wird es ermöglichen, Testsuiten im Vergleich zu einem lokalen Webtreiber-Grid oder einem Saas-Anbieter wie BrowserStack oder SauceLabs schneller auszuführen. Derzeit versuche ich, die Anzahl der Testmethoden für eine Testklasse auf die Anzahl der verfügbaren Webtreiberknoten oder Browsersitzungen zu beschränken, damit das Raster vollständig genutzt wird. Andernfalls, wenn ein Test 8 Testmethoden hat und mein Grid 8 verfügbare Browsersitzungen hat, wird nur eine verwendet, da alle Testmethoden der Klasse nacheinander ausgeführt werden.

@pablomxnl Stimme voll und ganz zu. Als Coach oder Projektleiter habe ich diese Idee immer sehr stark vorangetrieben. Allerdings trage ich hier keinen dieser Hüte. Ich bin ein Softwareanbieter mit Benutzern, die nach Dingen fragen. Wenn sie nach wirklich ungeheuerlichem Zeug fragen, sage ich einfach nein. Aber wenn sie nach Dingen fragen, die in einem Kontext vernünftig sind, in anderen aber nicht – auch nicht in den meisten –, dann ziehe ich das in Betracht.

Bei Websites sprechen wir fast immer nicht von Unit-Tests. Funktionstests auf höherer Ebene erfordern oft eine Sequenzierung. Ob dies über eine Reihe von Testschritten oder eine Reihe von Methoden erfolgt, ist für uns ein Implementierungsdetail und für den Anwender eine Frage der Bequemlichkeit. Persönlich denke ich, dass wir wahrscheinlich etwas namens [Step] brauchen, das sich in einer [StepFixture]-Klasse befindet, oder ähnliche Namen, damit wir all diese Reihenfolgen/Sequenzen vom Unit-Testen wegbewegen können. Vielleicht habe ich Zeit, das zu tun, bevor das Web stirbt. :-)

Wie auch immer, es ist immer interessant zu erfahren, wie die Leute Ihre Software tatsächlich nutzen.

@CharliePoole , bitte verstehen Sie mich nicht falsch, indem Sie dies fragen (ich möchte nur sicher sein): Wird diese Funktion der nächsten Version (3.5, fällig bis 29. September 2016) hinzugefügt?

Ich könnte zwar so tun, als würde ich die Zukunft vorhersagen, aber das würde Sie nur bis September zufriedenstellen. :-)

Lassen Sie mich antworten, indem Sie erklären, wie wir Funktionen "planen".

Wir versuchen derzeit (seit Anfang des Jahres) einen Ansatz, bei dem es einmal pro Quartal Releases gibt. Wenn wir beim Release besser werden, können wir das Tempo erhöhen. Irgendwann können wir möglicherweise eine kontinuierliche Bereitstellung durchführen.

In einem ehrenamtlichen Open Source Projekt steht kein fester Aufwand pro Monat zur Verfügung. Wir können den "Wetter von gestern"-Ansatz verwenden, aber es stellt sich heraus, dass die Zeit, die die Menschen für NUnit aufwenden müssen, sowie die Anzahl der Menschen, die sich freiwillig engagieren, sehr unterschiedlich ist.

Als Kompromiss wählen wir eine kleine Anzahl von Themen aus, die für ein Release entscheidend sind und fügen sie dem Meilenstein im Voraus hinzu. Ich bevorzuge es, nicht mehr als etwa 25 % von dem hinzuzufügen, was wir zu erreichen hoffen. Die meisten Probleme in einem Release werden diesem Meilenstein erst hinzugefügt, nachdem sie fertig sind oder bestenfalls, wenn sich jemand dazu verpflichtet, daran zu arbeiten. Im Allgemeinen werden Sie in unserem 3.5-Meilenstein keine offenen Probleme finden, ohne dass ihnen jemand zugewiesen wurde, obwohl ich es gelegentlich tue, wenn es so aussieht, als würde etwas andere Arbeit blockieren.

Die positive Seite dessen, was wir tun, ist also, dass wir praktisch garantieren können, dass die Veröffentlichung pünktlich erscheint. Die negative Seite ist, dass wir Ihnen nicht sagen können, was darin enthalten ist. :-(

Für dieses spezielle Thema... habe ich ihm hohe Priorität eingeräumt, um unseren Entwicklern mitzuteilen, dass es wichtig ist. Jemand muss die Freiheit haben, daran zu arbeiten und genügend Hintergrund für ein Projekt dieser Größenordnung und Schwierigkeit mitbringen. Wenn jemand mit dem richtigen Hintergrund dies in den nächsten Wochen aufgreift, würde ich vermuten, dass dies bis zum Release getan werden kann. Als Richtlinie denke ich, dass ich ungefähr einen Monat brauchen würde, während ich auch an einigen anderen Dingen arbeite, um mich durchzuarbeiten.

Tut mir leid, es gibt keine definitivere Antwort, aber eine solche Antwort wäre unbedingt eine Lüge!

@CharliePoole gibt es ein Update für diese Funktion?

@tomersss wir haben noch nicht mit der Arbeit daran begonnen und 3.5 wird hoffentlich in ein paar Wochen erscheinen, daher wird es unwahrscheinlich in der nächsten Version sein. Wir möchten, dass diese Funktion bald hinzugefügt wird, aber wir waren diese Woche ziemlich damit beschäftigt, unsere Repositorys und unsere Codebasis neu zu organisieren. Es hat jedoch hohe Priorität und ist daher auf unserem Radar.

@CharliePoole gibt es ein Update zu diesem Problem?

@KPKA Wir haben noch nicht mit der Arbeit begonnen, daher gibt es kein Update. Für Benutzer mit installiertem ZenHub wird dieses Problem von Backlog zu ToDo und dann In Progress verschoben, wenn wir damit beginnen.

Für Nicht-Benutzer von Zenhub können Sie erkennen, wann jemand es abholt, indem Sie beobachten, wer dem Problem zugewiesen ist.

@CharliePoole @rprouse

Hi!

Gibt es Neuigkeiten zu dieser Ausgabe?
Ob es im nächsten Release sein wird oder ob es in einem der kommenden Meilensteine ​​geplant ist?

Im Moment ist dies das einzige Problem, das uns daran hindert, auf NUnit umzusteigen.
Wäre nett, wenn sich jemand bekennen könnte, in naher Zukunft daran zu arbeiten, da ich denke, dass viele Menschen betroffen sind.

Hoffe bald von dir zu hören

@GitSIPA welches

Um Ihre Frage zu beantworten, hat niemand mit der Arbeit an diesem Thema begonnen, daher gibt es keine ETA, aber wir werden Ihre Stimme berücksichtigen, wenn wir entscheiden, woran wir als nächstes arbeiten.

+1, stimme @GitSIPA zu. Dies ist eine wirklich wichtige Funktion

@GitSIPA +1
@rprouse Wir verwenden mbunit, aber dieses Framework wird derzeit nicht unterstützt. Und wir haben einige Probleme mit mbunit.

@rprouse Wir verwenden derzeit auch MbUnit, da die Unterstützung für die neuen Visual Studio-Versionen jedoch nicht gegeben ist, haben wir überlegt, auf NUnit umzusteigen.

In Ausgabe #1921 fragte @jnm2 : "Was steht zwischen uns und der parallelen Ausführung parametrisierter Testfälle? Kann ich dazu beitragen?"

Zweite Frage zuerst: Auf jeden Fall! Wir würden uns über Ihre Hilfe freuen.

Und zur ersten Frage:

  1. Wir führen "WorkItems" aus, die derzeit Tests eins zu eins abbilden. Ich denke, wir müssen OneTimeSetUp und OneTimeTearDown für ein Fixture als separate WorkItems als vorbereitenden Schritt behandeln. Die Ausgabe #1096 befasst sich damit.

  2. Wir müssen eine Möglichkeit haben, ein WorkItem von anderen WorkItems abhängig zu machen, sodass es nur für die Ausführung geplant wird, wenn alle diese abhängigen Elemente abgeschlossen sind. Wir machen das derzeit sehr vereinfacht mit einem CountDown, aber wir brauchen etwas Allgemeineres. Die erste Verwendung davon wäre natürlich, OneTimeTearDown vom Abschluss aller Tests abhängig zu machen. Es würde später andere Verwendungen haben, wenn wir Abhängigkeiten zwischen Tests implementieren. Ich stelle mir dies als eine Warteschlange ausstehender Arbeitselemente vor, aber es gibt möglicherweise andere Möglichkeiten, dies zu implementieren.

  3. Nachdem diese beiden Dinge aus dem Weg geräumt waren, konnten wir mit der Arbeit am Hauptproblem selbst beginnen: Tests so zu planen, dass sie ausgeführt werden, anstatt sie im selben Thread auszuführen, der das OneTimeSetUp für das Gerät ausgeführt hat.

Wenn Sie daran arbeiten möchten, müssen Sie sich mit einigen Interna vertraut machen, wie NUnit tatsächlich Tests zur Ausführung absetzt. Ich helfe Ihnen gerne dabei.

Welche Planungen wurden bisher gemacht?
Meine Anforderungen sind, genügend TestCaseSource-Fälle parallel auszuführen, um die CPU zu sättigen. Ich habe keine Einrichtungs-, Abbau- oder Bestellanforderungen. Andere Menschen müssen diese jedoch berücksichtigen.

Ich würde erwarten, dass die Ausführung von TestCaseSource parallelisiert wird, sodass zwei Methoden in derselben Vorrichtung, die unterschiedliche TestCaseSources verwenden, die Enumerationen parallel ausführen. Es wäre auch schön, wenn zwei Methoden dieselbe TestCaseSource verwenden würden, wenn sie nur einmal ausgeführt würde - Gedanken dazu?

Edit: RENNBEDINGUNG kommentieren. Wir sind schon gut gestartet! 😆

Ich wiederhole eine Geschichte, die ich in letzter Zeit viel erzählen musste. :Lächeln:

NUnit lädt zuerst Tests (auch bekannt als Discovers, Explores) und führt sie dann je nach Läufertyp ein- oder mehrmals aus.

Ihre TestCaseSource wird beim Laden von Tests verwendet, nicht bei deren Ausführung, und wir betrachten sie nicht einmal als Teil Ihres Tests - obwohl Sie sie möglicherweise in derselben Klasse wie Ihr Test haben.

IOW, Ihre Testfälle "verwenden" nicht Ihre Testfallquelle, sondern NUnit verwendet die Quelle, um die Testfälle zu erstellen. Natürlich können sie nichts tun, bis sie erstellt wurden. Sinn ergeben?

Die Erstellung von Tests aus der Quelle erfolgt sequentiell. Wenn im Quellcode Code ausgeführt wird, der dies zu einem Problem macht, würde ich zunächst vermuten, dass Sie zu viel in der Testfallquelle tun. Sie möchten beispielsweise keine Instanzen von Klassen in Ihrer Testfallquelle erstellen, sondern Parameter speichern, die zum Erstellen verwendet werden. Leider könnte dies ein ganzes Buchkapitel sein. :Lächeln:

Bei diesem Thema geht es also darum, __Testfälle parallel auszuführen__. Das bedeutet alle Testfälle unter einem Fixture, es sei denn, Sie haben einige als nicht parallelisierbar markiert. Dabei würden sowohl einfache, nicht parametrisierte Tests als auch Einzelfälle eines parametrisierten Tests gleich behandelt.

Es wäre ein interessantes Experiment, die Parallelisierung von Tests in Fixtures zu ermöglichen, bei denen es kein OneTimeTearDown gibt (ich denke, OneTimeSetUp ist in Ordnung). Es könnte leicht funktionieren, wenn Sie diese Entscheidung richtig treffen könnten. Die Ermittlung ist jedoch schwieriger als Sie denken, da OneTimeTearDown sowohl geerbte Methoden als auch globale ActionAttributes enthalten kann.

@jnm2 Hatten Sie bereits die Gelegenheit, dieses spezielle Problem anzugehen?

@julianhaslinger Nein. Es steht auf meiner Liste nach meinen beiden unmittelbareren Ausgaben, 1885 und 1933. Wenn Sie es angehen wollen, umso besser!

@julianhaslinger Da wir uns nicht kennen, entschuldigen Sie bitte, dass dies eine schwierige https://github.com/nunit/nunit/issues/164#issuecomment -265267804 finden Sie eine Aufschlüsselung in separate PRs, die ich gerne sehen würde, um dies zu beheben. Wenn Sie einen einfacheren Ansatz haben, posten Sie ihn, bevor Sie ihn programmieren, damit wir zukünftige Überlegungen gegen das offensichtliche YAGNI abwägen können, das bei der Vorhersage der Zukunft beteiligt ist.

@CharliePoole @jnm2 Hallo Leute!

Es ist nicht so, dass ich mit der Implementierung dieses fehlenden Features beginnen wollte, sondern lediglich über seinen Fortschritt Bescheid wissen wollte. Wie ich Ihren Antworten (oben) entnehmen kann, gab es keine Fortschritte (?) in Bezug auf diese spezielle Funktionsanfrage.

@CharliePoole Eines der potenziellen Probleme, auf die ich bei der Recherche des Codes derzeit gehandhabt werden. Derzeit haben alle WorkItems Zugriff auf dieselbe Fixture-Instanz , was bedeutet, dass, wenn die WorkItems parallel ausgeführt würden, sie auf eine einzelne Instanz der Testklasse zugreifen würden. Dies ist aufgrund der Race-Bedingungen problematisch, die entstehen, wenn Tests auf Setup oder Teardown angewiesen sind, um Felder auf Instanzebene festzulegen.

Eine Lösung hierfür wäre, jedes WorkItem auf einer neuen Instanz der Testklasse ausführen zu lassen, aber dies wird wahrscheinlich das Verhalten von Fixture-Setups verkomplizieren, da es keine einzelne Instanz des Fixtures mehr geben würde

@chris-smith-zocdoc Ja, das ist der größte Unterschied zwischen NUnit und seinem Vorgänger junit. Früher wurde darüber viel pro und contra diskutiert, aber jetzt kommt nicht viel auf. Aus diesem Grund sollten NUnit-Tests zustandslos sein, wobei die gesamte Initialisierung in der SetUp-Methode durchgeführt wurde.

Nachdem TestFixtureSetUp (jetzt OneTimeSetUp genannt) eingeführt wurde, war es möglich, einmal eine teurere Initialisierung durchzuführen und die Tests alle mit denselben initialisierten Werten arbeiten zu lassen. Dies ist am nützlichsten, wenn Sie Instanzen der getesteten Klassen erstellen, die selbst zustandsbehaftet sein können. In den letzten Jahren haben immer mehr Benutzer von dieser Möglichkeit Gebrauch gemacht.

Das Thema des Hinzufügens einer Option zum Erstellen einer separaten Instanz des Benutzer-Fixtures pro Testfall kommt regelmäßig auf. Bisher hat es es noch nicht bis zum geplanten Feature geschafft. Es hängt definitiv mit der Benutzerfreundlichkeit eines parallelen Methodenfeatures seitens der Benutzer zusammen, aber ich denke, es ist orthogonal zur Implementierung. Wenn wir pro Instanz ein neues Gerät erstellen würden, würden wir einfach "ein" Setup mehr als einmal ausführen. Das würde natürlich alle Benutzer hart treffen, die sich der Statik bedienen. 😢

Wir haben parallele Testmethoden aus zwei Gründen verschoben: (1) es ist schwer zu implementieren und (2) es schien, dass parallele Fixtures für uns zwar einfacher sind, aber für die meisten Benutzer ausreichend sind. Sehr wenige Benutzer scheinen den Status über mehrere Geräte hinweg zu teilen, während es (basierend auf Online-Diskussionen) scheint, dass viele Benutzer den Status über die Testmethoden hinweg teilen. Bisher nutzen viele Benutzer die Parallelität, die es gibt, und obwohl einige die Methodenparallelität sehr wünschen, scheinen sie eine relativ kleine Gruppe zu sein.

Trotzdem denke ich, es ist an der Zeit, etwas zu tun. Ich werde dies für das erste Quartal übernehmen, zumindest in dem Maße, in dem ich einige Experimente durchführe und möglicherweise eine sinnvolle Aufteilung von Aufgaben erstelle, die andere weiterverfolgen können.

Wenn wir pro Instanz ein neues Gerät erstellen würden, würden wir einfach "ein" Setup mehr als einmal ausführen. Das würde natürlich alle Benutzer hart treffen, die sich der Statik bedienen.

Ich denke, es ist vernünftig zu verlangen, dass es keinen statischen Zustand gibt, wenn Sie sich für eine parallele Ausführung entscheiden, in dem Maße, dass es Ihre Schuld ist, wenn etwas durch die Mischung von statischem Zustand und Parallelität kaputt geht. Zum Glück wird dein gesamter Code getestet, also sollte er kaum zu übersehen sein 😆

Trotzdem denke ich, es ist an der Zeit, etwas zu tun. Ich werde dies für das erste Quartal übernehmen, zumindest in dem Maße, in dem ich einige Experimente durchführe und möglicherweise eine sinnvolle Aufteilung von Aufgaben erstelle, die andere weiterverfolgen können.

Zählen Sie mich dazu.

Ich auch!

Am Sa, 14. Januar 2017 um 3:58 Uhr, Joseph Musser [email protected]
schrieb:

>
>
>
>

[Bild: Boxbe] https://www.boxbe.com/overview

Automatische Bereinigung: Behalte die letzten 1 E-Mails ([email protected])

Regel bearbeiten
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3Dwa43L7bW5j4V5ymh5QXh%252FNXk%252F0KVSSFJSqwHw2yu4No%253D%26token%3DjkWoQ96YyOE%252FHA7PvZA8g%252FOAgpOQMZdIE7ophiWCxqx1y6zZCFJ%252FKSZ2WZELsWD3YQoDEdjwb%252BWo6wGi4xiUEkGngbggedv8iYBxU7zk% 252FJamyOuVtPzie4dhQJXQkQQ%252BtolspNKBzqBxtH6H%252FhqnTQ%253D%253D&tc_serial=28420100882&tc_rand=128339648&utm_source=stf&utm_medium=email&utm_001

| Regel löschen
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3Dwa43L7bW5j4V5ymh5QXh%252FNXk%252F0KVSSFJSqwHw2yu4No%253D%26token%3DjkWoQ96YyOE%252FHA7PvZA8g%252FOAgpOQMZdIE7ophiWCxqx1y6zZCFJ%252FKSZ2WZELsWD3YQoDEdjwb%252BWo6wGi4xiUEkGngbggedv8iYBxU7zk% 252FJamyOuVtPzie4dhQJXQkQQ%252BtolspNKBzqBxtH6H%252FhqnTQ%253D%253D&tc_serial=28420100882&tc_rand=128339648&utm_source=stf&utm_medium=email&utm_001

| Als wichtig markieren
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3Dwa43L7bW5j4V5ymh5QXh%252FNXk%252F0KVSSFJSqwHw2yu4No%253D%26token%3DjkWoQ96YyOE%252FHA7PvZA8g%252FOAgpOQMZdIE7ophiWCxqx1y6zZCFJ%252FKSZ2WZELsWD3YQoDEdjwb%252BWo6wGi4xiUEkGngbggedv8iYBxU7zk% 252FJamyOuVtPzie4dhQJXQkQQ%252BtolspNKBzqBxtH6H%252FhqnTQ%253D%253D%26important%3Dtrue%26emlId%3D54854949581&tc_serial=28420100882&tc_content =

Wenn wir pro Instanz ein neues Gerät erstellen würden, würden wir einfach "eins" ausführen.
Zeiteinstellung mehr als einmal. Das würde natürlich alle Benutzer hart treffen, die es sind
Statik nutzen.

Ich denke, es ist vernünftig zu verlangen, dass es keinen statischen Zustand gibt, wenn Sie
entscheide dich für einen parallelen Lauf, sofern es deine Schuld ist, wenn etwas
Pausen zum Mischen von statischem Zustand und Parallelität. Zum Glück wird all dieser Code
wird getestet, also sollte es kaum zu übersehen sein :D

Trotzdem denke ich, es ist an der Zeit, etwas zu tun. Ich werde das übernehmen
für das erste Quartal, zumindest soweit einige Experimente durchgeführt werden
und möglicherweise eine sinnvolle Aufteilung der Aufgaben, die andere ausführen können
weiter verfolgen.

Zählen Sie mich dazu.


Sie erhalten dies, weil Sie einen Kommentar abgegeben haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/nunit/nunit/issues/164#issuecomment-272488655 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAHNVlwVps8pQ93UIwZw6zY7TOyHO0a6ks5rR61EgaJpZM4CUZ8r
.

Bei einigen Timing-Tests habe ich etwas Interessantes entdeckt. Es gibt eine Mehrdeutigkeit beim Aufrufen von Testfällen parallelisierbar. Dies kann auch für Geräte und andere Suiten gelten, ist aber weniger offensichtlich.

Hier ist die Sache: Wenn eine Methode vollständig nicht parallelisierbar ist, bedeutet das, dass sie nicht parallel zu __jeder anderen Methode__ laufen kann. OTOH, wenn es nur innerhalb seines Fixtures nicht parallelisierbar ist, kann es nicht parallel zu __jeder anderen Methode im selben Fixture laufen.__

Ich schlage vor, dass wir diese Unterscheidung wie folgt handhaben:

  1. Wenn eine Testmethode kein parallelisierbares Attribut hat, sollte sie auf demselben Thread wie ihr enthaltendes Fixture ausgeführt werden, vorausgesetzt, kein anderes Attribut (zB Apartment) verlangt, dass sie auf einem anderen Thread ausgeführt wird

  2. Wenn es ein Parallelizable-Attribut mit dem Geltungsbereich Self hat oder wenn eine Suite auf höherer Ebene den Geltungsbereich Children angibt, wird die Testmethode parallel zu den anderen Methoden in der Vorrichtung ausgeführt.

Gedanken @nunit/core-team ?

Oben weggelassen:

  1. Wenn es ein Parallelizable-Attribut mit dem Gültigkeitsbereich None hat, wird es in der nicht parallelen Warteschlange ausgeführt.

@CharliePoole - Ihre drei Punkte sind sinnvoll, obwohl mir nicht klar ist, was die Alternative wäre, die Sie vorschlagen, dass wir dies nicht tun. Könnten Sie klären?

Derzeit behandeln wir kein Attribut wie bei ParallelScope.None. Dadurch werden sie in die nicht parallele Warteschlange eingereiht, wenn ich das Verteilen aktiviere und der Testlauf erheblich verlangsamt.

PR #2011 unternimmt einige erste Schritte zur Implementierung dieser Funktion, enthält jedoch ein #define, das erzwingt, dass Testfälle auf dem Thread ihres enthaltenden Fixtures ausgeführt werden. Dieser Kommentar dokumentiert, was meiner Meinung nach getan werden muss, um diese Einschränkung aufzuheben.

Derzeit wird OneTimeTearDown eines Fixtures auf dem Thread ausgeführt, der verwendet wurde, um den zuletzt ausgeführten Testfall zu beenden. Wenn Testfälle parallel laufen, können wir nicht vorhersagen, welcher Testfall das sein wird. Möglicherweise handelt es sich um ein Gewinde mit anderen Eigenschaften als die für die Vorrichtung erforderlichen. Wenn beispielsweise der letzte zu beendende Test in der STA ausgeführt wird, wird dies zum Ausführen von OneTimeTearDown verwendet, selbst wenn OneTimeSetUp in einem MTA ausgeführt wurde. In vielen Fällen kann dies kein Problem darstellen, in einigen jedoch schon.

Dies könnte auch bei höherstufigen Fixtures ein Problem sein, aber die Einführung paralleler Testfälle bedeutet, dass es viel mehr Möglichkeiten für eine Fehlanpassung gibt, die einen Fehler verursacht.

Um sicherzustellen, dass der Fixture-Teardown auf der richtigen Art von Thread stattfindet, können wir ihn nicht mehr auf dem Thread des letzten auszuführenden Tests ausführen. Stattdessen muss der Dispatcher Informationen über alle anstehenden Teardowns verwalten und benachrichtigt werden, um diese Teardowns im richtigen Thread zur richtigen Zeit auszuführen. Herauszufinden, wie das geht, ist die "Design"-Phase dieser Funktion.

Für alle, die diesen Thread von Anfang an verfolgt haben (damals im Jahr 2014) und keine eigene Problemumgehung implementieren möchten oder können, während sie auf diese Feature-Erweiterung warten, bin ich gerade über eine Implementierung mit NUnit 2.6.3 gestolpert, die auf verfügbar ist CodePlex, der ziemlich einfach zu verwenden scheint (ich habe überprüft, dass es bei der Ausführung unserer Funktionstests in mehreren parallelen Threads funktioniert).

http://cpntr.codeplex.com/

entschuldigt sich im Voraus @CharliePoole, wenn diese Nachricht etwas orthogonal zu den jüngsten Diskussionen in diesem Thread ist, aber wenn jemand in den letzten 3 Jahren auf diese Feature-Erweiterung gewartet hat, basierend auf den Versprechungen für NUnit 3 (sehr früh) Tage), denke ich, dass es eine Lösung bieten könnte, bis Sie es schaffen, die Designprobleme zu lösen (klingt, als würden Sie der Lösung näher kommen).

@CharliePoole

Um sicherzustellen, dass der Fixture-Teardown auf der richtigen Art von Thread stattfindet, können wir ihn nicht mehr auf dem Thread des letzten auszuführenden Tests ausführen. Stattdessen muss der Dispatcher Informationen über alle anstehenden Teardowns verwalten und benachrichtigt werden, um diese Teardowns im richtigen Thread zur richtigen Zeit auszuführen. Herauszufinden, wie das geht, ist die "Design"-Phase dieser Funktion.

Müssen wir den Disponenten vorab über die ausstehenden Teardown-Elemente informieren oder können wir sie versenden, sobald sie verfügbar sind? Konkreter gesagt , wo CompositeWorkItem derzeit

@chris-smith-zocdoc Ja, genau das mache ich. Ich habe einen neuen Arbeitsaufgabentyp erstellt, OneTimeTearDownWorkItem , der in CompositeWorkItem verschachtelt ist und beim Ausführen des letzten untergeordneten Tests gesendet wird. Später können wir uns einige Effizienzsteigerungen ansehen, wenn OneTimeSetUp und alle Tests im selben Thread ausgeführt wurden.

Ich habe nicht alles sorgfältig gelesen, aber eine Sache, die ich als Teil dieser Funktion fordern möchte, ist, dass die Parallelität "intelligent" ist, insbesondere für E/A-gebundene Tests. Wenn Sie beispielsweise über 10 Threads verfügen, die 100 parallelisierbare Tests ausführen, sollten die 10 Threads nicht warten und warten, bis die ersten 10 Tests abgeschlossen sind, bevor Sie mit den nächsten 10 Tests fortfahren. Wenn die ersten 10 Tests beginnen, auf sehr lange laufende E/A-Aufgaben zu warten, sollten die Threads frei sein, um mit anderen Tests fortzufahren. Wenn die E/A-Aufgaben abgeschlossen sind, setzen Threads die wartenden Tests fort, während Threads frei werden.

Grundsätzlich fordere ich ein intelligentes Durchsatzmanagement für E/A-gebundene Tests, die async/await ausgiebig nutzen. Dies ist bei weitem unser größter Engpass bei Tests.

@chris-smith-zocdoc Tatsächlich mache ich das so ziemlich. Ich verwende im Wesentlichen den vorhandenen Countdown-Mechanismus, um den Versand einer einmaligen Teardown-Aufgabe auszulösen. Der Trick besteht darin, es in die richtige Warteschlange zu stellen.

@gzak Denken Sie daran, dass der Mechanismus für die parallele Ausführung bereits vorhanden ist. Es hängt davon ab, dass die Mitarbeiter Aufgaben unabhängig erledigen, anstatt einen Controller zu haben, der Aufgaben an die Mitarbeiter weiterleitet. Wenn also ein Arbeiter eine Weile mit einer Aufgabe beschäftigt ist, werden andere Arbeiter andere Aufgaben selbstständig weiter ausführen. Der Trick besteht darin, die Anzahl der Worker basierend auf der Art der ausgeführten Tests festzulegen. NUnit funktioniert standardmäßig ziemlich gut mit normalen, rechengebundenen Unit-Tests, aber andere Arten von Tests erfordern möglicherweise, dass der Benutzer ein angemessenes Maß an Parallelität festlegt.

Kann mir jemand erklären wie das geht?
Ich habe eine Testklasse
Wenn ich die Tests in dieser Klasse NICHT parallel durchführe - alle Tests bestanden
Aber wenn ich sie mit [Parallelizable(ParallelScope.Children)] ausführe
Sie laufen also parallel (mehrere Methoden in derselben Klasse)
aber aus irgendeinem Grund schlagen einige Tests fehl.
Ich habe Instanzfelder in dieser Klasse, die in den Tests verwendet werden, und es scheint, dass diese Felder von Threads gemeinsam genutzt werden
Habe ich recht?
Erstellen Sie nur eine Instanz dieser Klasse und rufen Sie die Methoden gleichzeitig für dieses einzelne Objekt auf?
CharliePoole

Du hast es herausgefunden! Ja, alle Tests in einem Fixture verwenden dieselbe Instanz. Das ist bei NUnit historisch, das hat immer so funktioniert. Sie müssen wählen, ob Sie die Testfälle parallel ausführen oder einen beliebigen Status haben, der pro Test geändert wird. Daran führt derzeit kein Weg vorbei.

Das heißt, wenn Sie einen anständigen Anteil an Geräten haben, können Sie einfach die Geräte parallel laufen lassen, um eine gute Leistung zu erzielen.

Es ist möglich, die [Parallelizable(ParallelScope.Children)] im
AssemblyInfo.cs-Datei?

Hat jemand gesehen, dass das funktioniert?

Am 14. Juni 2017 um 01:37 Uhr schrieb CharliePoole [email protected] :

[Bild: Boxbe] https://www.boxbe.com/overview Automatische Bereinigung: beibehalten
letzte 1 E-Mails ([email protected]) Regel bearbeiten
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3DCCP9ir0TebdbdQOWVtGMQyr2TETYOrzfkbItPzUTgDk%253D%26token%3D0PvYtf1G2B%252FJ2FNN3b7MTSmP1zvs6x3Cu8z6LaAB8%252BJm73uy8ZNUCnQcknlgWKxRQ5zjE%252BY30Xkv1W1Gue9gGnpyi72YUTaHP2h6wvuEpTXe1WoQDoSHpUGDQefgQu6LDH0rRhsEvF%252FW%252BhysbMtsDw%253D% 253D&tc_serial=30872123699&tc_rand=2087335475&utm_source=stf&utm_medium=email&utm_campaign=ANNO_CLEANUP_EDIT&utm_content=001
| Regel löschen
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3DCCP9ir0TebdbdQOWVtGMQyr2TETYOrzfkbItPzUTgDk%253D%26token%3D0PvYtf1G2B%252FJ2FNN3b7MTSmP1zvs6x3Cu8z6LaAB8%252BJm73uy8ZNUCnQcknlgWKxRQ5zjE%252BY30Xkv1W1Gue9gGnpyi72YUTaHP2h6wvuEpTXe1WoQDoSHpUGDQefgQu6LDH0rRhsEvF%252FW%252BhysbMtsDw%253D% 253D&tc_serial=30872123699&tc_rand=2087335475&utm_source=stf&utm_medium=email&utm_campaign=ANNO_CLEANUP_EDIT&utm_content=001
| Als wichtig markieren
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3DCCP9ir0TebdbdQOWVtGMQyr2TETYOrzfkbItPzUTgDk%253D%26token%3D0PvYtf1G2B%252FJ2FNN3b7MTSmP1zvs6x3Cu8z6LaAB8%252BJm73uy8ZNUCnQcknlgWKxRQ5zjE%252BY30Xkv1W1Gue9gGnpyi72YUTaHP2h6wvuEpTXe1WoQDoSHpUGDQefgQu6LDH0rRhsEvF%252FW%252BhysbMtsDw%253D% 253D%26important%3Dtrue%26emlId%3D61187554820&tc_serial=30872123699&tc_rand=2087335475&utm_source=stf&utm_medium=email&utm_campaign=ANNO_CLEANUP_EDIT&utm_content=001

Du hast es herausgefunden! Ja, alle Tests in einem Fixture verwenden dieselbe Instanz.
Das ist bei NUnit historisch, das hat immer so funktioniert. Du musst
Wählen Sie zwischen der parallelen Ausführung der Testfälle und einem beliebigen Status, der
wird pro Test geändert. Daran führt derzeit kein Weg vorbei.

Das heißt, wenn Sie einen anständigen Anteil an Geräten haben, laufen Sie einfach
parallele Geräte können Ihnen eine gute Leistung bringen.


Sie erhalten dies, weil Sie einen Kommentar abgegeben haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/nunit/nunit/issues/164#issuecomment-308157832 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAHNVuK-J-X74mlAA_eT7OX7dxs7MpoRks5sDqzLgaJpZM4CUZ8r
.

@agray Ja, das ist tatsächlich der einzige Grund, warum ich jetzt eine AssemblyInfo.cs habe.

Hallo Josef,

Welche Parallelitätslinie fügen Sie Ihrer AssemblyInfo.cs-Datei hinzu?

Ich würde gerne wissen, was funktioniert.

Danke schön,

Andreas

Am Mittwoch, 14. Juni 2017 um 16:17 Uhr, Joseph Musser [email protected]
schrieb:

[Bild: Boxbe] https://www.boxbe.com/overview Automatische Bereinigung: beibehalten
letzte 1 E-Mails ([email protected]) Regel bearbeiten
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3DnRGYOf%252FKR68McP8RTipuFTLF9WUvAkSKSh6OYJYvJ2w%253D%26token%3DDcwWzMT9yPtQLckdXD3BLhW5xAB%252BMpc9XdsrbBlwdQJZC%252Bjo3SjsyMVC8vese%252BCNRw2IyucWqEcHR5Is7CK7nx01VuSQESvjG4ZUj%252B2Cfcwg51yUFFQJSwrmTVxqAk4%252BTVGDSrnutdAuqiJ3kTaYQA% 253D%253D&tc_serial=30882364582&tc_rand=1974513896&utm_source=stf&utm_medium=email&utm_campaign=ANNO_CLEANUP_EDIT&utm_content=001
| Regel löschen
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3DnRGYOf%252FKR68McP8RTipuFTLF9WUvAkSKSh6OYJYvJ2w%253D%26token%3DDcwWzMT9yPtQLckdXD3BLhW5xAB%252BMpc9XdsrbBlwdQJZC%252Bjo3SjsyMVC8vese%252BCNRw2IyucWqEcHR5Is7CK7nx01VuSQESvjG4ZUj%252B2Cfcwg51yUFFQJSwrmTVxqAk4%252BTVGDSrnutdAuqiJ3kTaYQA% 253D%253D&tc_serial=30882364582&tc_rand=1974513896&utm_source=stf&utm_medium=email&utm_campaign=ANNO_CLEANUP_EDIT&utm_content=001
| Als wichtig markieren
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3DnRGYOf%252FKR68McP8RTipuFTLF9WUvAkSKSh6OYJYvJ2w%253D%26token%3DDcwWzMT9yPtQLckdXD3BLhW5xAB%252BMpc9XdsrbBlwdQJZC%252Bjo3SjsyMVC8vese%252BCNRw2IyucWqEcHR5Is7CK7nx01VuSQESvjG4ZUj%252B2Cfcwg51yUFFQJSwrmTVxqAk4%252BTVGDSrnutdAuqiJ3kTaYQA% 253D%253D%26important%3Dtrue%26emlId%3D61214070592&tc_serial=30882364582&tc_rand=1974513896&utm_source=stf&utm_medium=email&utm_campaign=ANNO_CLEANUP_EDIT&utm_content=001

@array https://github.com/array Ja, das ist tatsächlich der einzige Grund, warum ich
habe jetzt eine AssemblyInfo.cs.


Sie erhalten dies, weil Sie einen Kommentar abgegeben haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/nunit/nunit/issues/164#issuecomment-308325726 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAHNVghNAX8CJkqAy-qhAz8bXNhZcFOQks5sD3NigaJpZM4CUZ8r
.

@agray Der, nach dem du gefragt hast:

c# [Parallelizable(ParallelScope.Children)]

Ziel nicht vergessen

[assembly: Parallelizable(ParallelScope.Children)]

@LirazShay Ich verwende NUnit, um Selenium-Tests zu

 public class TestFactory : IDisposable
    {
    // Instantiate a new SafeHandle instance.
    private readonly System.Runtime.InteropServices.SafeHandle handle = new Microsoft.Win32.SafeHandles.SafeFileHandle(IntPtr.Zero, true);

    // Flag: Has Disposed been called?
    private bool disposed = false;

    public TestFactory()
    {
        this.UserRepository = new List<UserAccount>();
        this.DU = new DataUtility();
    }

    // A list of users created for this test
    public List<UserAccount> UserRepository { get; private set; }

    // A very simple data layer utility that uses Dapper to interact with the database in my application 
    public DataUtility DU { get; private set; }

    // Gets a new user and adds it to the repository
    public UserAccount GetNewUser()
    {
        var ua = new UserAccount();
        this.UserRepository.Add(ua);
        return ua;
    }


    public void Dispose()
    {
        this.Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (this.disposed)
        {
            return;
        }

        if (disposing)
        {
            // Deletes all user accounts created during the test
            foreach (UserAccount ua in this.UserRepository)
            {
                try
                {
                    ua.Delete();
                }
                catch (Exception)
                {
                    // Take no action if delete fails.
                }
            }

            this.DU.DeleteNullLoginFailures(); // Cleans up the database after tests
            Thread.Sleep(1500);
        }

        this.disposed = true;
    }
}

Dann kann ich in einem Test Folgendes tun:

[TestFixture]
public class UserConfigureTests
{
    [Test]
    public void MyExampleTest()
    {
        using (TestFactory tf = new TestFactory())
        {
            var testUser = tf.GetNewUser();

    tf.DU.DoSomethingInTheDatabase(myParameter);

    // Test actions go here, and when we exit this using block the TestFactory cleans
    // up after itself using the Dispose method which calls whatever cleanup logic you've written into it
        }
    }
}

Auf diese Weise kann ich viel Code-Duplizierung vermeiden, und wenn ich die Abhängigkeiten meines Tests jemals ändern muss, mache ich dies nur einmal in der Fabrik. Wenn jemand Feedback zu meiner Strategie hat, würde ich mich freuen!

@tparikka Ich kann genau diesen Ansatz selbst sehr empfehlen.

Ich habe folgendes in meiner AssemblyInfo-Datei:

[Baugruppe: Parallelisierbar(ParallelScope.Children)]
[Baugruppe: LevelOfParallelism(16)]

Brauche ich auch das Attribut LevelOfParallelism mehr?

Am 15. Juni 2017 um 04:37 schrieb Joseph Musser [email protected] :

[Bild: Boxbe] https://www.boxbe.com/overview Automatische Bereinigung: beibehalten
letzte 1 E-Mails ([email protected]) Regel bearbeiten
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3Doth%252FFbAPG%252FhDbtUlS0i2PDDdQ0lP4dBi8o7QQmkLEMQ%253D%26token%3DHe7HfTrm%252Fiba3yIDazaBx8JO9NrmoL8p5TWtDB1hUxq0qp%252BhCRCB3OSl7sUQ6wDshc2I5LQhbR2jszLWr6FnRy%252FZUrCqghZIIilbDWKszT7pkI44xp9vaL6cszH9Sgg1YPCAHdVWqccZYxYXGW174A%253D% 253D&tc_serial=30894750852&tc_rand=1847060911&utm_source=stf&utm_medium=email&utm_campaign=ANNO_CLEANUP_EDIT&utm_content=001
| Regel löschen
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3Doth%252FFbAPG%252FhDbtUlS0i2PDDdQ0lP4dBi8o7QQmkLEMQ%253D%26token%3DHe7HfTrm%252Fiba3yIDazaBx8JO9NrmoL8p5TWtDB1hUxq0qp%252BhCRCB3OSl7sUQ6wDshc2I5LQhbR2jszLWr6FnRy%252FZUrCqghZIIilbDWKszT7pkI44xp9vaL6cszH9Sgg1YPCAHdVWqccZYxYXGW174A%253D% 253D&tc_serial=30894750852&tc_rand=1847060911&utm_source=stf&utm_medium=email&utm_campaign=ANNO_CLEANUP_EDIT&utm_content=001
| Als wichtig markieren
https://www.boxbe.com/popup?url=https%3A%2F%2Fwww.boxbe.com%2Fcleanup%3Fkey%3Doth%252FFbAPG%252FhDbtUlS0i2PDDdQ0lP4dBi8o7QQmkLEMQ%253D%26token%3DHe7HfTrm%252Fiba3yIDazaBx8JO9NrmoL8p5TWtDB1hUxq0qp%252BhCRCB3OSl7sUQ6wDshc2I5LQhbR2jszLWr6FnRy%252FZUrCqghZIIilbDWKszT7pkI44xp9vaL6cszH9Sgg1YPCAHdVWqccZYxYXGW174A%253D% 253D%26important%3Dtrue%26emlId%3D61245244440&tc_serial=30894750852&tc_rand=1847060911&utm_source=stf&utm_medium=email&utm_campaign=ANNO_CLEANUP_EDIT&utm_content=001

@tparikka https://github.com/tparikka Genau das kann ich nur empfehlen
an mich herangehen.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/nunit/nunit/issues/164#issuecomment-308521058 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAHNVmEzVDbw32Xx0jkYcGK9bZW3tLvXks5sECh8gaJpZM4CUZ8r
.

Ich habe mich noch nicht mit LevelOfParallelism . Es ist standardmäßig die Anzahl der Kerne, die Sie haben.

Wenn Ihre Tests nicht CPU-gebunden sind, ist höher sinnvoll. Aber wie immer bei Perf ist die Antwort so abhängig von Ihrem Szenario, dass es besser ist, zu messen als zu raten.

@CharliePoole Ich verwende TestcaseSource , aber es sieht so aus, als würden die resultierenden Testfälle nicht parallel ausgeführt. Wird erwartet, dass so etwas funktioniert:

```c#
[TestFixture]
Klasse Deserialisierung
{
öffentliche statische IEnumerableShouldDeserializeAllCases() => Enumerable.Repeat(0, 5).Select(x => TimeSpan.FromSeconds(2));

    [TestCaseSource("ShouldDeserializeAllCases"), Parallelizable(ParallelScope.Children)]
    public void ShouldDeserializeAll(TimeSpan t)
    {
        Thread.Sleep(t);
        Assert.AreEqual(1, 1);
    }
}

```

Die Gesamtzeit beträgt 10 Sekunden statt ~2.

Ich denke, es gibt keine Kinder, also könntest du in diesem Fall besser gebrauchen
[Parallelisierbar(ParallelScope.All)]
oder verschieben Sie Ihr Attribut auf Klassenebene.

@ParanoikCZE Danke. Ich bin tatsächlich blind in Bezug auf die Bedeutung dieses Attributs, also habe ich alle Aufzählungswerte dort ausprobiert. Unabhängig davon, welches von All , Children , Fixture oder Self ich verwende, erhalte ich eine Ausführungszeit von 10 Sekunden (zumindest in Visual Studio).

Ich habe gerade versucht, es in die Klasse zu verschieben, aber das scheint auch nicht zu helfen.

Versuchen Sie dies ist eine Inspirationsquelle :)

class Deserialization
{
    public static IEnumerable<TestCaseData> ShouldDeserializeAllCases
    {
        get
        {
            for (int i = 1; i <= 5; i++)
                yield return new TestCaseData(TimeSpan.FromSeconds(i)).SetName($"Thread_worker_{i}");
        }
    }

    [TestCaseSource(nameof(ShouldDeserializeAllCases)), Parallelizable(ParallelScope.Children)]
    public void ShouldDeserializeAll(TimeSpan t) => System.Threading.Thread.Sleep(t);
}

@ParanoikCZE Nochmals vielen Dank. Ich habe dies in Visual Studio getestet und die Visualisierung ist viel klarer, aber die Tests laufen immer noch sequentiell. Dies ist einfacher zu erkennen, wenn Sie für jeden Testfall einen konstanten Ruhezustand verwenden, anstatt die Schritte zu erhöhen.

Versuchen Sie, [assembly: LevelOfParallelism(5)] in AssemblyInfo hinzuzufügen, ich denke, es gibt einen Standardwert, aber vielleicht funktioniert es für Sie irgendwie nicht. Jedenfalls habe ich keine Ideen mehr. :)

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen