【发布时间】:2018-01-17 19:25:00
【问题描述】:
我正在尝试为一个小型测试库生成代码覆盖率。该库仅包含两个文件。
计算器.cpp:
#include "calculator.h"
Calculator::Calculator()
{
}
Calculator::~Calculator()
{
}
void Calculator::addNumbers(int x, int y)
{
this->result = x + y;
}
计算器.h:
#ifndef CALCULATOR_H
#define CALCULATOR_H
class Calculator
{
public:
Calculator();
~Calculator();
void addNumbers(int x, int y);
};
#endif
我有一个正在执行的这个库的单元测试。它包括库并且运行良好。我已将 cmake_cxx_flags 设置为在顶级 CMakeLists.txt 中包含 -fprofile-arcs 和 -ftest-coverage。
cmake_minimum_required(VERSION 2.8.11)
set(CMAKE_CXX_FLAGS "-std=c++11")
include_directories("${PROJECT_BINARY_DIR}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 --coverage")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 --coverage -ftest-coverage -fprofile-arcs")
add_subdirectory(src)
add_subdirectory(test)
我正在使用脚本来获取构建时生成的 gcno 和 gcda 文件以生成人类可读的报告。
#!/bin/bash
OUTPUT_DIR="$1/bin/ExecutableTests/Coverage"
mkdir -p "$OUTPUT_DIR"
component=Calculator
dependency=calculator
script=test_calculator.sh
unit_test=unit_test_calculator
mkdir $OUTPUT_DIR/$component
cd "$1"/bin/
make clean || exit 1
make || exit 1
# Create baseline coverage
lcov -c -i -d "$1"/bin/src/"$component"/CMakeFiles/"$dependency".dir -o "$1/Coverage/$component"_"$dependency".coverage.base
# Run the test
$1/scripts/$script $1
# Create test coverage
lcov -c -d "$1"/bin/test/$component/CMakeFiles/"$unit_test".dir -o "$1/Coverage/$component"_"$dependency".coverage.run
lcov -d "$1/test/$component" -a "$1/Coverage/$component"_"$dependency".coverage.base -a "$1/Coverage/$component"_"$dependency".coverage.run -o "$1/Coverage/$component"_"$dependency".coverage.total
genhtml --branch-coverage -o "$OUTPUT_DIR/$component" "$1/Coverage/$component"_"$dependency".coverage.total
rm -f "$1/Coverage/$component"_"$dependency".coverage.base "$1/Coverage/$component"_"$dependency".coverage.run "$1/Coverage/$component"_"$dependency".coverage.total
我可以看到正在为库生成数据文件;但是,当我查看从脚本生成的报告时,它显示该库从未被触及。正如我的单元测试所示,这显然是错误的。
#include "lest_basic.hpp"
#include "calculator.h"
#include <memory>
#include <iostream>
int addResult(int x, int y)
{
Calculator calc1;
return calc1.addNumbers(x, y);
}
const lest::test specification[] =
{
CASE( "Addition" )
{
std::cout << "Starting Addition testing..." << std::endl;
std::cout << "Adding 1 and 2..." << std::endl;
EXPECT(addResult(1, 2) == 3);
std::cout << "Adding 2 and 8..." << std::endl;
EXPECT(addResult(2, 8) > 1);
std::cout << "Adding 7 and 4..." << std::endl;
EXPECT(addResult(7, 4) < 12);
},
};
int main(int argc, char **argv) {
return lest::run( specification );
}
这是我的单元测试的 CMakeLists.txt:
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin/ExecutableTests/)
include_directories(${CMAKE_SOURCE_DIR}/externalinclude/)
include_directories(${CMAKE_SOURCE_DIR}/src/Calculator/)
add_executable (unit_test_calculator test_calculator.cpp)
target_link_libraries(unit_test_calculator -Wl,--whole-archive calculator -Wl,--no-whole-archive)
我的问题是为什么报告说库代码没有被覆盖?数据文件有问题吗?
【问题讨论】:
-
您是否尝试过在不使用 CMake 的情况下手动构建库?在这种情况下覆盖范围可以吗?您可以检查编译时实际使用了哪些标志并将您的库与
make VERBOSE=1链接。尝试使用相同的标志手动构建,并检查覆盖率。 -
覆盖标志也应该出现在链接阶段。
-
离题:您可以通过不使用
this->表示法来节省键入击键。仅当成员名称与参数名称相同时才需要该符号;您重命名参数以避免输入this->。 -
@Tsyvarev 当我手动构建库时,我确实得到了一个 gcno 文件。然而,报告仍然说图书馆没有报道。我很好奇为什么当我手动而不是使用 cmake 时 gcno 文件存在。我认为这与 Jarod42 建议的丢失标志有关。
标签: c++ cmake code-coverage