¿Cómo se ejecutan las pruebas NUnit de Jenkins?

108

Estoy buscando ejecutar pruebas NUnit automatizadas para una aplicación C #, todas las noches y en cada confirmación de svn.

¿Es esto algo que Jenkins-CI puede hacer?
¿Existe un tutorial en línea o un documento de instrucciones que documente una configuración similar que pueda ver?

arándanos
fuente
¿Hay algo más que estés buscando?
jglouie
1
Estoy buscando un tutorial o un documento de instrucciones con una configuración similar.
blueberryfields
1
¿Tiene NUnit ejecutando las pruebas como desee desde la línea de comandos? Si no, ese es el paso 1
jglouie

Respuestas:

120

Necesitaba hacer exactamente lo que tú haces, así es como configuré a Jenkins para hacer esto:

  1. Agregue el complemento NUnit a Jenkins
  2. En su proyecto, vaya a Configurar -> Construir -> Agregar un paso de construcción
  3. En el menú desplegable, desplácese hacia abajo hasta -> Ejecutar comando por lotes de Windows
  4. Asegúrese de que este paso se coloque después del paso de MSBuild
  5. Agregue lo siguiente, reemplazando las variables:

Prueba de dll única:

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

Prueba de dll múltiple usando proyectos de prueba NUnit :

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

  1. En Acciones posteriores a la compilación , marque Publicar informe de resultado de prueba de NUnit
  2. Para los XML del informe de prueba del cuadro de texto , ingrese nunit-result.xml

Una vez que se haya creado su proyecto, NUNit ahora se ejecutará y los resultados se podrán ver en el Panel de control (si se desplaza sobre el ícono del Informe meteorológico) o en la página del proyecto debajo de Resultado de la última prueba .

También puede ejecutar el comando desde Visual Studio o como parte de su proceso de compilación local.

Aquí hay dos publicaciones de blog que usé como referencia. No encontré ninguno que se ajustara exactamente a mis requisitos:
Guía de 1 hora para la configuración de integración continua: Jenkins cumple con .Net (2011)
Guía para crear proyectos .NET usando Hudson (2008)

Ralph Willgoss
fuente
Realmente no veo cómo esto es suficiente. ¿Es normal tener solo una (o algunas) DLL de prueba? Tenemos un montón de ellos, y se crean y eliminan con frecuencia. ¿No debería haber una manera de hacer esto sin tener que codificar la prueba en jenkins?
André C. Andersen
Apunte el paso de compilación a un uso de un archivo .bat o .cmd bajo control de código fuente, que inicia su comando NUnit. Ahora, puede modificar las pruebas que se ejecutarán con la frecuencia que desee sin cambiar Jenkins. También debe mirar NUnit Test Projects, ya que eso también podría ayudarlo. La clave es decirle a Jenkins qué archivo xml usar para el informe de prueba.
Ralph Willgoss
4
simplemente use su archivo * .nunit como parámetro en lugar del archivo DLL, por ejemplo "C:\Program Files (x86)\NUnit 2.6.3\bin\nunit-console-x86.exe" UnitTests/UnitTests.nunit. Funcionó perfectamente para mí.
JCH2k
3
Puede usar el archivo * .sln en lugar de la DLL, consulte la documentación
Martin
2
Ahhh. Mi falacia lógica fue que el complemento NUnit creó un nuevo tipo de "Tarea de compilación". Su vudú mágico es el evento Post-Build. (Y uno solo usa la línea de comando regular para generar el .xml)
granadaCoder
16

Si no desea codificar sus proyectos de prueba unitaria, es mejor que escriba un script para obtener todos los dll de su proyecto de prueba unitaria. Lo hacemos con Powershell y seguimos una convención específica para nombrar nuestros proyectos de pruebas unitarias. Aquí está el contenido del archivo de PowerShell que ejecuta nuestras pruebas unitarias:

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

El script es lo suficientemente robusto como para reutilizarlo para todos nuestros trabajos de compilación. Si no le gusta la ruta completa a la consola NUnit, siempre puede poner esa ubicación en su variable de entorno PATH.

Luego colocamos el archivo RunUnitTests.ps1 en nuestro servidor de compilación y usamos este comando por lotes:

powershell.exe -file "{full-path-to-script-direcory}\RunUnitTests.ps1"
Daniel McQuiston
fuente
Funcionó bien pero tuve dos problemas. primero fue el directorio de origen. Tuve que cambiar el directorio de origen hacia [string] $sourceDirectory = $(get-location)y para las rutas con espacios.Tuve que cambiar el pase de ensamblaje a nUnit to$cFiles = $cFiles + '"' + $file + '"' + " "
Choco Smith
Si tenemos Test, lo estamos ejecutando mediante Test Playlist. ¿Podemos ejecutar esta lista de reproducción de prueba para Jenkins usando .dll?
Ishita Shah
15

Para granjas Nunit 3 o superior:

  1. Paso de construcción (línea de comandos de 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. Paso posterior para la publicación de informes de Nunit, solo muestra el archivo de resultados de la prueba en el directorio del espacio de trabajo de Jenkins, no en su proyecto: TestR.xml

Necesitamos hacer los resultados de las pruebas en formato nunit2 porque ahora el complemento Jenkins Nunit no reconoce el formato de resultados Nunit3. También el formato de cadena de opciones es diferente: --result=TestR.xml;format=nunit2 NO /xml=nunit-result.xml

Winston33
fuente
8

Esto funciona muy bien, lo he configurado antes.

Configure NUnit para generar los resultados en un archivo XML y configure NUnit Jenkins Plugin para consumir este archivo XML. Los resultados estarán disponibles en el tablero.

Ahora, la forma de invocar NUnit depende de usted. La forma en que lo hicimos fue: el trabajo de Jenkins ejecuta NAnt target ejecuta NUnit test suite.

Puede configurar los trabajos de Jenkins para que se ejecuten en la confirmación o se programen en un momento determinado.

jglouie
fuente
Esto es casi lo que busqué, pero no pude hacer que el complemento NUnit funcionara desde una tubería / flujo de trabajo. Usé el complemento XUnit en su lugar, que funcionó bien.
demoncodemonkey
4

La solución de Ralph Willgoss está funcionando bien, pero cambié 2 cosas para que fuera genial:

a) Usé un proyecto NUnit en lugar del archivo DLL directamente. Esto hace que sea más fácil agregar más ensamblados o configurar la prueba en la GUI de NUnit.

b) Agregué una línea más al lote para evitar que la compilación fallara cuando falla una prueba:

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

El complemento NUnit mencionado marca la compilación como INESTABLE automáticamente, que es exactamente lo que quiero, cada vez que falla una prueba. Se muestra con un punto amarillo.

JCH2k
fuente
3
¿Por qué no querría que la compilación falle si falla la prueba unitaria? ¿La prueba fallida no debería indicar que no desea continuar con una implementación?
Kirk Woll
1
También construyo mis camisones con jenkins y no quiero que fallen si se compilan para poder probar todo lo demás. el estado "inestable" me da una pista de que no todo funciona como se supone. Inestable. Si una compilación de lanzamiento es inestable, no la implementaré.
JCH2k
2

Creo que es mejor fallar la compilación cuando no se aprueba para no implementarla. Haz algo como esto:

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%

Referencia: http://www.greengingerwine.com/index.php/2013/01/tip-check-errorlevel-in-your-post-build-steps-when-using-nunit/

Akira Yamamoto
fuente
¿Esto hace algo más de lo que haría la primera línea por sí sola? No lo creo. la compilación falla de todos modos si nunit-console.exe devuelve! = 0, lo que ocurre si falla una prueba.
JCH2k
Olvidé decir que tenía algunos comandos después de llamar a nunit-console.exe en mi trabajo de Jenkins. Jenkins considera solo el último comando ERRORLEVEL, por lo que no me funcionó.
Akira Yamamoto
¿Impide esto los beneficios del paso de publicación? Desearía que el complemento tuviera una marca simple como "" en la configuración de prueba fallida.
Tommy Holman
1

Jenkins tiene complementos que lo admitirán. La configuración exacta dependerá bastante de la configuración de su proyecto. Hay complementos específicos para nUnit, MSBuild, nAnt, etc. Empiece por mirar la página de complementos, pero no debería ser muy difícil de entender.

Mate
fuente
1

Esta es mi solución para ejecutar OpenCover con vstest en 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

Cada dll de prueba se ejecuta en un proceso propio porque tuvimos problemas para ejecutar todas las dll de prueba en un solo proceso (problemas con la carga del ensamblaje).

MeJ
fuente
0

Para .Net Core, basta con agregar el paso de compilación "ejecutar shell" con el siguiente script:

#!bash -x

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

Después de eso, agregue la acción posterior a la compilación "Publicar informe de resultado de prueba de MSTest" para que los resultados de la prueba sean visibles.

La ruta predeterminada de los informes de prueba debe ser **/*.trxy publicará todos los .trxarchivos producidos .

stop-cran
fuente