Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What physical layout for Unit-Tested projects?

At the moment, I'm learning about Unit-Testing and I want to integrate testing to my current (10 files of OpenGL experiments) project. For this purpose I downloaded Boost.Test, and while I can figure out how it works on a single file sample, I have no idea about how to integrate it in my project (I'd like to use static link version).

Are test a different binary from the application itself ? (if it's one binary, how to run it ?) Should I create a test file for every tested class ? How much should my CMakeLists change to reflect this integration ? Is it possible to decouple testing from the application, in a way that I can build my app on a platform where I didn't install boost ?

I know I have many questions, but to put it simply : how is Boost.Test used in real life ?

like image 824
bisthebis Avatar asked Oct 18 '22 12:10

bisthebis


1 Answers

Weather your project builds a library or executable, I suggest you create an extra test runner executable. In my projects I normally have the following layout:

/mylib
  CMakeLists.txt
  /inc
    ClassA.hpp
    ClassB.hpp
  /src
    ClassA.cpp
    ClassB.cpp
  /test
    ClassA_test.cpp
    ClassB_test.cpp
    main_test.cpp

As you see there is a test file for every class. This has the main benefit of reducing compilation dependencies. In my CMakeLists.txt I then create my library and the associated test runner

# Get Boost
find_package ( Boost COMPONENTS unit_test_framework )
# Here you set library sources, use file ( GLOB ... ) if you have many
set ( SOURCES ClassA.cpp ClassB.cpp )    
add_library ( mylib ${SOURCES} )

if (Boost_FOUND)
  # Here you set test sources, use file ( GLOB ... ) if you have many
  set ( TESTSOURCES ClassA_test.cpp ClassB_test.cpp )    
  # This creates the test runner
  add_executable (  mylib_test_runner ${TESTSOURCES} )
  # Here the tests of the runner are linked to the related library and Boost
  target_link_libraries ( mylib_test_runner mylib ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} )
endif ( )

The file main_test.cpp is only there to automatically generate the main function for the test runner

#define BOOST_TEST_MODULE MyTestSuite
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>

Then, for example, ClassB_test.cpp might have the following layout:

#include "../inc/ClassB.hpp"
#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_SUITE ( ClassBTest )

BOOST_AUTO_TEST_CASE ( TestFoo )
{
  BOOST_CHECK(true);
}

...

BOOST_AUTO_TEST_SUITE_END() // ClassBTest

So wrapping up:

  • Are test a different binary from the application itself? - Yes, that is possible and certainly helpful.
  • If it's one binary, how to run it? - In this case: ./mylib_test_runner
  • Should I create a test file for every tested class? - I suggest you do.
  • How much should my CMakeLists change to reflect this integration? - See the example.
  • Is it possible to decouple testing from the application, in a way that I can build my app on a platform where I didn't install boost? - The check for Boost_FOUND takes care of this, you could also add an option to your CMakeLists.txt and check against that. I personally think this is even better.
like image 99
ToniBig Avatar answered Nov 15 '22 11:11

ToniBig