Jak mogę równolegle przeprowadzać testy NUnit?

83

Mam duży pakiet testów akceptacyjnych (~ 10 sekund na test) napisany przy użyciu NUnit. Chciałbym wykorzystać fakt, że wszystkie moje maszyny mają wiele rdzeni. Idealnie byłbym w stanie uruchomić jeden test na rdzeń, niezależnie od innych testów.

Istnieje PNUnit, ale jest przeznaczony do testowania problemów z synchronizacją wątków i tym podobnych, a nie widziałem oczywistego sposobu, aby to osiągnąć.

Czy istnieje przełącznik / narzędzie / opcja, której mogę użyć do równoległego uruchamiania testów?

Billy ONeal
źródło
Nawet ja chciałbym wiedzieć więcej na ten temat. @Billy ONeal, napisz odpowiedź, jeśli ją znajdziesz.
PK
Mówisz dziesięć sekund na test, a najlepiej jeden test na rdzeń. Czy testy obciążają procesor? W przeciwnym razie powinno być możliwe jednoczesne działanie wielu innych.
Mattias Nilsson
@Mattias: Tak, testy intensywnie wykorzystują procesor.
Billy ONeal

Odpowiedzi:

52

Jeśli chcesz uruchomić testy NUnit równolegle, są co najmniej 2 opcje:

  • NCrunch oferuje to po wyjęciu z pudełka (bez zmian, ale jest produktem komercyjnym)
  • NUnit 3 oferuje atrybut Parallelizable , którego można użyć do określenia, które testy mogą być uruchamiane równolegle
David_001
źródło
Ta odpowiedź wydaje się błędna, biorąc pod uwagę pytanie, jest bardziej dobrą sugestią niż prawdziwą odpowiedzią. Moim zdaniem NCrunch potrzebuje twoich pozytywnych głosów i powinien być najlepszą odpowiedzią, ponieważ może uruchamiać testy (NUnit) jednocześnie w ramach tego samego lub wielu procesów i na jednej lub wielu maszynach i zrobi to z VS lub z serwera kompilacji.
chillitom
2
@chillitom NCrunch został wydany po udzieleniu odpowiedzi na to pytanie i jest dobrym wyborem (ponieważ powinno to działać po wyjęciu z pudełka, chociaż dla niektórych jest zbyt drogie). Inne opcje w przyszłości mogą obejmować NUnit 3, który może oferować równoległe uruchamianie testów (zgodnie z github.com/nunit/dev/wiki/Roadmap ).
David_001
3
Chociaż jest to najlepsza odpowiedź, nie jest już tak poprawna, jak kiedyś. Nunit 3.0 został wydany pod koniec 2015 roku i ma teraz atrybut Parallelizable. Ref: github.com/nunit/nunit/wiki/Parallelizable-Attribute
pb.
36

NUnit w wersji 3 będzie obsługiwał równoległe uruchamianie testów:

Dodanie atrybutu do klasy: [Parallelizable(ParallelScope.Self)]uruchomi twoje testy równolegle.

• ParallelScope.None oznacza, że ​​testu nie można uruchomić równolegle z innymi testami.

• ParallelScope.Self wskazuje, że sam test można uruchomić równolegle z innymi testami.

• ParallelScope.Children wskazuje, że potomkowie testu mogą być przeprowadzani równolegle względem siebie.

• ParallelScope.Fixtures wskazuje, że urządzenia mogą działać równolegle ze sobą.

NUnit Framework-Parallel-Test-Execution

Piotr
źródło
10

Jeśli projekt zawiera wiele testowych bibliotek DLL, możesz uruchomić je równolegle przy użyciu tego skryptu MSBuild. Oczywiście musisz dostosować ścieżki do układu projektu.

Aby pracować z 8 rdzeniami, uruchom z: 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>

Aktualizacja Gdybym teraz odpowiedział na to pytanie, gorąco poleciłbym NCrunch i jego narzędzie do uruchamiania testów z wiersza poleceń, aby uzyskać maksymalną wydajność testu. Nie ma nic podobnego, a jednocześnie zrewolucjonizuje cykl testowania kodu i debugowania.

chillitom
źródło
1
Pomogło mi to skrócić czas wykonywania testów jednostkowych z 3 minut do 2 minut. Testowałem na 2-rdzeniowym procesorze.
Dmitrii Lobanov,
4

W tym artykule wspomniano, że w celu przyspieszenia testów plakat uruchamia wiele instancji NUnit z parametrami poleceń określającymi, które testy powinny zostać uruchomione w każdej instancji.

FTA:

Napotkałem dziwny problem.

Używamy nunit-console do uruchamiania testów na naszym serwerze ciągłej integracji. Ostatnio przechodziliśmy z Nunit 2.4.8 na 2.5.5 iz .Net 3.5 na 4.0. Aby przyspieszyć wykonywanie testów, uruchamiamy wiele instancji Nunit równolegle z różnymi argumentami wiersza poleceń

  • Mamy dwie kopie naszych zestawów testowych i plików binarnych nunit w folderze A i B.
  • W folderze A wykonujemy

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

  • W folderze B wykonujemy

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

Jeśli wykonamy polecenia w kolejności, oba działają pomyślnie. Ale jeśli wykonamy je równolegle, tylko jeden się powiedzie. O ile wiem, to ten, który jako pierwszy ładuje urządzenia testowe. Drugi kończy się niepowodzeniem z komunikatem „Nie można zlokalizować urządzenia”.

Czy ten problem jest już znany? Nie udało mi się znaleźć niczego związanego na liście błędów na launchpadzie. BTW Na naszym serwerze działa 64-bitowy system Windows Server 2008. Mogłem również odtworzyć problem w 64-bitowym systemie Windows 7.

Zakładając, że błąd został naprawiony lub nie używasz nowszych wersji wspomnianego oprogramowania, powinieneś być w stanie odtworzyć ich technikę.

Aktualizacja

TeamCity wygląda jak narzędzie, którego możesz użyć do automatycznego uruchamiania testów NUnit. Mają omówiony tutaj program uruchamiający NUnit , którego można użyć do uruchomienia wielu instancji NUnit. Oto post na blogu omawiający łączenie wielu wyników NUnit XML w jeden plik wynikowy.

Teoretycznie więc TeamCity może automatycznie uruchamiać wiele testów NUnit w zależności od tego, jak chcesz podzielić obciążenie, a następnie połączyć wyniki w jeden plik do przetworzenia po teście.

Czy to wystarczająco zautomatyzowane dla Twoich potrzeb?

kniemczak
źródło
To jest ten sam pomysł, który już opublikowałem o kategoriach ... Nie chcę utrzymywać w miarę równych czasów wykonywania między instancjami tutaj. Wolałbym napisać własnego biegacza NUnit, zanim to zrobię.
Billy ONeal
O ile wiem, NUnit nie obsługuje tego bez obejścia, takiego jak uruchomienie wielu instancji. Jeśli chcesz, myślę, że możesz stworzyć narzędzie, które podzieli testy na N zestawów i automatycznie uruchomi N wystąpień NUnit, gdzie N to liczba posiadanych procesorów / rdzeni. Byłby to jedyny sposób na automatyczne testowanie równoległe, o którym mogę pomyśleć w NUnit.
kniemczak
Dodałem aktualizację omawiającą narzędzie do ciągłej integracji TeamCity i zamieściłem kilka postów o tym, jak używać tego narzędzia do rozwiązywania Twoich potrzeb w zakresie automatyzacji.
kniemczak
3

To, że PNUnit może przeprowadzać synchronizację wewnątrz kodu testowego, nie oznacza, że ​​faktycznie musisz używać tego aspektu. O ile widzę, nic nie stoi na przeszkodzie, aby po prostu odrodzić zestaw i zignorować resztę, dopóki jej nie potrzebujesz.

Przy okazji, nie mam czasu, aby przeczytać wszystkie ich źródła, ale byłem ciekawy, aby sprawdzić klasę Barrier i jest to bardzo prosty licznik blokad. Po prostu czeka, aż N wątków wejdzie, a następnie wysyła impuls, aby wszystkie z nich kontynuowały pracę w tym samym czasie. To wszystko - jeśli go nie dotkniesz, nie ugryzie cię.

Może to być nieco sprzeczne z intuicją dla normalnego rozwoju wątków (zamki są zwykle używane do serializacji dostępu - 1 na 1), ale jest to dość porywająca gra :-)

ZXX
źródło
3

Możesz teraz używać NCrunch do zrównoleglenia testów jednostkowych, a nawet możesz skonfigurować, ile rdzeni ma być używanych przez NCrunch, a ile ma być używanych przez Visual Studio.

dodatkowo jako bonus otrzymujesz ciągłe testowanie :)

Rickard
źródło
3
NCrunch jest świetny, gdy używasz go w programie Visual Studio, ale nie pomaga, gdy próbujesz zrównoleglać testy na serwerze kompilacji.
Paccc,
3
NCrunch ma teraz dostępne narzędzie wiersza poleceń, które działa naprawdę dobrze na serwerach kompilacji.
chillitom
3

Jako alternatywa dla dodania atrybutu Parallelizable do każdej klasy testowej:

Dodaj to do klasy AssemblyInfo.cs projektu testowego dla nunit3 lub nowszego:

// Make all tests in the test assembly run in parallel
[assembly: Parallelizable(ParallelScope.Fixtures)]
tom redfern
źródło
2

Byłby to trochę hack, ale można podzielić testy jednostkowe na kilka kategorii . Następnie uruchom nową instancję NUnit dla każdej kategorii.

Edycja: wygląda na to, że dodali opcję / process do aplikacji konsoli. Pomoc wiersza poleceń podaje, że jest to „Model procesu dla testów: pojedynczy, oddzielny, wielokrotny”. Wydaje się, że biegacz testowy również ma tę funkcję.

Edycja 2: Niestety, chociaż tworzy oddzielne procesy dla każdego zestawu, opcja izolacji procesu (/ proces z wiersza poleceń) uruchamia agentów pojedynczo.

Pedro
źródło
2

Ponieważ projekt nie został tutaj wymieniony, chciałbym przywołać NUnit.Multicore . Sam nie próbowałem tego projektu, ale wydaje się, że ma on interesujące podejście do problemu z testami równoległymi w NUnit.

tronda
źródło
2

Możesz wypróbować moje małe narzędzie TBox lub konsolę równoległą Runner lub nawet wtyczkę do wykonywania obliczeń rozproszonych, która również może uruchamiać testy jednostkowe na zestawie komputerów PC SkyNet

TBox został stworzony, aby uprościć pracę z dużymi rozwiązaniami, które zawierają wiele projektów. Obsługuje wiele wtyczek, a jedna z nich zapewnia możliwość równoległego uruchamiania testów NUnit. Ta wtyczka nie wymaga żadnych zmian w istniejących testach.

Obsługuje również:

  • Klonowanie folderu za pomocą testu jednostkowego (jeśli Twoje testy zmieniają dane lokalne),

  • Synchronizacje testów (na przykład jeśli twoje testy na testfixtureteardown zabijają wszystkie serwery deweloperskie lub chromerunner dla qunit)

  • Tryb x86 i uprawnienia administratora do uruchamiania testów

  • Uruchomienie wsadowe - można równolegle uruchamiać testy dla wielu zestawów

  • Nawet w przypadku pojedynczego wątku działa szybciej niż standardowy biegacz nunit, jeśli masz dużo małych testów.

To narzędzie obsługuje również program uruchamiający testy z wiersza poleceń (do uruchamiania równoległego) i można go używać z ciągłą integracją.

Alex H.
źródło
Jeśli jesteś powiązany z tym produktem, ujawnij to. Wysłałeś wiele rzeczy, które na to wskazują.
Brad Larson
Jasne, TBox - to moje własne narzędzie. Napisałem to sam w wolnym czasie. Jeśli mówienie o darmowych narzędziach jest złą praktyką, usunę tę odpowiedź, nie ma problemu :)
Alex H
Chcemy tylko, aby ludzie mieli jasność co do produktów, z którymi są związani. Jeśli w pełni ujawnisz, że jest twój, dlaczego warto byłoby rozwiązać problem, który stawia pytanie, i nie promujesz go zbyt agresywnie, twoje odpowiedzi powinny być tutaj do zaakceptowania.
Brad Larson
@brad To open source na Codeplex, nie jestem pewien, dlaczego jest tu problem.
dvallejo
@DanVallejo - Bycie projektem open source jest powodem, dla którego społeczność nie usunęła tego po wysłaniu. Dajemy trochę więcej swobody, ale nadal prosimy, abyś ujawnił swoje powiązania z projektem, aby ludzie mogli zrozumieć kontekst Twojej rekomendacji. Alex zrobił to tutaj, więc jego odpowiedź jest w porządku w obecnej formie.
Brad Larson
1

Z powodzeniem korzystałem z NUnit 3.0.0 beta-4 do równoległego uruchamiania testów

  • Działa na serwerze kompilacji
  • Uruchamia testy selenu
  • Obsługuje Visual Studio
  • nie ma jeszcze wsparcia dla Resharper

Dzięki za odpowiedź rówieśników .

Problemy:

  • Atrybut z możliwością równoległości nie jest dziedziczony, więc musi być określony w klasie testowej.
Alvis
źródło
1
NUnit 3.0 jest już dostępny
Ralph Willgoss
0

Możesz użyć następującego polecenia PowerShell (dla NUnit3, dla NUnit2 zmień nazwę runnera):

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

Przedstawione polecenie uruchamia wszystkie zestawy testowe w jednej instancji nunit, co pozwala na wykorzystanie wbudowanego w silnik równoległego przebiegu testowego .

Uwagi

  1. Pamiętaj, aby dostosować wzorzec wyszukiwania w katalogu. Podany przykład uruchamia tylko zestawy kończące się na .Tests.dlli wewnątrz \bin\Debugkatalogów.

  2. Uważaj na Uniquefiltrowanie - możesz nie chcieć go mieć.

one_mile_run
źródło