Como você executa os testes NUnit do Jenkins?

108

Estou tentando executar testes NUnit automatizados para um aplicativo C #, todas as noites e em cada commit para svn.

Isso é algo que o Jenkins-CI pode fazer?
Existe um tutorial online ou documento de instruções que documenta uma configuração semelhante que eu possa consultar?

mirtilo
fonte
há mais alguma coisa que você esteja procurando?
jglouie
1
Estou procurando um tutorial ou documento de instruções com uma configuração semelhante.
blueberryfields de
1
Você tem o NUnit executando os testes como deseja na linha de comando? Se não, essa é a etapa 1
jglouie de

Respostas:

120

Eu precisava fazer exatamente o que você faz, eis como configurei o Jenkins para fazer isso:

  1. Adicione o plug-in NUnit ao Jenkins
  2. Em seu projeto, vá para Configurar -> Construir -> Adicionar uma etapa de construção
  3. No menu suspenso, role para baixo até -> Executar comando em lote do Windows
  4. Certifique-se de que esta etapa seja colocada após sua etapa do MSBuild
  5. Adicione o seguinte, substituindo as variáveis:

Teste de dll único:

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

Teste de dll múltiplo usando projetos de teste NUnit :

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

  1. Em Ações de pós-construção , marque Publicar relatório de resultado de teste NUnit
  2. Para os XMLs do relatório de teste da caixa de texto , insira nunit-result.xml

Assim que o projeto tiver sido construído, o NUNit será executado e os resultados poderão ser visualizados no Painel (se você passar o mouse sobre o ícone do relatório meteorológico) ou na página do projeto em Resultado do Último Teste .

Você também pode executar o comando de dentro do Visual Studio ou como parte do processo de compilação local.

Aqui estão duas postagens de blog que usei como referência. Não encontrei nenhum que
atendesse exatamente aos meus requisitos: Guia de 1 hora para configuração de integração contínua: Jenkins atende .Net (2011)
Guia para construção de projetos .NET usando Hudson (2008)

Ralph Willgoss
fonte
Eu realmente não vejo como isso é suficiente. É normal ter apenas uma (ou algumas) dlls de teste? Temos um monte deles, e eles são criados e removidos com frequência. Não deveria haver uma maneira de fazer isso sem ter que codificar o teste para jenkins?
André C. Andersen
Aponte a etapa de compilação para usar um arquivo .bat ou .cmd sob controle de origem, que inicia seu comando NUnit. Agora, você pode modificar os testes que serão executados com a frequência que desejar, sem alterar o Jenkins. Você também deve examinar os Projetos de teste do NUnit, pois isso também pode ajudá-lo. A chave é dizer ao Jenkins qual arquivo xml usar para o relatório de teste.
Ralph Willgoss,
4
apenas use seu arquivo * .nunit como parâmetro em vez do arquivo DLL, por exemplo "C:\Program Files (x86)\NUnit 2.6.3\bin\nunit-console-x86.exe" UnitTests/UnitTests.nunit. Funcionou perfeitamente para mim.
JCH2k
3
Você pode usar o arquivo * .sln em vez da DLL, consulte a documentação
Martin
2
Ahhh. Minha falácia lógica foi que o plugin NUnit criou um novo tipo "Build-Task". Seu vodu mágico é o evento Pós-construção. (E só se usa a linha de comando regular para gerar o .xml)
granadaCoder
16

Se você não quiser codificar seus projetos de teste de unidade, é melhor escrever um script para obter todas as dlls de seus projetos de teste de unidade. Fazemos isso com o Powershell e seguimos uma convenção específica para nomear nossos Projetos de Teste de Unidade. Aqui está o conteúdo do arquivo powershell que executa nossos testes de unidade:

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

O script é robusto o suficiente para ser reutilizado em todos os nossos trabalhos de construção. Se você não gosta do caminho completo para o console NUnit, você sempre pode colocar esse local em sua variável de ambiente PATH.

Em seguida, colocamos o arquivo RunUnitTests.ps1 em nosso servidor de compilação e usamos este comando em lote:

powershell.exe -file "{full-path-to-script-direcory}\RunUnitTests.ps1"
Daniel McQuiston
fonte
funcionou bem, mas eu tive dois problemas. primeiro foi o diretório de origem. Tive que mudar o diretório de origem para [string] $sourceDirectory = $(get-location)e para caminhos com espaços. Tive que mudar o passe de montagem para nUnit para$cFiles = $cFiles + '"' + $file + '"' + " "
Choco Smith
Se tivermos Teste, que estamos executando por Test Playlist. Podemos executar esta lista de reprodução de teste para Jenkins, usando .dll?
Ishita Shah
15

Para trabalho agrícola Nunit 3 ou superior:

  1. Etapa de construção (linha de comando do 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. Pós-etapa para publicação de relatório Nunit, mostra apenas o arquivo de resultados de teste no diretório do espaço de trabalho do Jenkins, não em seu projeto: TestR.xml

Precisamos fazer os resultados do teste no formato nunit2 porque agora o plugin Jenkins Nunit não reconhece o formato de resultados Nunit3. Além disso, o formato da string de opções é diferente: --result=TestR.xml;format=nunit2 NÃO /xml=nunit-result.xml

Winston33
fonte
8

Isso funciona bem, eu configurei isso antes.

Configure o NUnit para produzir os resultados em um arquivo XML e configure o plug - in NUnit Jenkins para consumir esse arquivo XML. Os resultados estarão disponíveis no painel.

Agora, como você invoca o NUnit é com você. A maneira como fizemos foi: Jenkins job executa NAnt target executa NUnit test suite.

Você pode configurar os trabalhos do Jenkins para serem executados na confirmação e / ou agendados em um determinado momento.

jglouie
fonte
Foi quase isso que eu tentei, mas não consegui fazer o plug-in NUnit funcionar em um pipeline / fluxo de trabalho. Eu usei o plugin XUnit, que funcionou bem.
demoncodemonkey
4

A solução de Ralph Willgoss está funcionando bem, mas eu mudei 2 coisas para torná-la ótima:

a) Usei um projeto NUnit em vez do arquivo DLL diretamente. Isso torna mais fácil adicionar mais assemblies ou configurar o teste na GUI do NUnit.

b) Eu adicionei mais uma linha ao lote para evitar que a compilação falhe quando um teste falhar:

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

O plug-in NUnit mencionado marca a build como UNSTABLE automaticamente, que é exatamente o que eu quero, sempre que um teste falha. Ele aparece com um ponto amarelo.

JCH2k
fonte
3
Por que você não quer que a construção falhe se o teste de unidade falhar? O teste com falha não deveria indicar que você não deseja prosseguir com uma implantação?
Kirk Woll
1
Eu também construo meus nightlies com Jenkins e não quero que eles falhem se compilarem, então posso testar todo o resto. o status "instável" me dá uma dica de que nem tudo funciona como esperado. Instável. Se uma versão de lançamento for instável, não vou implantá-la.
JCH2k
2

Eu acho que é melhor falhar a compilação quando ela não passa, para que você não a implante. Faça algo assim:

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%

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

Akira Yamamoto
fonte
isso faz algo mais do que a primeira linha sozinha faria? Acho que não. a compilação falha de qualquer maneira se nunit-console.exe retornar! = 0, o que acontecerá se um teste falhar.
JCH2k
Esqueci de dizer que recebi alguns comandos depois de chamar nunit-console.exe em meu trabalho do Jenkins. Jenkins considera apenas o último comando ERRORLEVEL, então não estava funcionando para mim.
Akira Yamamoto
Isso impede os benefícios da etapa de publicação? Gostaria que o plugin tivesse uma marca simples construída como "" na configuração de teste com falha.
Tommy Holman
1

Jenkins tem plug-ins que suportam isso. A configuração exata vai depender um pouco da configuração do seu projeto. Existem plug-ins específicos para nUnit, MSBuild, nAnt etc. Comece observando a página de plug-ins, mas não deve ser terrivelmente difícil de descobrir.

Matt
fonte
1

Esta é a minha solução para a execução de OpenCover com vstest em 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 teste é executado em um próprio processo porque tivemos problemas para executar todas as dlls de teste em um único processo (problemas com o carregamento do assembly).

MeJ
fonte
0

Para .Net Core, é suficiente adicionar a etapa de compilação "execute shell" com o seguinte script:

#!bash -x

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

Depois disso, adicione a ação pós-compilação "Publicar relatório de resultado do teste MSTest" para tornar os resultados do teste visíveis.

O caminho padrão dos relatórios de teste deve ser **/*.trxe publicará todos os .trxarquivos produzidos .

stop-cran
fonte