web-dev-qa-db-fra.com

Comment puis-je exécuter des tests NUnit en parallèle?

J'ai une grande suite de tests de test d'acceptation (~ 10 secondes par test) écrite en utilisant NUnit. Je voudrais profiter du fait que mes machines sont toutes des boîtiers à noyaux multiples. Idéalement, je serais en mesure d'avoir un test en cours d'exécution par cœur, indépendamment des autres tests.

Il y a PNUnit, mais il est conçu pour tester les problèmes de synchronisation des threads et des choses comme ça, et je n'ai pas vu de moyen évident d'y parvenir.

Existe-t-il un commutateur/outil/option que je peux utiliser pour exécuter les tests en parallèle?

76
Billy ONeal

Le runner standard d'unité ne prend pas en charge l'exécution de tests en parallèle. Vous pouvez créer votre propre lanceur de test pour exécuter les tests en parallèle (en utilisant vos tests de nunit actuels). Je ne sais pas pourquoi l'équipe des nunités ne l'a pas déjà fait.

Alternativement, MBUnit a la possibilité de créer des tests parallélisables, et comme MBUnit a à peu près la même syntaxe que NUnit, cela pourrait ne pas prendre beaucoup d'efforts pour effectuer le changement.

EDIT: Comme indiqué dans les commentaires, bien que cette réponse soit correcte au moment de la rédaction, si vous souhaitez exécuter des tests NUnit en parallèle maintenant, il y a au moins 2 options:

  • NCrunch le propose hors de la boîte (sans rien changer, mais c'est un produit commercial)
  • NUnit 3 offre un attribut parallélisable, qui peut être utilisé pour indiquer quels tests peuvent être exécutés en parallèle
47
David_001

NUnit version 3 prendra en charge l'exécution de tests en parallèle:

L'ajout de l'attribut à une classe: [Parallelizable(ParallelScope.Self)] exécutera vos tests en parallèle.

• ParallelScope.None indique que le test ne peut pas être exécuté en parallèle avec d'autres tests.

• ParallelScope.Self indique que le test lui-même peut être exécuté en parallèle avec d'autres tests.

• ParallelScope.Children indique que les descendants du test peuvent être exécutés en parallèle les uns par rapport aux autres.

• ParallelScope.Fixtures indique que les appareils peuvent être exécutés en parallèle les uns avec les autres.

NUnit Framework-Parallel-Test-Execution

33
Peter

Si votre projet contient plusieurs DLL de test, vous pouvez les exécuter en parallèle à l'aide de ce script MSBuild. De toute évidence, vous devrez modifier les chemins en fonction de la disposition de votre projet.

Pour exécuter avec 8 cœurs, exécutez avec: c:\proj> msbuild /m:8 RunTests.xml

RunTests.xml

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="RunTestsInParallel" xmlns="http://schemas.Microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration>
    <Nunit Condition=" '$(Nunit)' == '' ">$(MSBuildProjectDirectory)\..\tools\nunit-console-x86.exe</Nunit>
  </PropertyGroup>

  <!-- see http://mikefourie.wordpress.com/2010/12/04/running-targets-in-parallel-in-msbuild/ -->

  <Target Name="RunTestsInParallel">
    <ItemGroup> 
      <TestDlls Include="..\bin\Tests\$(Configuration)\*.Tests.dll" />
    </ItemGroup>

    <ItemGroup> 
      <TempProjects Include="$(MSBuildProjectFile)" > 
        <Properties>TestDllFile=%(TestDlls.FullPath)</Properties> 
      </TempProjects> 
    </ItemGroup> 

    <MSBuild Projects="@(TempProjects)" BuildInParallel="true" Targets="RunOneTestDll" /> 
  </Target>

  <Target Name="RunOneTestDll"> 
    <Message Text="$(TestDllFile)" />
    <Exec Command="$(Nunit) /exclude=Integration $(TestDllFile)  /labels /xml:$(TestDllFile).results.xml"
      WorkingDirectory="$(MSBuildProjectDirectory)\..\bin\Tests\$(Configuration)" /> 
  </Target>

</Project>

Mise à jour Si je répondais à cette question maintenant, je recommanderais fortement NCrunch et son outil de test en ligne de commande pour des performances de test maximales . Il n'y a rien de tel et cela révolutionnera en même temps votre cycle de débogage de test de code.

10
chillitom

Dans cet article , il est mentionné que pour accélérer les tests, le poster exécute plusieurs instances de NUnit avec des paramètres de commande spécifiant les tests que chaque instance doit exécuter.

ALE:

J'ai rencontré un problème étrange.

Nous utilisons nunit-console pour exécuter des tests sur notre serveur d'intégration continue. Récemment, nous passions de Nunit 2.4.8 à 2.5.5 et de .Net 3.5 à 4.0. Pour accélérer l'exécution des tests, nous exécutons plusieurs instances de Nunit en parallèle avec différents arguments de ligne de commande

  • Nous avons deux copies de nos assemblys de test et des binaires d'unité dans les dossiers A et B.
  • Dans le dossier A, nous exécutons

nunit-console-x86.exe Model.dll Test.dll/exclude: MyCategory /xml=TestResults.xml /framework=net-4.0/noshadow

  • Dans le dossier B, nous exécutons

nunit-console-x86.exe Model.dll Test.dll/include: MyCategory /xml=TestResults.xml /framework=net-4.0/noshadow

Si nous exécutons les commandes en séquence, les deux s'exécutent avec succès. Mais si nous les exécutons en parallèle, un seul réussit. Pour autant que je sache, c'est celui qui charge d'abord les appareils de test. L'autre échoue avec le message "Impossible de localiser le luminaire".

Ce problème est-il déjà connu? Je n'ai rien trouvé de similaire dans la liste des bogues sur le tableau de bord. BTW Notre serveur exécute Windows Server 2008 64 bits. Je pourrais également reproduire le problème sur Windows 7 64 bits.

En supposant que ce bogue est corrigé ou que vous n'exécutez pas la ou les versions les plus récentes du logiciel mentionné, vous devriez pouvoir reproduire leur technique.

Mise à jour

TeamCity ressemble à un outil que vous pouvez utiliser pour exécuter automatiquement les tests NUnit. Ils ont un lanceur NUnit discuté ici qui pourrait être utilisé pour lancer plusieurs instances NUnit. ici est un article de blog traitant de la fusion de plusieurs résultats NUnit XML en un seul fichier de résultats.

Donc, théoriquement, TeamCity pourrait lancer automatiquement plusieurs tests NUnit en fonction de la façon dont vous souhaitez fractionner la charge de travail, puis fusionner les résultats en un seul fichier pour le traitement post-test.

Est-ce suffisamment automatisé pour vos besoins?

4
kniemczak

Ce n'est pas parce que PNUnit peut effectuer la synchronisation dans le code de test que vous devez réellement utiliser cet aspect. Pour autant que je sache, rien ne vous empêche de créer un ensemble et d'ignorer le reste jusqu'à ce que vous en ayez besoin.

BTW Je n'ai pas le temps de lire toute leur source mais j'étais curieux de vérifier la classe Barrière et c'est un compteur de serrure très simple. Il attend juste que N threads entrent, puis envoie l'impulsion pour que tous continuent à fonctionner en même temps. C'est tout ce qu'il y a à faire - si vous ne le touchez pas, il ne vous mordra pas.

Peut être un peu contre-intuitif pour un développement fileté normal (les verrous sont normalement utilisés pour sérialiser l'accès - 1 par 1) mais c'est une diversion assez animée :-)

3
ZXX

Vous pouvez maintenant utiliser NCrunch pour paralléliser vos tests unitaires et vous pouvez même configurer le nombre de cœurs à utiliser par NCrunch et le nombre à utiliser par Visual Studio.

en plus, vous obtenez des tests continus en bonus :)

3
Rickard

Étant donné que le projet n'a pas été mentionné ici, je voudrais faire apparaître NUnit.Multicore . Je n'ai pas essayé le projet moi-même, mais il semble avoir une approche intéressante du problème de test parallèle avec NUnit.

2
tronda

Ce serait un peu un hack, mais vous pouvez diviser les tests unitaires en un certain nombre de catégories . Ensuite, démarrez une nouvelle instance de NUnit pour chaque catégorie.

Modifier: il semble qu'ils aient ajouté une option/process à l'application console. L'aide en ligne de commande indique qu'il s'agit du "modèle de processus pour les tests: simple, séparé, multiple". Le lanceur de test semble également avoir cette fonctionnalité.

Édition 2: Malheureusement, bien qu'elle crée des processus distincts pour chaque assembly, l'option d'isolation des processus (/ process à partir de la ligne de commande) exécute les agents un par un.

2
Pedro

Vous pouvez essayer mon petit outil TBox ou parallèle console Runner ou même un plugin pour faire des calculs distribués, qui peuvent également exécuter des tests unitaires sur l'ensemble des PC SkyNet

TBox est créé pour simplifier le travail avec de grandes solutions, qui contient de nombreux projets. Il prend en charge de nombreux plugins et l'un d'eux offre la possibilité d'exécuter des tests NUnit en parallèle. Ce plugin ne nécessite aucune modification de vos tests existants.

Il prend également en charge:

  • Clonage du dossier avec test unitaire (si vos tests modifient les données locales),

  • Synchronisations des tests (par exemple si vos tests sur testfixtureteardown tuent tous les serveurs de développement ou chromerunner pour qunit)

  • mode x86 et privilèges d'administrateur pour exécuter des tests

  • Exécution par lots - vous pouvez exécuter des tests pour de nombreux assemblages en parallèle

  • Même pour une exécution à un seul thread, fonctionne plus rapidement que runner nunit standard, si vous avez beaucoup de petits tests.

Cet outil prend également en charge le testeur de ligne de commande (pour une exécution parallèle) et vous pouvez l'utiliser avec une intégration continue.

2
Alex H
1
Sjoerd

J'ai utilisé avec succès NUnit 3.0.0 beta-4 pour exécuter des tests en parallèle

  • Fonctionne sur le serveur de build
  • Exécute les tests de sélénium
  • Compatible avec Visual Studio
  • pas encore de support Resharper

Merci pour réponse des pairs .

Gotchas:

  • L'attribut parallélisable n'est pas hérité, il doit donc être spécifié dans la classe de test.
1
Alvis

Comme alternative à l'ajout de l'attribut Parallelizable à chaque classe de test:

Ajoutez ceci dans la classe AssemblyInfo.cs du projet de test pour nunit3 ou plus:

// Make all tests in the test Assembly run in parallel
[Assembly: Parallelizable(ParallelScope.Fixtures)]
0
tom redfern

Vous pouvez utiliser la commande PowerShell suivante (pour NUnit3, pour NUnit2 change runner name):

PS> nunit3-console (ls -r *\bin\Debug\*.Tests.dll | % FullName | sort-object -Unique)

La commande présentée exécute tous les assemblys de test dans une seule instance de nunit, ce qui permet de tirer parti du moteur exécution de test parallèle intégrée .

Remarques

  1. N'oubliez pas de modifier le modèle de recherche de répertoire. L'exemple donné exécute uniquement les assemblys se terminant par .Tests.dll et à l'intérieur \bin\Debug répertoires.

  2. Soyez conscient du filtrage Unique - vous ne voudrez peut-être pas l'avoir.

0
one_mile_run