Search code examples
unit-testingvisual-c++catch-unit-testcatch2

Best practices for Unit testing with Catch2 in Visual Studio


I'm new to unit testing in C++ and want to get some advice on this. I use Visual Studio 2019 for development and I chose Catch2 as my testing library, I also got the Test Adapter for Catch2 installed.

I read docs for both Catch2 and Test Adapter for Catch2 on GitHub, but I still cannot figure out a proper way to use unit test in Visual Studio.

Let's assume that I already have a project with some classes in it and I want to test those classes. Should I put files with test code in the same project or should I create new test projects within the solution?

When I try the first approach, Test Explorer doesn't discover tests unless I comment out the main() function of the project. With second approach, I get a bunch of unresolved external symbol errors for my classes' methods, although I set correct relative paths to header files and referenced the main project from the test project:

LNK2019 unresolved external symbol "public: bool __thiscall MyClass::Check(int,int)" (?Check@MyClass@@QAE_NHH@Z) referenced in function "void __cdecl ____C_A_T_C_H____T_E_S_T____0(void)" (?____C_A_T_C_H____T_E_S_T____0@@YAXXZ)

I would appreciate if someone show me a correct way to do unit testing with Catch2 in VS.


Solution

  • OK, I guess I found a suitable workflow to make Catch2 test work in Visual Studio 2019:

    1. Create a new project within the solution of the Project under test (PuT). This will be our Test project.
    2. Add a reference to PuT from the Test project.
    3. In the Test project, create a source file and put the following lines in it:
    #define CATCH_CONFIG_MAIN
    #include "path_to_catch2/catch.hpp"
    
    1. Write some tests. You can have as many source files with tests as you want, but remember that only one of them must have the #define CATCH_CONFIG_MAIN declaration.
    2. In Test project Configuration Properties, set following settings:
    • Linker -> General -> Additional Library Directories - add here a path to object files directory of the PuT.
    • Linker -> Input -> Additional Dependencies - here, put object files names of the PuT (not paths, just the names of .OBJ files!), separated by semicolon, which were used in tests. For example, if you want to test some code declared in MyCode.h, put MyCode.obj file name here. When you reference more header files from the PuT, don't forget to update this setting.
    1. Open Test Explorer.
    2. Add a .runsettings file with to the solution root folder. Minimal config looks like this:
    
        <?xml version="1.0" encoding="utf-8"?>
        <RunSettings>
            <Catch2Adapter>
                <FilenameFilter>^Test_</FilenameFilter>
            </Catch2Adapter>
        </RunSettings>
    
    

    where <FilenameFilter> controls filter for test projects filenames. In this particular example, tests will be discovered only in projects which names start with "Test_".

    1. Select this .runsettings file in Test -> Configure Run Settings -> Select Solution Wide runsettings File. You can have multiple .runsettings file with different configuration, here you can switch them at any moment.
    2. Rebuild the solution to discover tests.

    Now you should see your tests in Test Explorer.


    Some useful links:

    https://learn.microsoft.com/en-us/visualstudio/test/how-to-use-microsoft-test-framework-for-cpp?view=vs-2019

    https://github.com/JohnnyHendriks/TestAdapter_Catch2/blob/master/Docs/Walkthrough.md