[GCOV] Unit testing of shared libraries with code coverage

  • Hi!

    My library looks like the following:


    The subproject code.pro creates a shared library.
    The subproject test.pro creates an application with unit tests.

    Compiler and linker options for code coverage:
    @QMAKE_CXXFLAGS += -fprofile-arcs -ftest-coverage
    QMAKE_LDFLAGS +=-fprofile-arcs -ftest-coverage
    LIBS += -lgcov@

    After that the .gcno files will be created in $${OBJECTS_DIR} directory.
    After executing the application with unit tests, the .gcda files will be created in $${OBJECTS_DIR} directory.

    After executing the following command I get some errors:
    @lcov --capture --directory $${OBJECTS_DIR} --output-file coverage_all.info@

    The files in subdirectory test will be found:
    @Processing obj/test_class1.gcda@

    The files in subdirectory code will not be found:

    @Processing obj/class1.gcda
    class1.cpp:cannot open source file@

    The problem is, that the files in class1.h and class1.cpp were built in a different directory.
    It does not help if I specify the test directory as --base-directory in lcov.

    Solution with include
    I found a solution but I am not very happy about it:

    • create code.pri in code subdirectory
    • include code.pri in test .pro: #include(../code/code.pri)
    • compile class1.h and class1.cpp directly from test subproject.

    Solution with shared libraries
    I am looking for such a solution. It means, that the application test would use the shared library created by code subproject. Do you think is it realistic? Do you think is it a better solution as the first one? Do you have any other suggestion?

    Thank you!

  • To get coverage with gcov for a shared library the following steps are necessary:

    1. Create two different output directories in subprojects code and test for the files .o, .gcno, .gcda:


    1. Create a configuration file for lcov in your home directory (linux) with the following content (for more details see man lcovrc):

    geninfo_adjust_src_path = /code/bin/obj => /code
    geninfo_adjust_src_path = /test/bin/obj => /test

    1. Build the executable. (It creates .gcno files.)

    2. Set LD_LIBRARY_PATH to the shared libraries.

    3. Run the executable. (It creates .gcda files.)

    4. Run lcov:
      @lcov --capture --directory path_to_lib1 --output-file coverage_all.info@

    5. Run genhtml:
      @genhtml coverage_all.info -o output_path@

Log in to reply