Nunit: Échec des tests unitaires dans nunit.framework.tests après un nouveau clone

Créé le 25 juin 2018  ·  31Commentaires  ·  Source: nunit/nunit

Je viens de saisir un nouveau clone de nunit et d'ouvrir la solution dans Visual Studio 2017 (Communauté 15.7.4) avec le dernier adaptateur de test NUnit 3 (3.10 avec exécuter des tests en parallèle) exécuté sur Windows 10 Professionnel et sélectionné le "Debug-AnyCPU " et appuyez sur build.

Après avoir lu le BUILDING.md, il semble que je devrais ignorer les échecs qui ne proviennent pas de nunit.framework.tests-* et nunitlite.tests-*

Cependant, hors de la porte, j'obtiens 2 échecs de nunit.framework.tests-*

Première erreur :

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"
  -------------------------------------------------^

En regardant la source, je ne vois pas comment cela a été possible, pour autant que je sache, ces valeurs auraient dû être identiques ( _workDirectory et les données de test sont toutes les deux définies sur TestContext.CurrentContext.WorkDirectory ) mon seul Je suppose qu'il s'agit d'un type de condition de concurrence, peut-être dû à une mauvaise configuration de mon côté ?

Deuxième erreur :

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)

Je me perds dans ce que ce test essaie de faire ici ; mais sur la base de ma compréhension limitée, il semble que ce code soit vraiment sensible à tout changement dans la pile d'appels, cela pourrait-il être dû à un changement récent dans le .NET Framework ?

Je reçois également tous les cas de test qui échouent dans NUnitLite.Tests.CommandLineTests. Je serais heureux de creuser là-dessus si cela est inattendu.

Étant donné que la construction passe dans CI, ce ne sont probablement que des problèmes de configuration de mon côté, mais rien n'a été mentionné dans BUILDING.md à ce sujet, alors j'ai pensé qu'un rapport en valait la peine.

bug normal

Tous les 31 commentaires

Merci pour le rapport ! J'ai confirmé que TestCaseSourceCanAccessWorkDirectory et CommandLineTests ne fonctionnent pas dans Test Explorer. Nous devons trouver un moyen de les rendre indépendants du coureur et du parallélisme. @nunit/framework-team Des idées ?

Pour la deuxième erreur, c'est un test d'odeur. Il est logique de porter ce chiffre à 5.

Dans le passé, je disais simplement aux gens de ne pas utiliser l'explorateur de tests pour les tests NUnit. D'autres membres de l'équipe ont repoussé cela en disant que l'explorateur de tests est devenu, pour de nombreuses personnes, le moyen par défaut d'exécuter des tests.

Il existe certainement de nombreux précédents pour qu'un coureur particulier ne soit pas utile lors du test d'un framework de test. Les frameworks de test en cours de test sont une situation assez spéciale et non rencontrée par la plupart des utilisateurs. OTOH, si l'équipe le souhaite, peut-être que vous vous fixerez comme objectif de pouvoir exécuter avec succès l'explorateur de test via l'adaptateur.

Quoi que vous fassiez, je pense que vous devriez probablement publier une documentation indiquant aux gens que l'exécution de tests NUnit sous l'explorateur de tests ne fonctionne pas actuellement. Vous pouvez leur dire dans ce contexte soit que c'est un objectif de le faire fonctionner, soit que ce n'est pas une priorité, selon ce qui est décidé.

En tant que premier auteur de l'adaptateur et contributeur de nombreuses années au framework, j'ai toujours décrié l'utilisation de l'explorateur de tests dans le développement de NUnit. C'est toujours mon point de vue sur la question. Zut, je n'aime même pas que nous utilisions la console pour tester le framework dans notre CI maintenant !!!

Quelle que soit la décision, je pense que vous devrez continuer à renvoyer les gens vers les exécuteurs NUnit réels (soit NUnitLite, soit l'exécuteur de console) lorsque des problèmes surviennent, qui peuvent ou non être dus à l'adaptateur. L'adaptateur reste fondamentalement équivalent à un programme d'exécution tiers, même s'il se trouve dans le cadre du projet NUnit.

FWIW de l'extérieur en regardant dedans : Peu m'importe de quel côté il coupe tant qu'il est documenté en tant que tel.

En tant que développeur, je vais essayer de faire ce que je ferais normalement lorsque je rencontre un nouveau projet qui utilise les mêmes pratiques que j'utilise en interne :

  1. Cloner le code
  2. Lisez le fichier README.md/BUILD.md/HACKING.md
  3. Tenter une compilation (sans modifications)
  4. Exécutez les tests unitaires (via le Runner intégré).
  5. Si tout fonctionne, commencez à jouer avec des trucs.

Dans le passé, cela aurait été le dotCover de ReSharper, mais nous avons essayé de nous en débarrasser car les coûts de licence sont tout simplement fous pour les petits magasins / développeurs individuels lorsqu'il existe des alternatives de logiciels libres / open source qui "fonctionnent pour la plupart".

Il y a beaucoup (à mon avis) dans le concept d'environnement de développement intégré, ne pas avoir à sortir du flux de travail est super utile, c'est pourquoi nous le faisons.

Cependant, si nous sommes censés utiliser Console Runner (ou un autre Runner) cela me convient, il suffit de le documenter.

Si vous développez sur NUnit, travaillez sur le framework, je pense que mélanger tous les coureurs qui font les choses de manière spéciale (R#, notre propre adaptateur) peut brouiller le problème. J'aime savoir que le framework fonctionne correctement de manière isolée avant de le tester avec des coureurs. Donc, dans mon propre travail, j'utilise nunitlite pour tester pendant que je développe, puis j'exécute le CI localement. Si une personne souhaite développer sur NUnit dans Test Explorer, je dirais qu'elle devrait toujours exécuter CI localement et devrait également se rabattre sur nunitlite ou nunit3-console lorsque tout semble louche.

Pour les personnes qui exécutent simplement les tests nunit à partir d'une version particulière, je pense qu'il y a beaucoup plus de latitude.

Nous devrions rendre CI canonique, probablement avec NUnitLite pour tous les tests de framework, puis la console, l'adaptateur VSTest et un exécuteur UWP pour les tests de bout en bout.

En supposant que CI soit solide, cela me semble correct s'il existe des différences subtiles entre Test Explorer, ReSharper, NCrunch et notre script CI. Dire que ces outils dans l'IDE doivent être ignorés est quelque chose que je considère comme un obstacle à la contribution et faux puisque ce n'est même pas mon flux de travail. Mon flux de travail idéal :

  1. Localisez les tests existants ou écrivez de nouveaux tests
  2. Épinglez ce montage de test pour qu'il soit rapide de réexécuter les tests tout en tapant (encore mieux, lancez des tests continus)
  3. Mettre en œuvre un changement
  4. Avant de créer un commit Git, exécutez .\build.ps1 -t test pour vous assurer que les réussites et les échecs sont comme prévu
  5. S'il y a des surprises, recherchez et épinglez les tests concernés que je ne connaissais pas et passez à l'étape 3

Dans le cas rare où les tests sont sensibles aux coureurs, je ne suis pas sûr qu'il soit difficile de les rendre insensibles aux coureurs. Cela ne peut pas être pire que les tests d'intégration que j'ai écrits pour ILMerge que j'ai rendus résistants aux clichés instantanés ReSharper et NCRunch.

@aolszowka Je suis à 100% d'accord avec votre point de vue selon lequel quoi que nous fassions, nous devrions respecter le temps des contributeurs en gardant les documents de contribution faciles à utiliser et à jour.

@jnm2 J'aime votre approche "canonique". Je doute qu'il soit facile de tout faire fonctionner correctement dans Test Explorer, mais cela vaut la peine d'essayer.

C'est toujours utile, c'est essentiel, pour quiconque travaille sur nunit de savoir quand passer à un niveau de test inférieur.

La plus grande chose que nous puissions faire pour faire avancer cette idée IMO est d'établir un système séparé et peut-être des tests d'intégration.

Cela peut être la cause première. Lors de l'écriture de tests pour obtenir XML à partir de FrameworkController, j'ai remarqué que TestContext.WorkDirectory était changé en C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE :

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

Pile d'appels :

>   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#

C'est parce que TestContext.WorkDirectory est un état mutable statique :

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

Cela signifie qu'il est partagé par tous les tests (!), y compris les tests concurrents. Tout test qui repose sur WorkDirectory doit être marqué [NonParallelizable] pour être correct.

J'ai noté ce problème il y a longtemps. Il y a un problème à ce sujet quelque part.

NonParallélisable n'est pas suffisant. Si un test modifie WorkDirectory (comme le font de nombreux tests NUnit), il existe une probabilité raisonnable que d'autres tests qui s'appuient sur lui échouent.

Tout dépend de l'ordre dans lequel les tests sont exécutés, qui n'est pas défini dans NUnit.

L'intention est que le répertoire de travail doit être défini une fois et rester inchangé pour l'exécution. Tout le reste US un bug.

Y a-t-il une raison pour laquelle nous ne pouvons pas autoriser un répertoire de travail indépendant pour chaque contexte d'exécution ?

@CharliePoole Comment

Laissant de côté nos tests, la signification de WorkDirectory est "le répertoire défini par l'utilisateur pour recevoir tous les fichiers de sortie pour l'exécution". Donc un test ne devrait pas pouvoir le changer.

Pour nos propres tests, nous devons pouvoir le définir, mais ce paramètre ne devrait pas affecter les autres tests si nous le faisons correctement. Nous ne le faisons probablement pas correctement. 😜

À la rigueur, nous pourrions le rendre immuable et arrêter de le tester. <ducks>

C'est en fait une bonne idée - savoir si le champ statique a été défini et ne pas le définir par la suite ? De cette façon, c'est immuable et je ne vois aucun test qui vérifie si DefaultTestAssemblyBuilder définit, donc nous devrions être bons !

Il existe des tests NUnit qui le modifient, et s'il est rendu non modifiable, ils peuvent échouer.

@oznetmaster J'ai cherché mais je ne trouve aucun test NUnit qui le modifie, sauf accidentellement. En avez-vous à portée de main ?

Je devrais chercher dans mes archives.

J'ai déjà résolu le problème dans ma version CF en faisant ce qui a été discuté. Permettre à la valeur d'être définie une seule fois. Je vérifie qu'il est nul, et si c'est le cas, alors permets qu'il soit défini.

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

Les tests qui posaient problème étaient ceux qui appelaient DefaultTestAssemblyBuilder.Build avec des options qui n'incluaient pas FrameworkPackageSettings.WorkDirectory, provoquant l'écrasement de TestContext.DefaultWorkDirectory par CurrentDirectory. Cela signifiait que si le WorkDirectory avait été défini dans l'exécution de niveau supérieur, il serait écrasé par le test et jamais restauré.

On dirait que nous serions bien d'adopter la même approche alors?

Travaille pour moi. Ma version CF réussit 100 % des tests NUnit.

@OmicronPersei Si vous êtes là dans les prochains jours, pouvez-vous essayer le correctif de ?

Oui! je vais essayer ce soir

Je ne peux pas vraiment reproduire ce bogue à cause de nunit3-vs-adapter#528 causant d'autres problèmes. Des idées ?

@OmicronPersei Oh. Je ne sais pas. L'utilisation d'un fichier .runsettings avec WorkDirectory correctement défini serait-elle une bonne solution de contournement ?

Bon j'ai essayé ça. TestCaseSourceCanAccessWorkDirectory réussit mais StackTracesAreFiltered échoue avec la même trace de message/pile dans l'OP.

Je pense que StackTracesAreFiltered devrait être augmenté à 5. C'est un test d'odeur afin que nous remarquions si de nouveaux cadres sont ajoutés afin que nous puissions nous assurer qu'il n'est pas devenu incontrôlable.

Qu'en est-il de TestCaseSourceCanAccessWorkDirectory , ou est-ce toujours dans le cadre de ce PR ?

PourTestCaseCanAccessWorkDirectory, le correctif de résout-il ? Sinon, nous devrons enquêter davantage.

Je n'arrive pas à reproduire le problème sur ma machine, le test en question passe pour moi.

Pas de soucis, quelqu'un d'autre peut faire cette partie. J'aime aussi avoir des PR plus petits.

J'essaie juste de faire le ménage ; y a-t-il une raison pour laquelle ce problème devrait toujours être ouvert ou pouvons-nous le fermer avec un certain type de résolution ? (Même si c'est WONTFIX).

Non, merci de l'avoir signalé. Fermeture.

Cette page vous a été utile?
0 / 5 - 0 notes