Nunit: Fehler bei Unit-Tests in nunit.framework.tests nach neuem Klon

Erstellt am 25. Juni 2018  ·  31Kommentare  ·  Quelle: nunit/nunit

Ich habe mir gerade einen neuen Klon von Nunit geholt und die Lösung in Visual Studio 2017 (Community 15.7.4) mit dem neuesten NUnit 3-Testadapter (3.10 mit parallelen Tests) geöffnet, der unter Windows 10 Professional ausgeführt wird, und die "Debug-AnyCPU" ausgewählt “ und klicken Sie auf Build.

Nachdem ich BUILDING.md gelesen habe, scheint es, als ob ich alle Fehler ignorieren sollte, die nicht von nunit.framework.tests-* und nunitlite.tests-* stammen.

Ich bekomme jedoch von vornherein 2 Fehler von nunit.framework.tests-*

Erster Fehler:

Test Name:  TestCaseSourceCanAccessWorkDirectory("C:\\Users\\ace.olszowka\\source\\nunit\\bin\\Debug\\net20")
Test FullName:  NUnit.Framework.TestContextTests.TestCaseSourceCanAccessWorkDirectory("C:\\Users\\ace.olszowka\\source\\nunit\\bin\\Debug\\net20")
Test Source:    C:\Users\ace.olszowka\source\nunit\src\NUnitFramework\tests\TestContextTests.cs : line 110
Test Outcome:   Failed
Test Duration:  0:00:00.001

Result StackTrace:  at NUnit.Framework.TestContextTests.TestCaseSourceCanAccessWorkDirectory(String workDirectory) in C:\Users\ace.olszowka\source\nunit\src\NUnitFramework\tests\TestContextTests.cs:line 112
Result Message: 
Expected string length 34 but was 50. Strings differ at index 34.
  Expected: "C:\\Users\\ace.olszowka\\source\\nunit"
  But was:  "C:\\Users\\ace.olszowka\\source\\nunit\\bin\\Debug\\net20"
  -------------------------------------------------^

Wenn ich mir die Quelle anschaue, sehe ich nicht, wie dies möglich war, soweit ich das beurteilen kann, hätten diese Werte identisch sein sollen ( _workDirectory und die Testdaten sind beide auf TestContext.CurrentContext.WorkDirectory ) mein einziger vermute ist eine Art Race Condition, vielleicht aufgrund einer schlechten Konfiguration auf meiner Seite?

Zweiter Fehler:

Test Name:  StackTracesAreFiltered("WarningInBeginInvoke",4)
Test FullName:  NUnit.Framework.Assertions.WarningTests.StackTracesAreFiltered("WarningInBeginInvoke",4)
Test Source:    C:\Users\ace.olszowka\source\nunit\src\NUnitFramework\tests\Assertions\WarningTests.cs : line 292
Test Outcome:   Failed
Test Duration:  0:00:00.004

Result StackTrace:  at NUnit.Framework.Assertions.WarningTests.StackTracesAreFiltered(String methodName, Int32 maxLineCount) in C:\Users\ace.olszowka\source\nunit\src\NUnitFramework\tests\Assertions\WarningTests.cs:line 310
Result Message: 
Multiple failures or warnings in test:
  1) (Warning message)
  2) Expected the number of lines to be no more than 4, but it was 5:

 1. at NUnit.TestData.WarningFixture.<>c__DisplayClass45_0.<WarningInBeginInvoke>b__0()
 2. at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs)
 3. at System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg, IMessageSink replySink)
 4. at System.Runtime.Remoting.Proxies.AgileAsyncWorkerItem.ThreadPoolCallBack(Object o)
 5. at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
(end)

Ich verliere mich in dem, was dieser Test hier versucht; Aber nach meinem begrenzten Verständnis scheint dieser Code wirklich empfindlich auf Änderungen in der Aufrufliste zu reagieren. Könnte dies an einer kürzlichen Änderung im .NET Framework liegen?

Ich erhalte auch, dass jeder einzelne Testfall in NUnitLite.Tests.CommandLineTests fehlschlägt. Ich würde dort gerne weitergraben, wenn dies unerwartet ist.

Da der Build in CI übergeben wird, sind dies wahrscheinlich nur Konfigurationsprobleme auf meiner Seite, aber in BUILDING.md wurde nichts darüber erwähnt, also dachte ich, ein Bericht lohnt sich.

bug normal

Alle 31 Kommentare

Danke für den Bericht! Ich habe bestätigt, dass TestCaseSourceCanAccessWorkDirectory und CommandLineTests im Test Explorer nicht funktionieren. Wir müssen einen Weg finden, sie unabhängig von Läufer und Parallelität zu machen. @nunit/framework-team Irgendwelche Ideen?

Für den zweiten Fehler ist das ein Geruchstest. Es ist sinnvoll, das auf 5 zu erhöhen.

In der Vergangenheit habe ich den Leuten nur gesagt, dass sie den Test-Explorer nicht für die NUnit-Tests verwenden sollen. Andere Teammitglieder haben sich dagegen ausgesprochen, dass der Test-Explorer für viele Menschen zur Standardmethode zum Ausführen von Tests geworden ist.

Es gibt sicherlich zahlreiche Präzedenzfälle dafür, dass ein bestimmter Runner beim Testen eines Testframeworks nicht nützlich ist. Das Testen von zu testenden Frameworks ist eine ziemlich spezielle Situation und wird von den meisten Benutzern nicht angetroffen. OTOH, wenn das Team es wünscht, machen Sie es sich vielleicht zum Ziel, den Test-Explorer erfolgreich durch den Adapter laufen zu lassen.

Was auch immer Sie tun, ich denke, Sie sollten wahrscheinlich eine Dokumentation veröffentlichen, die den Leuten sagt, dass das Ausführen von NUnit-Tests unter dem Test-Explorer derzeit nicht funktioniert. Sie können ihnen in diesem Zusammenhang sagen, dass es entweder ein Ziel ist, dass es funktioniert, oder dass es keine Priorität hat, je nachdem, was entschieden wird.

Als Erstautor des Adapters und langjähriger Mitarbeiter des Frameworks habe ich den Einsatz des Test-Explorers bei der Entwicklung von NUnit immer kritisiert. Das ist immer noch meine Meinung zu dem Thema. Verdammt, ich mag es nicht einmal, dass wir jetzt die Konsole verwenden, um das Framework in unserer CI zu testen!!!

Wie auch immer die Entscheidung ausfällt, ich denke, Sie müssen immer wieder Leute zu den eigentlichen NUnit-Runnern (entweder NUnitLite oder dem Konsolen-Runner) zurückschicken, wenn Probleme auftreten, die möglicherweise am Adapter liegen oder nicht. Der Adapter bleibt grundsätzlich einem Drittanbieter-Runner gleichwertig, auch wenn er unter dem NUnit-Projekt steht.

FWIW von außen: Es ist mir eigentlich egal, in welche Richtung es schneidet, solange es als solches dokumentiert ist.

Out of the box werde ich als Entwickler versuchen, das zu tun, was ich normalerweise tun würde, wenn ich auf ein neues Projekt stoße, das dieselben Praktiken verwendet, die ich intern verwende:

  1. Klonen Sie den Code
  2. Lesen Sie die README.md/BUILD.md/HACKING.md
  3. Build versuchen (ohne Änderungen)
  4. Führen Sie die Unit-Tests aus (über den integrierten Runner).
  5. Wenn alles funktioniert, fang an, mit Sachen zu spielen.

In der Vergangenheit wäre dies das dotCover von ReSharper gewesen, aber wir haben versucht, uns davon zu entwöhnen, da die Lizenzkosten für kleine Shops/Einzelentwickler einfach verrückt sind, wenn es freie/Open Source Software-Alternativen gibt, die "meistens funktionieren".

Das Konzept der integrierten Entwicklungsumgebung hat (meiner Meinung nach) viel zu bieten, es ist sehr nützlich, nicht aus dem Workflow herausspringen zu müssen, weshalb wir es tun.

Wenn jedoch von uns erwartet wird, dass wir den Console Runner (oder einen anderen Runner) verwenden, ist das meiner Meinung nach in Ordnung, dokumentieren Sie es einfach.

Wenn Sie auf NUnit entwickeln und am Framework arbeiten, denke ich, dass das Mischen von Runnern, die Dinge auf besondere Weise tun (R#, unser eigener Adapter), das Problem verwirren kann. Ich möchte wissen, dass das Framework isoliert richtig funktioniert, bevor ich es mit Läufern teste. In meiner eigenen Arbeit verwende ich nunitlite also zum Testen, während ich die CI entwickle und dann lokal führe. Wenn eine Person im Test Explorer auf NUnit entwickeln möchte, würde ich sagen, dass sie CI immer noch lokal ausführen und auch auf Nunitlite oder Nunit3-Konsole zurückgreifen sollte, wenn etwas fragwürdig aussieht.

Für Leute, die nur die Nunit-Tests einer bestimmten Version ausführen, gibt es meiner Meinung nach viel mehr Spielraum.

Wir sollten CI kanonisch machen, wahrscheinlich mit NUnitLite für alle Framework-Tests und dann die Konsole, den VSTest-Adapter und einen UWP-Runner für End-to-End-Tests.

Angenommen, CI ist solide, erscheint es mir in Ordnung, wenn es feine Unterschiede zwischen Test Explorer, ReSharper, NCrunch und unserem CI-Skript gibt. Zu sagen, dass diese In-IDE-Tools ignoriert werden sollten, sehe ich als Hindernis für den Beitrag und als falsch, da dies nicht einmal mein Arbeitsablauf ist. Mein idealer Arbeitsablauf:

  1. Lokalisieren Sie vorhandene Tests oder schreiben Sie neue Tests
  2. Fixieren Sie diese Testhalterung, um die Tests während des Tippens schnell wiederholen zu können (noch besser, starten Sie kontinuierliche Tests).
  3. Implementieren Sie eine Änderung
  4. Führen Sie vor dem Erstellen eines Git-Commits .\build.ps1 -t test , um sicherzustellen, dass die Durchläufe und Fehler wie erwartet sind
  5. Wenn es Überraschungen gibt, suchen und pinnen Sie die betroffenen Tests, von denen ich nichts wusste, und fahren Sie mit Schritt 3 fort

In dem seltenen Szenario, in dem die Tests läuferempfindlich sind, bin ich mir nicht sicher, ob es schwierig ist, sie läuferunempfindlich zu machen. Es kann nicht schlimmer sein als die Integrationstests, die ich für ILMerge geschrieben habe und die ich resistent gegen ReSharper- und NCrunch-Schattenkopien gemacht habe.

@aolszowka Ich stimme Ihrem Punkt zu 100% zu, dass wir bei allem, was wir tun, die Zeit der Mitwirkenden respektieren sollten, indem wir die Beitragsdokumente einfach und aktuell halten.

@jnm2 Ich mag deinen "kanonischen" Ansatz. Ich bezweifle, dass es einfach sein wird, im Test Explorer alles reibungslos zum Laufen zu bringen, aber es ist einen Versuch wert.

Es ist immer noch nützlich, es ist wichtig für jeden, der an Nunit arbeitet, zu wissen, wann er zu einer niedrigeren Teststufe wechseln muss.

Das Größte, was wir tun können, um diese Idee voranzubringen, ist IMO, separate System- und vielleicht Integrationstests einzurichten.

Dies kann die Ursache sein. Beim Schreiben von Tests zum Abrufen von XML von FrameworkController ist mir aufgefallen, dass TestContext.WorkDirectory in C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE geändert wurde:

https://github.com/nunit/nunit/blob/81fcc7c047c09fcb5a86989d0829716ca7d08e1e/src/NUnitFramework/framework/Api/DefaultTestAssemblyBuilder.cs#L137

Aufrufliste:

>   nunit.framework.dll!NUnit.Framework.Api.DefaultTestAssemblyBuilder.Build(System.Reflection.Assembly assembly, string suiteName, System.Collections.Generic.IDictionary<string, object> options) Line 137    C#
    nunit.framework.dll!NUnit.Framework.Api.DefaultTestAssemblyBuilder.Build(string assemblyNameOrPath, System.Collections.Generic.IDictionary<string, object> options) Line 114    C#
    nunit.framework.dll!NUnit.Framework.Api.NUnitTestAssemblyRunner.Load(string assemblyNameOrPath, System.Collections.Generic.IDictionary<string, object> settings) Line 154   C#
    nunit.framework.dll!NUnit.Framework.Api.FrameworkController.LoadTests() Line 204    C#

Das liegt daran, dass TestContext.WorkDirectory ein statischer veränderlicher Zustand ist:

https://github.com/nunit/nunit/blob/81fcc7c047c09fcb5a86989d0829716ca7d08e1e/src/NUnitFramework/framework/TestContext.cs#L96 -L101

Das bedeutet, dass er von allen Tests (!) gemeinsam genutzt wird, auch von gleichzeitigen. Jeder Test, der auf WorkDirectory basiert, muss mit [NonParallelizable] markiert werden, um korrekt zu sein.

Dieses Problem habe ich schon vor längerer Zeit festgestellt. Irgendwo gibt es ein Problem damit.

Nicht parallelisierbar ist nicht genug. Wenn ein Test WorkDirectory modifiziert (wie es viele der NUnit-Tests tun), besteht eine vernünftige Wahrscheinlichkeit, dass andere Tests, die darauf basieren, fehlschlagen.

Es hängt alles von der Reihenfolge ab, in der die Tests ausgeführt werden, die in NUnit nicht definiert ist.

Es ist beabsichtigt, dass das Arbeitsverzeichnis einmal gesetzt wird und für den Lauf unverändert bleibt. Alles andere ist ein Bug.

Gibt es einen Grund, warum wir nicht für jeden Ausführungskontext ein unabhängiges Arbeitsverzeichnis zulassen können?

@CharliePoole Wie würden wir das verwirklichen? Da die Framework-Tests FrameworkController testen, einen Controller-Lauf in einem Controller-Lauf, sind wir in einer Sonderstellung.

Abgesehen von unseren Tests bedeutet WorkDirectory "das Verzeichnis, das vom Benutzer festgelegt wurde, um alle Ausgabedateien für den Lauf zu empfangen". Ein Test sollte es also nicht ändern können.

Für unsere eigenen Tests müssen wir es einstellen können, aber diese Einstellung sollte andere Tests nicht beeinflussen, wenn wir es richtig machen. Wir machen es wahrscheinlich nicht richtig. 😜

Zur Not könnten wir es unveränderlich machen und aufhören, es zu testen. <ducks>

Das ist eigentlich eine coole Idee - ob das statische Feld gesetzt wurde und danach das Setzen überspringen? Auf diese Weise ist es unveränderlich und ich sehe keine Tests, die überprüfen, ob DefaultTestAssemblyBuilder setzt, also sollten wir gut sein!

Es gibt NUnit-Tests, die es ändern, und wenn es unveränderlich gemacht wird, können sie fehlschlagen.

@oznetmaster Ich habe gesucht, aber keine NUnit-Tests gefunden, die es außer versehentlich ändern. Hast du was zur Hand?

Ich müsste mein Archiv durchsuchen.

Ich habe das Problem in meinem CF-Build bereits behoben, indem ich das besprochene getan habe. Der Wert darf nur einmal gesetzt werden. Ich überprüfe, ob es null ist, und wenn dies der Fall ist, lasse es zu.

                if (options.ContainsKey (FrameworkPackageSettings.WorkDirectory))
                    TestContext.DefaultWorkDirectory = options[FrameworkPackageSettings.WorkDirectory] as string;
                else
                    if (TestContext.DefaultWorkDirectory == null)
                        TestContext.DefaultWorkDirectory = Directory.GetCurrentDirectory ();

Das Problem waren die Tests, die DefaultTestAssemblyBuilder.Build mit Optionen aufrufen, die FrameworkPackageSettings.WorkDirectory nicht enthalten, wodurch TestContext.DefaultWorkDirectory von CurrentDirectory überschrieben wird. Dies bedeutete, dass das WorkDirectory, wenn es in der Ausführung der obersten Ebene festgelegt wurde, vom Test überschrieben und nie wiederhergestellt wurde.

Klingt, als wären wir gut, den gleichen Ansatz zu wählen?

Funktioniert bei mir. Mein CF-Build besteht 100% der NUnit-Tests.

@OmicronPersei Wenn du in den nächsten Tagen da bist, kannst du @oznetmasters Fix eine

Jawohl! Werde es heute Abend versuchen

Ich kann diesen Fehler nicht wirklich reproduzieren, da nunit3-vs-adapter#528 andere Probleme verursacht. Ideen?

@OmicronPersei Oh. Ich weiß nicht. Wäre die Verwendung einer .runsettings mit WorkDirectory korrekt eingestellt eine gute Lösung?

Ok das habe ich probiert. TestCaseSourceCanAccessWorkDirectory erfolgreich, aber StackTracesAreFiltered schlägt mit derselben Nachricht/Stack-Trace im OP fehl.

Ich denke, StackTracesAreFiltered sollte auf 5 erhöht werden. Es ist ein Geruchstest, damit wir bemerken, wenn neue Frames hinzugefügt werden, damit wir sicherstellen können, dass es nicht außer Kontrolle gerät.

Was ist mit TestCaseSourceCanAccessWorkDirectory , oder ist das noch Gegenstand dieser PR?

ForTestCaseCanAccessWorkDirectory, löst der Fix von @oznetmaster das

Ich kann das Problem auf meinem Gerät nicht reproduzieren, der betreffende Test besteht für mich.

Keine Sorge, das kann jemand anderes übernehmen. Ich mag auch kleinere PRs.

Ich versuche nur, Hausputz zu machen; Gibt es einen Grund, warum dieses Problem noch offen sein sollte oder können wir es mit einer Lösung schließen? (Auch wenn es WONTFIX ist).

Nein, danke für den Hinweis. Schließen.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen