visual-studionunitvisual-studio-2019post-build

How do I Run Nunit Tests As a Post-Build Task in Visual Studio?


I have a solution in Visual Studio with a bunch of projects under it. A number of these projects are test projects, containing only nunit tests and code relating to tests. For these projects, I want to set up a post-build event that runs the tests for each such test project. I have researched this but haven't found any questions exactly asking to do what I'm asking- see below. I already have the nunit framework installed on Visual Studio via nuget and I can run nunit tests already from within the VS test explorer.

Notes

Links

This asks how to run mstest as a post-build, rather than nunit: Using Post-Build Event To Execute Unit Tests With MS Test in .NET 2.0+

This asks how to run nunit from within VS, but not as a post-build: How to run NUnit tests in Visual Studio 2017?


Solution

  • The first thing you need to do is install nunit.consolerunner if you don't have it already. Install this via NuGet in VS. Once this is done, you can proceed to writing a post-build script for each test project.

    The post build script thankfully doesn't need to vary per project. In fact, it doesn't need to vary at all assuming NuGet puts nunit.consolerunner into the expected place. The script will work in both debug and release configurations because the TargetDir and TargetFileName properties from VS are passed down to the console runner as params. Here is the script, you just need to paste it into the post-build section of build events in the properties pane of the respective project:

    cd %HOMEPATH%
    cd ".nuget\packages\nunit.consolerunner\3.10.0\tools"
    nunit3-console.exe $(TargetDir)$(TargetFileName) --where "cat == Unit"  --work=$(TargetDir)\..
    

    The various parts of this can be explained as follows:

    Links

    Nunit console runner docs: https://github.com/nunit/docs/wiki/Console-Command-Line

    Update: A Less Annoying Way

    The above is pretty annoying, because if any of your tests fail, and you then try to run them from VS's integrated test runner, you can't, because you end up in a vicious cycle: running the tests kicks off a build, which kicks off the tests on the console, which fail, which cause your tests in VS not to run. So in order to debug, you have to go rooting around for the results.XML file. Ugh.

    A better way is to do the following:

    We have five test projects. Let's say they're called TestProject1, TestProject2, ... etc. Then this batch file will serve as the post-build script, if it is put in any sub-directory of the main solution directory. It assumes you have Nuget v3.11.1 installed. If not, just change that for whatever version you do have:

    @echo off
    rem Debug or release
    set CONFIG=%1
    set HOMEPATH=%2
    cd ../
    echo Running unit tests for soln. in root dir %cd%
    set currentTest=TestProject1
    call :RUN_TESTS_FOR_PROJECT
    set currentTest=TestProject2
    call :RUN_TESTS_FOR_PROJECT
    set currentTest=TestProject3
    call :RUN_TESTS_FOR_PROJECT
    set currentTest=TestProject4
    call :RUN_TESTS_FOR_PROJECT
    set currentTest=TestProject5
    call :RUN_TESTS_FOR_PROJECT
    echo Finished running tests
    goto :EOF
    
    :RUN_TESTS_FOR_PROJECT
        cd %currentTest%
        cd bin/%CONFIG%
        echo --- Running tests in directory %cd%
        set targetDir=%cd%
        cd %HOMEPATH%
        cd ".nuget\packages\nunit.consolerunner\3.11.1\tools"
        set targetFileName=%currentTest%.dll
        nunit3-console.exe %targetDir%\%targetFileName% --where "cat == Unit" --work=%targetDir%\..
        if errorlevel 1 (       
            echo Tests Failed for %currentTest%
            echo Exiting test run early
            exit %errorlevel%
        )
        cd %targetDir%
        cd ../../../
        goto :EOF
    
    :EOF    
    

    Let's say you put the above script in a folder called Util. The post-build script of your TestMaster project is then:

    cd $(SolutionDir)
    cd Util
    RunTests $(ConfigurationName) %HOMEPATH%