Nunit: Exécuter des méthodes de test dans un appareil en parallèle

Créé le 5 août 2014  ·  76Commentaires  ·  Source: nunit/nunit

Actuellement, nous n'avons implémenté l'exécution parallèle qu'au niveau de l'appareil. Il devrait être possible d'exécuter des méthodes individuelles d'un appareil en parallèle ainsi que des cas de test individuels pour une méthode paramétrée.

Nous devrions être en mesure de spécifier le niveau exact de parallélisme sur l'appareil ou la méthode.

Ce numéro faisait auparavant partie du #66

done hardfix feature high

Commentaire le plus utile

Si je pouvais prétendre prédire l'avenir, cela ne vous satisferait que jusqu'en septembre. :-)

Permettez-moi de répondre en expliquant comment nous « programmons » les fonctionnalités.

Nous essayons actuellement (depuis le début de l'année) une approche qui a des sorties qui sortent une fois par trimestre. Au fur et à mesure que nous nous améliorons dans la libération, nous pouvons augmenter le rythme. À terme, nous pourrons peut-être effectuer un déploiement continu.

Dans un projet Open Source volontaire, il n'y a pas de montant fixe d'effort disponible par mois. Nous pouvons utiliser l'approche « temps d'hier », mais il s'avère que le temps que les gens doivent passer sur NUnit, ainsi que le nombre de personnes volontaires, est assez variable.

En guise de compromis, nous sélectionnons un petit nombre de problèmes qui sont essentiels à une version et les ajoutons au jalon à l'avance. Ma préférence est de ne pas ajouter plus d'environ 25 % de ce que nous pouvons espérer faire. La majorité des problèmes d'une version ne sont ajoutés à ce jalon qu'une fois qu'ils sont terminés ou au mieux lorsque quelqu'un s'engage à y travailler. Vous ne trouverez généralement pas de problèmes ouverts dans notre jalon 3.5 sans que quelqu'un leur soit affecté, bien que je le fasse de temps en temps s'il semble que quelque chose bloque d'autres travaux.

Donc, le côté positif de ce que nous faisons est que nous pouvons pratiquement garantir que la version sortira à temps. Le côté négatif est que nous ne pouvons pas vous dire ce qu'il y aura dedans. :-(

Pour ce problème particulier... Je lui ai donné une priorité élevée afin de dire à nos développeurs que c'est important. Quelqu'un doit être libre de travailler dessus et avoir suffisamment d'expérience pour un projet de cette envergure et de cette difficulté. Si quelqu'un avec le bon bagage le découvre dans les prochaines semaines, je suppose que cela peut être fait d'ici la sortie. À titre indicatif, je pense qu'il me faudrait environ un mois, tout en travaillant sur d'autres choses également, pour me frayer un chemin à travers cela.

Désolé il n'y a pas de réponse plus définitive mais une telle réponse serait forcément un mensonge !

Tous les 76 commentaires

Mise à jour : ce commentaire et le suivant étaient en réponse à un individu qui a apparemment supprimé ses propres commentaires. Je laisse mes réponses.

Eh bien, c'est dans les spécifications et prévu pour l'implémentation post-3.0. Si c'était si facile, nous l'aurions probablement fait. Je ne sais pas quelle connexion vous voyez avec mbunit. Le fait qu'ils l'aient eu ne nous aide pas.

Cela devient un peu lassant. Quelques points, déjà dits mais apparemment manqués...

  1. Il existe un plan pour mettre en œuvre ce que vous demandez.
  2. Nous avons décidé en équipe de le programmer à un moment donné.
  3. Le moment où il est programmé a principalement à voir avec notre évaluation de la valeur de la fonctionnalité par rapport à d'autres fonctionnalités.
  4. Il y a plusieurs personnes dans l'équipe NUnit qui pourraient implémenter la fonctionnalité.
  5. Ils seraient capables de le mettre en œuvre, en fonction des priorités, hors de leur tête et n'auraient pas besoin de le copier de n'importe où.

Je trouve votre discours de "reverse engineering" très dérangeant. L'open source n'est possible que dans un contexte où le droit d'auteur est respecté. Donc, si vous suggérez que nous pourrions ignorer les conditions de licence mbunit, vous êtes loin de la base.

Bien que j'aie contribué à de nombreux correctifs à MbUnit et que je l'ai utilisé pendant des années, j'étais
jamais un contributeur clé. Je ne voudrais pas que mon statut soit déformé :)

Quant à la rétro-ingénierie, elle n'a pas vraiment d'utilité ici. L'unité fonctionne
totalement différent de celui de MbUnit. Nous aborderons ce problème en temps voulu,
mais nous l'abordons avec prudence car d'autres problèmes similaires pourraient changer
la façon dont nous devons mettre en œuvre cela ou même un conflit.
Le 19 avril 2015 à 02h45, "CharliePoole" [email protected] a écrit :

Cela devient un peu lassant. Quelques points, déjà énoncés mais
apparemment raté...

1.

Il existe un plan pour mettre en œuvre ce que vous demandez.
2.

Nous avons décidé en équipe de le programmer à un moment donné.
3.

Le moment où il est programmé a principalement à voir avec notre évaluation de la
valeur de la caractéristique par rapport à d'autres caractéristiques.
4.

Il y a plusieurs personnes dans l'équipe NUnit qui pourraient mettre en œuvre le
caractéristique.
5.

Ils seraient en mesure de le mettre en œuvre, en fonction des priorités, à partir de
leurs têtes et n'auraient pas besoin de le copier de n'importe où.

Je trouve votre discours de "reverse engineering" très dérangeant. L'open source est
possible que dans un contexte où le droit d'auteur est respecté. Alors si vous êtes
suggérant que nous pourrions ignorer les conditions de licence mbunit, vous êtes loin
base.

-
Répondez directement à cet e-mail ou consultez-le sur GitHub
https://github.com/nuni/nunit/issues/164#issuecomment-94244650 .

Un commentaire bien plus plein de tact que le mien !

Nos priorités actuelles dans le monde de l'exécution parallèle sont :

  1. Exécution de processus en parallèle
  2. Groupes d'exclusion
  3. Exécution de la méthode parallèle (dans un appareil).

Cela semble représenter l'ordre de la plus grande utilité pour les utilisateurs.

Je mentionnerai également que marquer quelque chose comme post-3.0 ne signifie pas nécessairement que la fonctionnalité arrive plus tard que si nous l'intégrions à la 3.0. Au contraire, cela peut signifier que la 3.0 arrive plus tôt dans le temps.

Lorsque nous ferons cela, nous devrons décider comment gérer les commandes de configuration et de démontage. L'option la plus simple serait probablement de construire la classe de test pour chaque test afin qu'il n'y ait pas de conflit pour les données.

Je préférerais de toute façon en faire une option à un moment donné, mais je ne sais pas s'il s'agit d'une option d'exécution ou d'une option appareil par appareil (attribuée) ou des deux.

Salut!
L'ajout de cette fonctionnalité à la prochaine version de NUnit serait formidable, car c'est la seule chose qui m'empêche de passer à NUnit. Cette fonctionnalité est-elle toujours prévue pour la 3.4 ?

@julianhaslinger NUnit 3.4 sortira à la fin du mois, donc non, cette fonctionnalité ne sera pas incluse.

Pour info, ce problème se trouve dans notre jalon de carnet de commandes (ou pseudo-jalon) plutôt que 3.4, car nous suivons une pratique consistant à n'ajouter à l'avance qu'un petit nombre de problèmes de définition clés à chaque jalon numéroté.

Le prochain jalon, 3.6, devrait tomber dans 3 mois supplémentaires, ce qui vous semble probablement décourageant. :-( Cependant, si vous constatez que ce problème est fusionné avec le master, vous pourrez obtenir une version plus rapide de notre flux MyGet.

@julianhaslinger ce ne sera pas dans 3.4 qui sortira probablement dans un peu plus d'une semaine, mais c'est celui que j'aimerais voir bientôt terminé, donc votre vote aide :+1:

En passant, quel framework de test utilisez-vous qui prend en charge l'exécution de méthodes parallèles ? Je pensais que XUnit permettait uniquement d'exécuter des tests en parallèle jusqu'au niveau de la classe également. Est-ce que je me trompe ? Je n'utilise pas beaucoup XUnit :smile:

@CharliePoole Merci pour la réponse ! D'accord, cela semble un peu décourageant, cependant. Cependant, j'attendrai les prochaines versions (ou des baisses antérieures). Veuillez (encore) considérer cette fonctionnalité dans la prochaine version (3.6).

@rprouse J'utilise MbUnit/Gallio en ce moment. Le projet est à peu près mort et maintenant je vais passer à NUnit.

@julianhaslinger Est-ce une question de temps de course pour vous ? Avez-vous des chiffres sur la distribution des cas de test au sein des appareils ? Je pose la question parce que mon hypothèse est que la fonctionnalité donne peu aux utilisateurs au-delà de ce qu'ils obtiennent des appareils parallèles. Si c'est faux, cela pourrait changer sa priorité relative.

@CharliePoole Exactement, notre problème réel est le temps d'exécution des cas de test. Nous aimerions utiliser NUnit pour nos tests automatisés / de régression (y compris Selenium / WebDriver) et comme certaines de nos classes de test ont plus de 200 cas de test, il est actuellement très difficile d'exécuter l'ensemble de la suite de tests avec NUnit.

Des comparaisons (au sein d'un ensemble de tests plus petit de nos tests de régression) ont montré qu'une solution NUnit possible sera exécutée en environ 1,5 heures alors que la solution MBunit actuelle sera exécutée en 0,5 heures (même ensemble de tests).

Cependant, @CharliePoole , je suis conscient du fait que nous pourrions peut-être réduire le temps d'exécution en divisant les classes de test plus grandes en plus petites, mais cela saperait en quelque sorte l'idée initiale de notre hiérarchie de classes de test.

@julianhaslinger - Juste pour confirmer, êtes-vous sûr que le temps d'exécution est lié au processeur et non à la mémoire ?

Nous avons rencontré le même problème lorsque nous avons essayé pour la première fois de passer à NUnit 3 - le temps d'exécution est devenu considérablement plus long. Cela était dû au fait que NUnit utilisait au maximum la mémoire disponible - il y a un problème avec la version actuelle qui conserve tous les objets de test jusqu'à ce que le test soit terminé. Nous utilisons actuellement une version corrigée en interne - je voulais obtenir un PR pour la 3.4, mais je ne suis pas sûr d'avoir le temps à ce stade. :-(

Désolé si ce n'est pas le cas, mais j'ai pensé que cela valait la peine d'être mentionné, car Selenium peut utiliser sa juste part de mémoire. :-)

@ChrisMaddock Merci pour la contribution ! :+1: Nous y jetterons un oeil prochainement et je reviendrai vers vous alors.

@ChrisMaddock J'aimerais voir votre correction de mémoire dans 3.4. Si vous souhaitez mettre en place un PR, nous pouvons vous aider à le nettoyer s'il n'est pas encore prêt pour la production :+1:

@rprouse - Ce commit initial https://github.com/nuni/nunit/pull/1367/commits/5f98ae51025f7af8244abd4367d1f47260874dfc dans PR #1367 libère les choses correctement pour nous, dans une v3.0.1 corrigée.

Vous verrez dans le PR qu'il a été déplacé vers OneTimeTearDown avant la fusion - je ne sais pas encore si ce déplacement l'a empêché de fonctionner dans la v3.2.1, ou s'il y avait un autre changement qui a réintroduit le rétention - Je n'ai peut-être pas retesté après avoir déménagé.

J'essaierai de le retester et de le lancer demain, ce serait bien pour nous de revenir également aux versions principales. :-)

@ChrisMaddock J'ai examiné la consommation de mémoire lors d'un test de régression et j'ai découvert que l'exécution des tests n'est pas liée à la mémoire. Je suppose que nous devons vraiment attendre une version de NUnit capable de gérer l'exécution parallèle de méthodes individuelles à l'intérieur de chaque classe.

juste pour ajouter à ce que @julianhaslinger a dit, j'ai vu exactement le même problème lors de l'utilisation de NUnit avec des tests Selenium. J'ai dû écrire un wrapper personnalisé qui exécute des instances individuelles de nunit-console.exe sur un seul test tel qu'il est extrait d'un assembly réussi afin que je puisse exécuter des tests parallèles pour le moment. Ce n'est pas idéal car cela entraîne la génération de nombreux fichiers de sortie .xml (un pour chaque test) plutôt qu'une seule sortie .xml et cela signifie également que je ne peux pas utiliser les méthodes _OneTimeSetUp_ et de démontage et que je dois plutôt m'appuyer sur des sémaphores externes et des variables d'environnement pour contrôler le flux d'exécution où je ne veux exécuter les choses qu'une seule fois. J'ai suivi la promesse d'avoir une exécution parallèle dans NUnit depuis longtemps maintenant (des années) et j'ai été très déçu de la façon dont la fonctionnalité a été déployée dans 3.0 (seulement partiellement pris en charge et nécessitant de véritables fouilles dans les problèmes et les notes de version pour découvrir que tout n'était pas réellement pris en charge). Je suis même allé jusqu'à enquêter sur ce qui serait impliqué pour faire avancer cela moi-même, mais malheureusement, il semble que la conception de NUnit va à l'encontre de la mise en œuvre de l'exécution parallèle au niveau de la méthode de test, je n'ai aucune idée de ce que vous aimeriez réellement pour gérer le potentiel de code non threadsafe (c'est-à-dire devrait-il être laissé à la personne utilisant NUnit en parallèle pour s'assurer que toutes les méthodes de test référencent correctement tous les externes d'une manière threadsafe ou si NUnit lui-même doit gérer l'exécution de chaque méthode dans son propre domaine tout en essayer de n'exécuter qu'une seule fois les méthodes de configuration et de démontage uniques) et comme j'ai déjà une solution de contournement en place, je ne pouvais pas justifier le temps passé à implémenter cette fonctionnalité moi-même (ce qui est probablement pour le mieux car j'ai déjà été brûlé quand travailler avec des équipes sur GitHub pour les aider à mettre en œuvre une exécution parallèle). Quoi qu'il en soit... désolé de divaguer... Je comprends que la priorité pour les tests unitaires du code C# ne repose probablement pas autant sur le parallélisme au niveau des méthodes, mais sachez que pour ceux d'entre nous qui utilisent NUnit pour les tests basés sur Selenium ce serait une énorme amélioration. Merci d'avance! :le sourire:

Merci pour vos commentaires. Je pense que je vais radoter un peu moi-même ici...

Cela aide à comprendre ce dont les gens ont besoin et pourquoi ils en ont besoin. N'étant pas moi-même développeur web, j'ai essayé d'écouter les utilisateurs de Selenium et de me concentrer sur ce qu'ils voulaient. Ce qui semblait être des montages parallèles avec un ordre parmi les cas de test. Je comprends parfaitement que différentes personnes voudront des choses différentes, mais lorsque les deux groupes se présentent comme exprimant "ce dont les utilisateurs de Selenium ont besoin", c'est un peu déroutant. Pouvez-vous me décrire les types de tests Web qui pourraient nécessiter un parallélisme au niveau des méthodes, par opposition à ceux qui souhaitent exécuter des méthodes dans un ordre prédéfini ? Je pense que je pourrais deviner, mais je préfère l'avoir d'un utilisateur.

En ce qui concerne votre solution de contournement... avez-vous envisagé d'utiliser des assemblages de test distincts ? NUnit serait heureux de les exécuter en parallèle dans un processus séparé. Bien sûr, cela n'élimine pas le besoin de synchroniser l'accès à des éléments tels que des fichiers.

Concernant la sécurité des threads - nous n'avons jamais prévu que notre implémentation parallèle prenne la responsabilité de la sécurité des threads. La seule chose que je m'attendais à garantir est que NUnit ne créera aucun problème de sécurité des threads si vos méthodes sont déjà thread-safe. Cela en soi s'avère non trivial.

Merci pour la réponse. Je comprends tout à fait vos commentaires sur
ordre de l'exécution des tests dans un appareil et division des tests en différents
assemblées.

Je suis déjà un utilisateur de NUnit depuis des années (et JUnit avant cela)
donc l'idée de s'appuyer sur l'ordre des tests dans un appareil n'était même pas un
considération dans ma conception de test. Chaque test essaie d'être un
action ou ensemble d'actions au sein du site sans attente sur ordre de
exécution. Le design du site que je teste signifie aussi que de nombreux tests
peut prendre jusqu'à 20 minutes pour s'exécuter (une grande partie de ce temps est passée en attente
que quelque chose se passe sur le site) et le type de test couvre
plusieurs scénarios similaires afin que les classes de test de base soient utilisées pour réduire le code
duplication et augmentation de la maintenabilité grâce à l'utilisation d'une classe de base commune
méthodes. Les tests sont organisés en projets séparés basés sur le dev
propriété de l'équipe de cette zone (nous utilisons donc des assemblages séparés, mais il
y a beaucoup de tests par assembly et mon wrapper de test gérera l'exécution de
tous les tests dans tous passés dans les assemblages en parallèle car il a été créé avant
la première version officielle de NUnit 3 et je voulais m'assurer que tous les tests avaient
le potentiel d'être exécuté simultanément avec suffisamment de threads
disponible).

Essentiellement, vous pouvez imaginer qu'un assemblage peut avoir 10 tests et
100 autres tests, mais l'assemblage avec 10 a des tests prenant 10 minutes
chacun alors que l'assemblage avec 100 a des tests prenant 1 minute chacun. Si je
avoir une machine capable d'exécuter 110 threads parallèles (ce qui est en fait
partie de la conception de notre infrastructure) alors je m'attendrais à ce que les tests se terminent
en 10 minutes, pas en 100 minutes.

Espérons que cela aide à expliquer... désolé si les choses ne sont toujours pas totalement claires,
mais le point global est que le parallélisme au niveau de la méthode est quelque chose que j'ai
vu manquant dans d'autres bibliothèques de test (prspec dans ruby ​​par exemple) et quand
faire l'analyse des améliorations de performances à obtenir en l'ajoutant i
trouvé que cela peut être un changement positif majeur. Voir l'exemple suivant :
https://github.com/bicarbon8/rspec-parallel/wiki/Examples
Le 1er juillet 2016 00:45, "CharliePoole" [email protected] a écrit :

Merci pour vos commentaires. Je pense que je vais radoter un peu moi-même ici...

Cela aide à comprendre ce dont les gens ont besoin et pourquoi ils en ont besoin. N'étant pas un
développeur web moi-même, j'ai essayé d'écouter les utilisateurs de Selenium et de me concentrer sur ce
ils voulaient. Ce qui semblait être des montages parallèles avec la commande
parmi les cas de test. Je comprends parfaitement que différentes personnes voudront
choses différentes, mais lorsque les deux groupes se présentent comme exprimant
"ce dont les utilisateurs de Selenium ont besoin", c'est un peu déroutant. Pouvez-vous me décrire
quels types de tests Web pourraient souhaiter un parallélisme au niveau de la méthode par opposition à
ces gens qui veulent exécuter des méthodes dans un ordre prédéfini ? je pense que je pourrais
deviner, mais je préfère l'avoir d'un utilisateur.

En ce qui concerne votre solution de contournement... avez-vous envisagé d'utiliser un test séparé
assemblées ? NUnit serait heureux d'exécuter chacun en parallèle dans un
traiter. Bien sûr, cela n'élimine pas la nécessité de synchroniser l'accès à
des choses comme des fichiers.

Concernant la sécurité des threads - nous n'avons jamais prévu notre implémentation parallèle
assumer la responsabilité de la sécurité des threads. La seule chose à laquelle je m'attendais
garantie est que NUnit ne _créera_ aucun problème de sécurité des threads si votre
les méthodes sont déjà thread-safe. Cela en soi s'avère non trivial.

-
Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/nuni/nunit/issues/164#issuecomment -229819324, ou couper le son
le fil
https://github.com/notifications/unsubscribe/ACNsyoczCUV9L7kbF2SHB7lLsyBKlrv9ks5qRFUJgaJpZM4CUZ8r
.

Merci pour l'info... c'est utile de voir une variété de points de vue.

Mes 5 centimes.

Dans notre projet, nous avons environ 25 assemblages de test et l'exécution de tests parallèles par assemblage et par appareil réduit déjà considérablement le temps d'exécution. L'exécution parallèle de tests au sein de fixture l'améliorera encore plus. Maintenant, nous avons même divisé les appareils les plus chronophages en plusieurs appareils pour accélérer l'exécution, mais ce sera bien mieux si nunit exécute les tests d'appareils en parallèle.

Ce que je veux vraiment voir dans nunit, c'est une parallélisation des tests au niveau des cas de test, car diviser ces tests en fixtures n'est pas toujours pratique et conduit à la duplication de code. Nous avons plusieurs tests qui peuvent prendre jusqu'à plusieurs milliers de cas de test (chaque exécution de cas est rapide mais au total cela prend quelques minutes) ou juste des dizaines de cas (mais chaque cas est lent) et pour l'instant de tels tests sont les principaux nous.

Merci pour la contribution... c'est un domaine que nous allons aborder dans la prochaine version avec la question concurrente mais complémentaire de s'assurer que certains tests ne s'exécutent pas en parallèle les uns avec les autres !

Ma question précédente portait davantage sur la façon dont les gens écrivent des tests, en particulier lorsqu'ils conduisent une application Web. Certaines personnes insistent pour que chaque méthode soit une étape séquencée et que l'appareil représente une série de telles étapes. Ceci est bien sûr non parallèle par définition. D'autres personnes semblent écrire des tests très similaires sans séquencer les tests. Je suppose que ce dernier groupe écrit des méthodes de test plus importantes, avec une série d'actions et d'assertions dans chacune.

@CharliePoole Bonne nouvelle ! Merci beaucoup!

À mon avis, les cas de test doivent être isolés et ne pas dépendre d'autres cas de test ou de l'ordre d'exécution. Si les gens veulent toujours exécuter des tests à un seul thread, ils peuvent toujours utiliser [Parallelizable(ParallelScope.None)] et/ou OrderAttribute.

Ce problème en cours de mise en œuvre permettra d'exécuter des suites de tests plus rapidement par rapport à une grille de pilotes Web locaux ou à un fournisseur Saas tel que BrowserStack ou SauceLabs. Actuellement, j'essaie de limiter le nombre de méthodes de test sur une classe de test au nombre de nœuds de pilote Web ou de sessions de navigateur disponibles, afin que la grille soit pleinement utilisée. Sinon, si un test a 8 méthodes de test et que ma grille a 8 sessions de navigateur disponibles, une seule sera utilisée car toutes les méthodes de test de la classe s'exécuteront une à la fois.

@pablomxnl Absolument d'accord. En tant que coach ou chef de projet, j'ai toujours poussé cette idée très fort. Cependant, je ne porte aucun de ces chapeaux ici. Je suis un fournisseur de logiciels avec des utilisateurs qui demandent des choses. S'ils demandent des trucs vraiment flagrants, je dis simplement non. Mais s'ils demandent des choses qui sont raisonnables dans certains contextes, mais pas dans d'autres - même pas la plupart - je les prends en considération.

Dans le cas des sites web, on ne parle presque toujours

Quoi qu'il en soit, il est toujours intéressant d'apprendre comment les gens utilisent réellement votre logiciel.

@CharliePoole , ne vous méprenez pas en posant cette question (je veux juste être sûr) : cette fonctionnalité sera-t-elle ajoutée à la prochaine version (3.5, prévue d'ici le 29 septembre 2016) ?

Si je pouvais prétendre prédire l'avenir, cela ne vous satisferait que jusqu'en septembre. :-)

Permettez-moi de répondre en expliquant comment nous « programmons » les fonctionnalités.

Nous essayons actuellement (depuis le début de l'année) une approche qui a des sorties qui sortent une fois par trimestre. Au fur et à mesure que nous nous améliorons dans la libération, nous pouvons augmenter le rythme. À terme, nous pourrons peut-être effectuer un déploiement continu.

Dans un projet Open Source volontaire, il n'y a pas de montant fixe d'effort disponible par mois. Nous pouvons utiliser l'approche « temps d'hier », mais il s'avère que le temps que les gens doivent passer sur NUnit, ainsi que le nombre de personnes volontaires, est assez variable.

En guise de compromis, nous sélectionnons un petit nombre de problèmes qui sont essentiels à une version et les ajoutons au jalon à l'avance. Ma préférence est de ne pas ajouter plus d'environ 25 % de ce que nous pouvons espérer faire. La majorité des problèmes d'une version ne sont ajoutés à ce jalon qu'une fois qu'ils sont terminés ou au mieux lorsque quelqu'un s'engage à y travailler. Vous ne trouverez généralement pas de problèmes ouverts dans notre jalon 3.5 sans que quelqu'un leur soit affecté, bien que je le fasse de temps en temps s'il semble que quelque chose bloque d'autres travaux.

Donc, le côté positif de ce que nous faisons est que nous pouvons pratiquement garantir que la version sortira à temps. Le côté négatif est que nous ne pouvons pas vous dire ce qu'il y aura dedans. :-(

Pour ce problème particulier... Je lui ai donné une priorité élevée afin de dire à nos développeurs que c'est important. Quelqu'un doit être libre de travailler dessus et avoir suffisamment d'expérience pour un projet de cette envergure et de cette difficulté. Si quelqu'un avec le bon bagage le découvre dans les prochaines semaines, je suppose que cela peut être fait d'ici la sortie. À titre indicatif, je pense qu'il me faudrait environ un mois, tout en travaillant sur d'autres choses également, pour me frayer un chemin à travers cela.

Désolé il n'y a pas de réponse plus définitive mais une telle réponse serait forcément un mensonge !

@CharliePoole y a-t-il une mise à jour compte tenu de cette fonctionnalité ?

@tomersss, nous n'avons pas encore commencé à travailler dessus et la version 3.5 sortira, espérons-le, dans quelques semaines, donc ce ne sera probablement pas dans la prochaine version. Nous aimerions voir cette fonctionnalité ajoutée bientôt, mais nous avons été assez occupés cette semaine à réorganiser nos référentiels et notre base de code. Il est cependant marqué comme une priorité élevée, il est donc sur notre radar.

@CharliePoole y a-t-il une mise à jour de ce problème ?

@KPKA, nous n'avons pas encore commencé à travailler là-dessus, il n'y a donc pas de mise à jour. Pour les utilisateurs avec ZenHub installé, vous verrez ce problème passer de Backlog à ToDo puis En cours au fur et à mesure que nous commençons à y travailler.

Pour les non-utilisateurs de Zenhub, vous pourrez savoir quand quelqu'un le récupère en regardant qui est affecté au problème.

@CharliePoole @rprouse

Salut!

Y a-t-il des nouvelles selon ce problème?
Que ce soit dans la prochaine version ou si c'est prévu dans l'une des prochaines étapes ?

Pour le moment, c'est le seul problème qui nous empêche de passer à NUnit.
Ce serait gentil si quelqu'un pouvait s'avouer de se mettre au travail dans un avenir proche car il y a beaucoup de personnes concernées, je suppose.

J'espère avoir de vos nouvelles bientôt

@GitSIPA quel framework de test utilisez-vous qui vous permet d'exécuter des méthodes de test en parallèle ?

Pour répondre à votre question, personne n'a commencé à travailler sur ce problème, il n'y a donc pas d'ETA, mais nous prendrons en compte votre vote pour décider sur quoi travailler ensuite.

+1, d'accord avec @GitSIPA. C'est une fonctionnalité vraiment importante

@GitSIPA +1
@rprouse Nous utilisons mbunit, mais ce framework ne prend pas en charge actuellement. Et nous avons quelques problèmes avec mbunit.

@rprouse Nous

Au sujet du numéro 1921, @jnm2 a demandé « Qu'est-ce qui nous sépare du fait que les cas de test paramétrés s'exécutent en parallèle ? Puis-je contribuer ? »

Deuxième question d'abord : Bien sûr ! Nous aimerions votre aide.

Et à la première question :

  1. Nous exécutons des « WorkItems », qui correspondent actuellement à des tests un à un. Je pense que nous devons traiter OneTimeSetUp et OneTimeTearDown pour un appareil comme des WorkItems distincts comme étape préliminaire. Le numéro #1096 traite de cela.

  2. Nous devons avoir un moyen de faire dépendre un WorkItem d'autres WorkItems, de sorte qu'il ne soit programmé pour s'exécuter que lorsque tous ceux qui dépendent des éléments sont terminés. Nous le faisons actuellement de manière très simpliste en utilisant un compte à rebours, mais nous avons besoin de quelque chose de plus général. La première utilisation de ceci, bien sûr, serait de faire dépendre OneTimeTearDown de l'achèvement de tous les tests. Il aurait d'autres utilisations plus tard, lorsque nous implémenterons la dépendance entre les tests. J'imagine cela comme une file d'attente d'éléments de travail en attente, mais il peut exister d'autres moyens de l'implémenter.

  3. Avec ces deux choses à l'écart, nous pourrions commencer à travailler sur le problème principal lui-même : planifier les tests à exécuter plutôt que de les exécuter sur le même thread qui a fait le OneTimeSetUp pour le luminaire.

Si vous souhaitez travailler là-dessus, vous devrez vous familiariser avec certains des éléments internes de la façon dont NUnit distribue réellement les tests pour l'exécution. Je serai ravi de vous aider à le faire.

Quelle planification a été faite jusqu'à présent?
Mes besoins sont d'exécuter suffisamment de cas TestCaseSource en parallèle pour saturer le processeur. Je n'ai aucune exigence d'installation, de démontage ou de commande. D'autres personnes auront besoin de ceux-ci pour être pris en compte.

Je m'attendrais à ce que l'exécution de TestCaseSource soit parallélisée, donc deux méthodes dans le même appareil qui utilisaient des TestCaseSources différents exécuteraient les énumérations en parallèle. Il semble également que ce serait bien si deux méthodes utilisaient le même TestCaseSource s'il n'était exécuté qu'une seule fois.

Edit : commenter CONDITION DE COURSE. On commence déjà bien ! ??

Je vais répéter une histoire que j'ai dû beaucoup raconter ces derniers temps. :le sourire:

NUnit charge d'abord les tests (c'est-à-dire découvre, explore), puis les exécute une ou plusieurs fois, selon le type de coureur.

Votre TestCaseSource est utilisé pour charger les tests, pas pour les exécuter, et nous ne le considérons même pas comme faisant partie de votre test - bien que vous puissiez l'avoir dans la même classe que votre test.

IOW, vos cas de test n'"utilisent" pas votre source de cas de test, NUnit utilise plutôt la source pour créer les cas de test. Bien sûr, ils ne peuvent rien faire tant qu'ils n'ont pas été créés. Avoir du sens ?

En l'occurrence, la création des tests à partir de la source se fait de manière séquentielle. Si vous avez du code en cours d'exécution dans la source qui en fait un problème, ma première supposition serait que vous en faites trop dans la source du cas de test. Par exemple, vous ne voulez pas créer d'instances de classes dans votre source de cas de test, vous voulez plutôt stocker les paramètres qui seront utilisés pour les créer. Malheureusement, cela pourrait être un chapitre entier de livre. :le sourire:

Ainsi, ce problème concerne __l'exécution__ des cas de test en parallèle. Cela signifie tous les cas de test sous un appareil, à moins que vous n'en marquiez certains comme non parallélisables. Les tests simples non paramétrés ainsi que les cas individuels d'un test paramétré seraient traités de la même manière.

Ce serait une expérience intéressante pour permettre la parallélisation des tests dans les appareils où il n'y a pas de OneTimeTearDown (je pense que OneTimeSetUp est OK). Cela pourrait fonctionner facilement si vous pouviez correctement prendre cette décision. La détermination est cependant plus difficile que vous ne le pensez, car OneTimeTearDown peut inclure à la fois des méthodes héritées et des ActionAttributes globaux.

@jnm2 Avez-vous déjà eu la chance de vous attaquer à ce problème spécifique ?

@julianhaslinger Non. C'est sur ma liste après mes deux numéros plus immédiats, 1885 et 1933. Si vous voulez vous y attaquer, tant mieux !

@julianhaslinger Puisque nous ne nous connaissons pas, veuillez m'excuser de dire que c'est une tâche difficile à affronter. Assurez-vous de bien comprendre comment les choses se passent maintenant et pourquoi - ce dernier point n'est pas toujours évident, j'en ai peur. Voir mon commentaire sur https://github.com/nuni/nunit/issues/164#issuecomment -265267804 pour une ventilation en PR distincts que j'aimerais voir afin de résoudre ce problème. Si vous proposez une approche plus simple, publiez-la avant de la coder, afin que nous puissions peser les considérations futures par rapport à l'évident YAGNI impliqué dans la prédiction de l'avenir.

@CharliePoole @jnm2 Salut les gars !

Ce n'est pas que je voulais commencer à implémenter cette fonctionnalité manquante, mais simplement connaître son évolution. Comme je peux le dire d'après vos réponses (ci-dessus), il n'y a eu aucun progrès (?) concernant cette demande de fonctionnalité particulière.

@CharliePoole L'un des problèmes potentiels que j'ai rencontrés lors de mes recherches sur le code était la façon dont les appareils sont gérés actuellement. Actuellement, tous les WorkItems ont accès à la même instance Fixture , ce qui signifie que si les WorkItems devaient être exécutés en parallèle, ils accéderaient à une seule instance de la classe de test. Ceci est problématique en raison des conditions de concurrence qu'il crée lorsque les tests reposent sur la configuration ou le démontage pour définir les champs au niveau de l'instance.

Une solution à cela serait de faire fonctionner chaque WorkItem sur une nouvelle instance de la classe de test, mais cela compliquera probablement le comportement des configurations de luminaire car il n'y aurait plus une seule instance de l'appareil.

@chris-smith-zocdoc Oui, c'est la plus grande différence entre NUnit et son prédécesseur junit. À l'époque, il a été largement discuté du pour et du contre, mais cela ne revient plus beaucoup maintenant. Pour cette raison, les tests NUnit étaient censés être sans état, toutes les initialisations étant effectuées dans la méthode SetUp.

Une fois TestFixtureSetUp (maintenant appelé OneTimeSetUp) introduit, il est devenu possible de faire une initialisation plus coûteuse une fois et de faire fonctionner tous les tests sur les mêmes valeurs initialisées. Ceci est particulièrement utile lors de la création d'instances des classes testées, qui peuvent elles-mêmes être avec état. Ces dernières années, de plus en plus d'utilisateurs ont profité de cette capacité.

Le sujet de l'ajout d'une option pour créer une instance distincte de l'appareil utilisateur par cas de test revient périodiquement. Jusqu'à présent, il n'a pas atteint le stade d'être une fonctionnalité planifiée. C'est certainement lié à la facilité d'utilisation d'une fonctionnalité de méthode parallèle de la part des utilisateurs, mais je pense que c'est orthogonal à la mise en œuvre. SI nous créions un nouveau projecteur par instance, nous exécuterions simplement une configuration "une fois" plus d'une fois. Bien sûr, cela frapperait durement tous les utilisateurs qui utilisent la statique. ??

Nous avons reporté les méthodes de test parallèles pour deux raisons : (1) elles sont difficiles à mettre en œuvre et (2) il semble que les appareils parallèles, bien que plus faciles pour nous, soient suffisants pour la plupart des utilisateurs. Très peu d'utilisateurs semblent partager l'état entre plusieurs appareils alors qu'il semble (sur la base des discussions en ligne) que de nombreux utilisateurs partagent l'état entre les méthodes de test. Jusqu'à présent, de nombreux utilisateurs tirent parti du parallélisme existant et, même si certains souhaitent vraiment le parallélisme des méthodes, ils semblent être un groupe relativement restreint.

Néanmoins, je suppose qu'il est temps de faire quelque chose. Je vais m'en occuper pour le premier trimestre, au moins dans la mesure où j'exécute certaines expériences et peut-être pour proposer une répartition judicieuse des tâches que d'autres peuvent suivre.

SI nous créions un nouveau projecteur par instance, nous exécuterions simplement une configuration "une fois" plus d'une fois. Bien sûr, cela frapperait durement tous les utilisateurs qui utilisent la statique.

Je pense qu'il est raisonnable d'exiger qu'il n'y ait pas d'état statique si vous choisissez de fonctionner en parallèle, dans la mesure où c'est de votre faute si quelque chose se brise pour avoir mélangé l'état statique et le parallélisme. Heureusement, tout votre code sera en cours de test, il devrait donc être difficile de le manquer 😆

Néanmoins, je suppose qu'il est temps de faire quelque chose. Je vais m'en occuper pour le premier trimestre, au moins dans la mesure où j'exécute certaines expériences et peut-être pour proposer une répartition judicieuse des tâches que d'autres peuvent suivre.

Comptez-moi pour ça.

Moi aussi!

Le sam. 14 janv. 2017 à 03h58, Joseph Musser [email protected]
a écrit:

>
>
>
>

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

Nettoyage automatique : conservez les 1 derniers e-mails ([email protected])

Modifier la règle
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_medium&utmUPCL_medium=emailign_utm

| Supprimer la règle
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_medium&utmUPCL_medium=emailign_utm

| Marquer important
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=48&camp

SI nous créions un nouveau projecteur par instance, nous lancerions simplement "un"
configuration de l'heure plus d'une fois. Bien sûr, cela frapperait durement tous les utilisateurs qui sont
en utilisant la statique.

Je pense qu'il est raisonnable d'exiger qu'il n'y ait pas d'état statique si vous
choisir de courir en parallèle, dans la mesure où c'est de votre faute si quelque chose
pauses pour mélanger état statique et parallélisme. Heureusement, tout ce code sera
être en cours de test donc il devrait être difficile de rater :D

Néanmoins, je suppose qu'il est temps de faire quelque chose. je vais prendre ça
pour le premier trimestre, au moins dans la mesure de l'exécution de certaines expériences
et éventuellement proposer une répartition judicieuse des tâches que d'autres peuvent
suivi.

Comptez-moi pour ça.

-
Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/nuni/nunit/issues/164#issuecomment-272488655 , ou couper le son
le fil
https://github.com/notifications/unsubscribe-auth/AAHNVlwVps8pQ93UIwZw6zY7TOyHO0a6ks5rR61EgaJpZM4CUZ8r
.

En exécutant quelques tests de chronométrage, j'ai découvert quelque chose d'intéressant. Il y a une ambiguïté dans l'appel des cas de test parallélisables. Cela peut également s'appliquer aux luminaires et autres suites, mais c'est moins évident.

Voici le problème : si une méthode est complètement non parallélisable, cela signifie qu'elle ne peut pas s'exécuter en parallèle avec __toute autre méthode__. OTOH, s'il n'est pas parallélisable uniquement dans son appareil, il ne peut pas s'exécuter en parallèle avec __ toute autre méthode dans le même appareil.__

Je propose que nous traitions cette distinction comme suit :

  1. Si une méthode de test n'a pas d'attribut Parallélisable, elle doit s'exécuter sur le même thread que son fixture conteneur, à condition qu'aucun autre attribut (par exemple Apartment) n'appelle pour qu'elle soit exécutée sur un thread différent

  2. S'il a un attribut Parallelizable avec une portée de Self, ou si une suite de niveau supérieur spécifie une portée de Children, alors la méthode de test est exécutée en parallèle avec les autres méthodes de l'appareil.

Réflexions @nunit/core-team ?

À gauche ci-dessus :

  1. S'il a un attribut Parallelizable avec une étendue de None, alors il s'exécute sur la file d'attente non parallèle.

@CharliePoole - vos trois points ont du sens, bien que je ne sois pas clair sur l'alternative que vous suggérez que nous ne fassions pas. Pourriez-vous clarifier ?

Nous traitons actuellement le fait de ne pas avoir d'attribut de la même manière que d'en avoir un avec ParallelScope.None. Cela les met en file d'attente sur la file d'attente non parallèle si j'active leur envoi et le test ralentit considérablement.

PR #2011 prend quelques mesures initiales pour implémenter cette fonctionnalité mais contient un #define qui force les cas de test à s'exécuter sur le thread de leur appareil contenant. Ce commentaire documente ce que je pense qu'il faut faire pour supprimer cette limitation.

Actuellement, le OneTimeTearDown d'un appareil s'exécute sur le thread qui a été utilisé pour terminer le dernier scénario de test exécuté. Si les cas de test s'exécutent en parallèle, nous ne pouvons pas prédire quel cas de test ce sera. Il peut s'agir d'un fil avec des caractéristiques différentes de celles requises pour le montage. Par exemple, si le dernier test à terminer s'exécute dans le STA, c'est ce qui sera utilisé pour exécuter le OneTimeTearDown, même si le OneTimeSetUp s'est exécuté dans un MTA. Dans de nombreux cas, cela pourrait ne poser aucun problème, mais dans certains cas, cela pourrait.

Cela peut également être un problème avec les appareils de niveau supérieur, mais l'introduction de cas de test parallèles signifie qu'il y aura beaucoup plus d'opportunités pour une incompatibilité qui provoque une erreur.

Ainsi, afin de garantir que le démontage du fixture a lieu sur le bon type de thread, nous ne pouvons plus l'exécuter sur le thread du dernier test à exécuter. Au lieu de cela, le répartiteur devra conserver des informations sur tous les démontages en attente et être averti pour exécuter ces démontages sur le fil approprié au bon moment. Déterminer comment faire cela est la phase de "conception" de cette fonctionnalité.

pour tous ceux qui suivent ce fil depuis le début (en 2014) et ne veulent pas ou ne peuvent pas implémenter leur propre solution de contournement en attendant cet ajout de fonctionnalité, je viens de tomber sur une implémentation utilisant NUnit 2.6.3 disponible sur CodePlex qui semble assez simple à utiliser (j'ai vérifié qu'il fonctionne lors de l'exécution de nos tests fonctionnels dans plusieurs threads parallèles).

http://cpntr.codeplex.com/

excuses d'avance @CharliePoole si ce message est un peu orthogonal aux discussions récentes sur ce fil, mais si quelqu'un d'autre attend depuis 3 ans cet ajout de fonctionnalité basé sur les promesses faites pour NUnit 3 (au début jours), je pense que cela pourrait offrir une solution jusqu'à ce que vous parveniez à résoudre les problèmes de conception (on dirait que vous vous rapprochez de la solution).

@CharliePoole

Ainsi, afin de garantir que le démontage du fixture a lieu sur le bon type de thread, nous ne pouvons plus l'exécuter sur le thread du dernier test à exécuter. Au lieu de cela, le répartiteur devra conserver des informations sur tous les démontages en attente et être averti pour exécuter ces démontages sur le fil approprié au bon moment. Déterminer comment faire cela est la phase de "conception" de cette fonctionnalité.

Avons-nous besoin que le répartiteur soit informé à l'avance des éléments en attente de démontage, ou pouvons-nous les expédier dès qu'ils deviennent disponibles ? Plus concrètement, là où CompositeWorkItem appelle actuellement PerformOneTimeTearDown, pouvons-nous utiliser le répartiteur pour

@chris-smith-zocdoc Oui, c'est exactement ce que je fais. J'ai créé un nouveau type d'élément de travail, OneTimeTearDownWorkItem , qui est imbriqué dans CompositeWorkItem et est distribué lorsque le dernier test enfant est exécuté. Plus tard, nous pourrions examiner certaines efficacités lorsque OneTimeSetUp et tous les tests ont été exécutés sur le même thread.

Je n'ai pas tout lu trop attentivement, mais une chose que je voudrais demander dans le cadre de cette fonctionnalité est que le parallélisme soit "intelligent", en particulier pour les tests liés aux E/S. Par exemple, si vous avez 10 threads exécutant 100 tests parallélisables, les 10 threads ne devraient pas attendre la fin des 10 premiers tests avant de passer aux 10 tests suivants. Si les 10 premiers tests commencent à attendre des tâches d'E/S de très longue durée, les threads devraient être libres de passer à d'autres tests. Une fois les tâches d'E/S terminées, les threads reprennent les tests en attente au fur et à mesure que les threads se libèrent.

Fondamentalement, je demande une gestion intelligente du débit pour les tests liés aux E/S qui utilisent largement async/wait. C'est de loin notre goulot d'étranglement numéro un dans les tests.

@chris-smith-zocdoc En fait, c'est à peu près ce que je fais. J'utilise essentiellement le mécanisme de compte à rebours existant pour déclencher l'envoi d'une tâche de démontage unique. L'astuce consiste à le faire envoyer dans la file d'attente appropriée.

@gzak Gardez à l'esprit que le mécanisme d'exécution parallèle existe déjà. Cela dépend des travailleurs qui tirent les tâches de manière indépendante plutôt que d'avoir un contrôleur qui pousse les tâches aux travailleurs. Ainsi, si un travailleur est occupé par une tâche pendant un certain temps, les autres travailleurs continueront à exécuter d'autres tâches de manière indépendante. L'astuce consiste à définir le nombre de travailleurs en fonction de la nature des tests en cours d'exécution. NUnit fonctionne assez bien par défaut avec les tests unitaires normaux liés au calcul, mais d'autres types de tests peuvent nécessiter que l'utilisateur définisse un niveau de parallélisme approprié.

Quelqu'un peut-il m'expliquer comment ça marche ?
j'ai un cours d'essai
Lorsque j'exécute les tests dans cette classe PAS en parallèle - tous les tests ont réussi
Mais quand je les lance avec [Parallelizable(ParallelScope.Children)]
Ils fonctionnent donc en parallèle (plusieurs méthodes dans la même classe)
mais pour une raison quelconque, certains tests échouent.
J'ai des champs d'instance dans cette classe qui sont utilisés dans les tests et il semble que ces champs soient partagés entre les threads
Ai-je raison?
Créez-vous une seule instance de cette classe et appelez-vous les méthodes simultanément sur cet objet unique ?
CharliePoole

Vous l'avez compris ! Oui, tous les tests d'un appareil utilisent la même instance. C'est historique avec NUnit, qui a toujours fonctionné de cette façon. Vous devez choisir entre exécuter les cas de test en parallèle et avoir un état modifié par test. Il n'y a aucun moyen de contourner cela actuellement.

Cela dit, si vous avez une proportion décente d'appareils, le simple fait de faire fonctionner des appareils en parallèle peut vous donner de bonnes performances.

Est-il possible d'avoir le [Parallelizable(ParallelScope.Children)] dans le
Fichier AssemblyInfo.cs ?

Est-ce que quelqu'un a vu ça fonctionner ?

Le 14 juin 2017 à 01h37, CharliePoole [email protected] a écrit :

[image : Boxbe] https://www.boxbe.com/overview Nettoyage automatique : garder
1 derniers e-mails ([email protected]) Modifier la règle
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
| Supprimer la règle
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
| Marquer important
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

Vous l'avez compris ! Oui, tous les tests d'un appareil utilisent la même instance.
C'est historique avec NUnit, qui a toujours fonctionné de cette façon. Vous devez
choisir entre exécuter les cas de test en parallèle et avoir n'importe quel état qui
est modifié par essai. Il n'y a aucun moyen de contourner cela actuellement.

Cela dit, si vous avez une proportion décente d'appareils, exécutez simplement
des montages en parallèle peuvent vous donner de bonnes performances.

-
Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/nuni/nunit/issues/164#issuecomment-308157832 , ou couper le son
le fil
https://github.com/notifications/unsubscribe-auth/AAHNVuK-J-X74mlAA_eT7OX7dxs7MpoRks5sDqzLgaJpZM4CUZ8r
.

@agray Oui, en fait, c'est la seule raison pour laquelle j'ai un AssemblyInfo.cs maintenant.

Salut Joseph,

Quelle ligne de parallélisme ajoutez-vous à votre fichier AssemblyInfo.cs ?

J'aimerais savoir ce qui fonctionne.

À votre santé,

André

Le mer. 14 juin 2017 à 16h17, Joseph Musser [email protected]
a écrit:

[image : Boxbe] https://www.boxbe.com/overview Nettoyage automatique : garder
1 derniers e-mails ([email protected]) Modifier la règle
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
| Supprimer la règle
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
| Marquer important
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 Oui, en fait c'est la seule raison pour laquelle je
avoir un AssemblyInfo.cs maintenant.

-
Vous recevez ceci parce que vous avez commenté.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/nuni/nunit/issues/164#issuecomment-308325726 , ou couper le son
le fil
https://github.com/notifications/unsubscribe-auth/AAHNVghNAX8CJkqAy-qhAz8bXNhZcFOQks5sD3NigaJpZM4CUZ8r
.

@agray Celui sur

c# [Parallelizable(ParallelScope.Children)]

n'oublie pas la cible

[assembly: Parallelizable(ParallelScope.Children)]

@LirazShay J'utilise NUnit pour conduire des tests Selenium et j'utilisais des champs au niveau de l'appareil pour contenir des éléments tels que des références aux comptes d'utilisateurs et à l'instance Selenium WebDriver avec laquelle je travaillais et je n'étais donc pas en mesure d'exécuter des tests en parallèle dans l'appareil. La façon dont j'ai contourné cela était d'écrire une "usine" (j'utilise des guillemets parce que je ne suis pas sûr que ce soit le bon terme) qui implémente IDisposable qui, pour chaque test, encapsule tous mes besoins de test et les démonte proprement à la fin du test sans avoir besoin de [TearDown] ou [OneTimeTearDown] un peu comme ceci:

 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;
    }
}

Ensuite, dans un test, je peux faire ceci:

[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
        }
    }
}

De cette façon, je peux éviter beaucoup de duplication de code, et si jamais j'ai besoin de changer les dépendances de mon test, je le fais juste une fois en usine. Si quelqu'un a des commentaires sur la stratégie que j'ai adoptée, je l'apprécierais !

@tparikka Je recommande fortement cette approche moi-même.

J'ai ce qui suit dans mon fichier AssemblyInfo :

[assemblage : Parallélisable(ParallelScope.Children)]
[assemblage : LevelOfParallelism(16)]

Ai-je également besoin de l'attribut LevelOfParallelism ?

Le 15 juin 2017 à 04h37, Joseph Musser [email protected] a écrit :

[image : Boxbe] https://www.boxbe.com/overview Nettoyage automatique : garder
1 derniers e-mails ([email protected]) Modifier la règle
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
| Supprimer la règle
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
| Marquer important
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 Je recommande fortement exactement cela
m'approcher.

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/nuni/nunit/issues/164#issuecomment-308521058 , ou couper le son
le fil
https://github.com/notifications/unsubscribe-auth/AAHNVmEzVDbw32Xx0jkYcGK9bZW3tLvXks5sECh8gaJpZM4CUZ8r
.

Je n'ai pas encore envisagé d'utiliser LevelOfParallelism . Il s'agit par défaut du nombre de cœurs que vous avez.

Si vos tests ne sont pas liés au processeur, une valeur plus élevée est logique. Mais comme toujours avec les performances, la réponse dépend tellement de votre scénario qu'il vaut mieux mesurer plutôt que deviner.

@CharliePoole J'utilise TestcaseSource , mais il semble que les cas de test résultants ne soient pas réellement exécutés en parallèle. Est-ce que quelque chose comme ça devrait fonctionner:

```c#
[Test Fixture]
désérialisation de classe
{
IEnumerable statique publicShouldDeserializeAllCases() => 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);
    }
}

```

Le temps total pris est de 10 secondes au lieu de ~2.

Je penserai qu'il n'y a pas d'enfants, donc dans ce cas, tu ferais mieux d'utiliser
[Parallélisable(ParallelScope.All)]
ou déplacez votre attribut au niveau de la classe.

@ParanoikCZE Merci. En fait, je vole à l'aveugle par rapport à la signification de cet attribut, j'ai donc essayé toutes les valeurs d'énumération là-dessus. Quel que soit le All , Children , Fixture ou Self que j'utilise, j'obtiens un temps d'exécution de 10 secondes (au moins dans Visual Studio).

J'ai juste essayé de le déplacer dans la classe, mais cela ne semble pas aider non plus.

Essayez ceci est une source d'inspiration :)

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 Merci encore. J'ai testé cela dans Visual Studio et la visualisation est beaucoup plus claire, mais les tests s'exécutent toujours de manière séquentielle. Plus facile à voir si vous utilisez un sommeil constant pour chaque test au lieu d'augmenter les étapes.

Essayez d'ajouter [assembly: LevelOfParallelism(5)] dans AssemblyInfo, je pense qu'il existe une valeur par défaut, mais peut-être que cela ne fonctionne pas pour vous d'une manière ou d'une autre. De toute façon, je suis à court d'idées. :)

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