Jak przeprowadzić testy NUnit z Jenkins?

108

Chcę uruchomić zautomatyzowane testy NUnit dla aplikacji C #, co noc i przy każdym zatwierdzeniu do svn.

Czy to jest coś, co może zrobić Jenkins-CI?
Czy istnieje samouczek online lub dokumentacja, która dokumentuje podobną konfigurację, którą mogę obejrzeć?

Blueberryfields
źródło
czy jest coś jeszcze, czego szukasz?
jglouie
1
Szukam samouczka lub dokumentu instruktażowego z podobną konfiguracją.
blueberryfields
1
Czy masz NUnit, który uruchamia testy, jak chcesz, z wiersza poleceń? Jeśli nie, to krok 1
jglouie

Odpowiedzi:

120

Musiałem zrobić dokładnie to, co robisz, oto jak skonfigurowałem Jenkins, aby to zrobić:

  1. Dodaj wtyczkę NUnit do Jenkins
  2. W swoim projekcie przejdź do Configure -> Build -> Add a build step
  3. W menu przewiń w dół do -> Wykonaj polecenie wsadowe systemu Windows
  4. Upewnij się, że ten krok jest umieszczony po kroku MSBuild
  5. Dodaj następujące elementy, zastępując zmienne:

Pojedynczy test DLL:

[PathToNUnit] \ bin \ nunit-console.exe [PathToTestDll] \ Selenium.Tests.dll /xml=nunit-result.xml

Test wielu bibliotek dll przy użyciu projektów testowych NUnit :

[PathToNUnit] \ bin \ nunit-console.exe [PathToTests] \ Selenium.Tests.nunit /xml=nunit-result.xml

  1. W obszarze Działania po kompilacji zaznacz opcję Publikuj raport wyników testu NUnit
  2. W polu tekstowym Pliki XML raportu testowego wprowadź nunit-result.xml

Po zbudowaniu projektu NUNit będzie teraz działał, a wyniki będą widoczne na pulpicie nawigacyjnym (jeśli najedziesz kursorem na ikonę raportu o pogodzie) lub na stronie projektu w sekcji Wynik ostatniego testu .

Możesz również uruchomić polecenie z poziomu programu Visual Studio lub w ramach lokalnego procesu kompilacji.

Oto dwa posty na blogu, których użyłem w celach informacyjnych. Nie znalazłem żadnego, który dokładnie pasowałby do moich wymagań:
1-godzinny przewodnik po konfiguracji ciągłej integracji: Jenkins spełnia .Net (2011)
Przewodnik po tworzeniu projektów .NET przy użyciu Hudson (2008)

Ralph Willgoss
źródło
Naprawdę nie rozumiem, czy to wystarczy. Czy posiadanie tylko jednej (lub kilku) testowych bibliotek DLL jest normalne? Mamy ich mnóstwo i często są tworzone i usuwane. Czy nie powinien istnieć sposób na zrobienie tego bez konieczności twardego kodowania testu w Jenkinsie?
André C. Andersen
Wskaż krok kompilacji, aby użyć pliku .bat lub .cmd pod kontrolą źródła, co spowoduje uruchomienie polecenia NUnit. Teraz możesz modyfikować testy, które będą uruchamiane tak często, jak chcesz, bez zmiany Jenkinsa. Powinieneś również przyjrzeć się projektom testowym NUnit, ponieważ może to również pomóc. Kluczem jest wskazanie Jenkinsowi, którego pliku XML użyć w raporcie z testu.
Ralph Willgoss,
4
po prostu użyj pliku * .nunit jako parametru zamiast pliku DLL, np "C:\Program Files (x86)\NUnit 2.6.3\bin\nunit-console-x86.exe" UnitTests/UnitTests.nunit. U mnie zadziałało idealnie.
JCH2k
3
Możesz użyć pliku * .sln zamiast biblioteki DLL. Zobacz dokumentację
Martin
2
Ahhh. Mój błąd logiczny polegał na tym, że wtyczka NUnit utworzyła nowy typ „Build-Task”. Jego magiczne voodoo to wydarzenie post-Build. (I po prostu używa się zwykłego wiersza poleceń do generowania .xml)
granadaCoder
16

Jeśli nie chcesz na stałe zakodować projektów testów jednostkowych, lepiej napisać skrypt, który pobierze wszystkie biblioteki DLL projektu testów jednostkowych. Robimy to za pomocą programu PowerShell i przestrzegamy określonej konwencji nazywania naszych projektów testów jednostkowych. Oto zawartość pliku PowerShell, który uruchamia nasze testy jednostkowe:

param(
[string] $sourceDirectory = $env:WORKSPACE
, $fileFilters = @("*.UnitTests.dll", "*_UnitTests.dll", "*UnitTests.dll")
, [string]$filterText = "*\bin\Debug*"
)

#script that executes all unit tests available.
$nUnitLog = Join-Path $sourceDirectory "UnitTestResults.txt"
$nUnitErrorLog = Join-Path $sourceDirectory "UnitTestErrors.txt"

Write-Host "Source: $sourceDirectory"
Write-Host "NUnit Results: $nUnitLog"
Write-Host "NUnit Error Log: $nUnitErrorLog"
Write-Host "File Filters: $fileFilters"
Write-Host "Filter Text: $filterText"

$cFiles = ""
$nUnitExecutable = "C:\Program Files (x86)\NUnit 2.6.3\bin\nunit-console-x86.exe"

# look through all subdirectories of the source folder and get any unit test assemblies. To avoid duplicates, only use the assemblies in the Debug folder
[array]$files = get-childitem $sourceDirectory -include $fileFilters -recurse | select -expand FullName | where {$_ -like $filterText}

foreach ($file in $files)
{
    $cFiles = $cFiles + $file + " "
}

# set all arguments and execute the unit console
$argumentList = @("$cFiles", "/framework:net-4.5", "/xml=UnitTestResults.xml")

$unitTestProcess = start-process -filepath $nUnitExecutable -argumentlist $argumentList -wait -nonewwindow -passthru -RedirectStandardOutput $nUnitLog -RedirectStandardError $nUnitErrorLog

if ($unitTestProcess.ExitCode -ne 0)
{
    "Unit Test Process Exit Code: " + $unitTestProcess.ExitCode
    "See $nUnitLog for more information or $nUnitErrorLog for any possible errors."
    "Errors from NUnit Log File ($nUnitLog):"
    Get-Content $nUnitLog | Write-Host
}

$exitCode = $unitTestProcess.ExitCode

exit $exitCode

Skrypt jest na tyle solidny, że używamy go ponownie do wszystkich naszych zadań kompilacji. Jeśli nie podoba ci się pełna ścieżka do konsoli NUnit, zawsze możesz umieścić tę lokalizację w zmiennej środowiskowej PATH.

Następnie umieszczamy plik RunUnitTests.ps1 na naszym serwerze kompilacji i używamy tego polecenia wsadowego:

powershell.exe -file "{full-path-to-script-direcory}\RunUnitTests.ps1"
Daniel McQuiston
źródło
działało dobrze, ale miałem dwa problemy. najpierw był katalog źródłowy. Musiałem zmienić katalog źródłowy na [string] $sourceDirectory = $(get-location)i dla ścieżek ze spacjami, musiałem zmienić przepustkę montażową na nUnit na$cFiles = $cFiles + '"' + $file + '"' + " "
Choco Smith
Jeśli mamy Test, który wykonujemy przez Test Playlist. Czy możemy wykonać tę testową listę odtwarzania dla Jenkinsa, używając .dll?
Ishita Shah
15

Do prac rolniczych Nunit 3 lub nowszych:

  1. Krok budowy (wiersz poleceń systemu Windows) "c:\Program Files (x86)\NUnit.org\nunit-console\nunit3-console.exe" c:\AutomationTraining\CSharpSelenium\bin\Debug\test.dll --result=TestR.xml;format=nunit2

  2. Krok po opublikowaniu raportu Nunit, pokazuje tylko plik wyników testu w katalogu obszaru roboczego Jenkins, a nie w Twoim projekcie: TestR.xml

Musimy zrobić wyniki testów w formacie nunit2, ponieważ teraz wtyczka Jenkins Nunit nie rozpoznaje formatu wyników Nunit3. Również format ciągu opcji jest inny: --result=TestR.xml;format=nunit2 NIE /xml=nunit-result.xml

Winston33
źródło
8

Działa to ładnie, już to ustawiłem.

Skonfiguruj NUnit, aby wyprowadzał wyniki do pliku XML i skonfiguruj wtyczkę NUnit Jenkins, aby używała tego pliku XML. Wyniki będą dostępne na pulpicie nawigacyjnym.

Teraz, jak wywołasz NUnit, zależy od Ciebie. Sposób, w jaki to zrobiliśmy, był następujący: zadanie Jenkinsa wykonuje zadanie NAnt target wykonuje zestaw testów NUnit.

Możesz skonfigurować zadania Jenkinsa, aby były uruchamiane po zatwierdzeniu i / lub zaplanowane w określonym czasie.

jglouie
źródło
To jest prawie to, do czego dążyłem, ale nie mogłem zmusić wtyczki NUnit do pracy z potoku / przepływu pracy. Zamiast tego użyłem wtyczki XUnit, która działała dobrze.
demoncodemonkey
4

Rozwiązanie Ralpha Willgossa działa dobrze, ale zmieniłem 2 rzeczy, aby było świetne:

a) Użyłem bezpośrednio projektu NUnit zamiast pliku DLL. Ułatwia to dodawanie większej liczby złożeń lub konfigurowanie testu w interfejsie GUI NUnit.

b) Dodałem jeszcze jedną linię do partii, aby zapobiec niepowodzeniu kompilacji w przypadku niepowodzenia testu:

[PathToNUnit]\bin\nunit-console.exe [PathToTestProject]\UnitTests.nunit /xml=nunit-result.xm
exit 0

Wspomniana wtyczka NUnit automatycznie oznacza kompilację jako NIESTABILNĄ , co jest dokładnie tym, czego chcę, gdy test zakończy się niepowodzeniem. Pokazuje żółtą kropkę.

JCH2k
źródło
3
Dlaczego nie chcesz, aby kompilacja zakończyła się niepowodzeniem, jeśli test jednostkowy zakończy się niepowodzeniem? Czy nieudany test nie powinien wskazywać, że nie chcesz kontynuować wdrażania?
Kirk Woll,
1
Tworzę też moje nightlies z Jenkinsem i nie chcę, żeby zawiodły, jeśli się kompilują, więc mogę przetestować wszystko inne. stan „niestabilny” daje mi wskazówkę, że nie wszystko działa tak, jak powinno. Nietrwały. Jeśli kompilacja wydania jest niestabilna, nie wdrożę jej.
JCH2k
2

Myślę, że lepiej jest zawieść kompilację, gdy nie przejdzie, aby jej nie wdrażać. Zrób coś takiego:

C:\YourNUnitDir\nunit-console.exe C:\YourOutDir\YourLib.dll /noshadow
if defined ERRORLEVEL if %ERRORLEVEL% neq 0 goto fail_build

:: any other command

: fail_build
endlocal
exit %ERRORLEVEL%

Źródła: http://www.greengingerwine.com/index.php/2013/01/tip-check-errorlevel-in-your-post-build-steps-when-using-nunit/

Akira Yamamoto
źródło
czy to robi coś więcej niż tylko pierwsza linijka? nie sądzę. kompilacja i tak kończy się niepowodzeniem, jeśli nunit-console.exe zwraca! = 0, co robi, jeśli test się nie powiedzie.
JCH2k
Zapomniałem powiedzieć, że mam kilka poleceń po wywołaniu nunit-console.exe w moim zadaniu Jenkinsa. Jenkins rozważa tylko ostatnie polecenie ERRORLEVEL, więc nie działało dla mnie.
Akira Yamamoto,
Czy to zapobiega korzyściom z etapu publikacji? Chciałbym, aby wtyczka miała prostą kompilację oznaczoną jako „” w przypadku niepowodzenia konfiguracji testowej.
Tommy Holman
1

Jenkins ma wtyczki, które to obsługują. Dokładna konfiguracja będzie w dużym stopniu zależeć od konfiguracji projektu. Istnieją specyficzne wtyczki dla nUnit, MSBuild, nAnt itp. Zacznij od obejrzenia strony z wtyczkami, ale nie powinno być to strasznie trudne do rozgryzienia.

Matt
źródło
1

Oto moje rozwiązanie do uruchamiania OpenCover z vstest w Jenkins:

param(
[string] $sourceDirectory = $env:WORKSPACE
, $includedFiles = @("*Test.dll")
, $excludedFiles = @("*.IGNORE.dll")
, [string]$filterFolder = "*\bin\Debug*"
)

# Executables
$openCoverExecutable = "C:\Users\tfsbuild\AppData\Local\Apps\OpenCover\OpenCover.Console.exe"
$unitExecutable = "F:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe"

# Logs
$openCoverReport = Join-Path $sourceDirectory "opencover.xml"
$openCoverFilter = "+[*]* -[*Test]*"

Write-Host "`r`n==== Configuration for executing tests ===="
Write-Host "Source: `"$sourceDirectory`""
Write-Host "Included files: `"$includedFiles`""
Write-Host "Excluded files: `"$excludedFiles`""
Write-Host "Folder filter: `"$filterFolder`""
Write-Host ""
Write-Host "OpenCover Report: `"$openCoverReport`""
Write-Host "OpenCover filter: `"$openCoverFilter`""

# look through all subdirectories of the source folder and get any unit test assemblies. To avoid duplicates, only use the assemblies in the Debug folder
[array]$files = get-childitem $sourceDirectory -include $includedFiles -exclude $excludedFiles -recurse | select -expand FullName | where {$_ -like $filterFolder} | Resolve-Path -Relative

$exitCode = 0
$failedTestDlls = ""

foreach ($file in $files)
{
    Write-Host "`r`nCurrent test dll: $file"

    # set all arguments and execute OpenCover
    $argumentList = @("-target:`"$unitExecutable`"", "-targetargs:`"$file /UseVsixExtensions:false /Logger:trx`"", "-register:user -filter:`"$openCoverFilter`" -mergeoutput -mergebyhash -skipautoprops -returntargetcode -output:`"$openCoverReport`"")

    $unitTestProcess = start-process -filepath $openCoverExecutable -argumentlist $argumentList -wait -nonewwindow -passthru -WorkingDirectory $sourceDirectory

    if ($unitTestProcess.ExitCode -ne 0)
    {
        $failedTestDlls = $failedTestDlls + $file + "`r`n"
        $exitCode = $unitTestProcess.ExitCode
    }
}

if ($exitCode -ne 0)
{
    Write-Host "`r`n==== Executing tests in following dlls failed ===="
    Write-Host "$failedTestDlls"
}

exit $exitCode

Każda testowa biblioteka dll jest wykonywana w ramach własnego procesu, ponieważ mieliśmy problemy z wykonaniem wszystkich testowych bibliotek dll w jednym procesie (problemy z ładowaniem zestawu).

MeJ
źródło
0

Dla .Net Core wystarczy dodać krok budowania "wykonaj powłokę" z następującym skryptem:

#!bash -x

cd $my_project_dir
rm -rf TestResults   # Remove old test results.
dotnet test -l trx

Następnie dodaj akcję „Opublikuj raport wyników testu MSTest” po kompilacji, aby wyniki testu były widoczne.

Domyślna ścieżka raportów z testów powinna być **/*.trxi będzie publikować wszystkie utworzone .trxpliki.

stop-cran
źródło