본문 바로가기
CS

gcov를 이용한 C++ 코드 커버리지의 확인, 테스트 지표 사용하기

by Warehaus 2022. 3. 18.

 

개요


최근에서야 코드 커버리지에 대한 필요성이 언급되고 있습니다.
사실 이 개념은 정말 오래 된 개념이고 gcov 도 정말 엄청 오래전부터 사용되던 툴 입니다.

개발을 서두르다보니 이런 부분까지 신경을 미처 쓰지 못하고 있었는데, 시켜서 한 일이기는 하지만 그래도 프로젝트에 어떻게 적용해야 할 지 가늠을 잡게 된 것 같습니다.

 

Code coverage


코드 커버리지는 이전 포스팅에서 간략하게 나마 정리해 둔 글이 있다.

2022.01.10 - [CS] - [CS] 코드커버리지(Code coverage) 란?

 

[CS] 코드커버리지(Code coverage) 란?

정의 화이트 박스테스트에서 테스트가 코드를 포함하는 수준을 지표화한 정보 유형 - function coverage - statement coverage - branch coverage - condition covereage 내용상세 - function covereage : 한 함수..

armin.tistory.com



다시한번 언급하자면,  기 작성 된 테스팅 코드들을 수행했을 때 얼마만큼의 코드를 실행하는지(커버하는지) 확인하기 위해서 코드 커버리지를 측정하게 된다.

 

코드커버리지는 테스트 의 Pass / Fail 개념과는 사뭇 다른 개념일 수 있으니 의미를 오해하는 일이 없었으면 한다.


코드를 100% 커버한다 하더라도 모든 Test결과가 예상과 다르다면 (Fail 이 많이 나온다면), 그 코드는 안전한 코드라고 할 수 없을 것이다.

 

코드 커버리지는 아래 구글 Best practice를 참고하면 좋을 것 같다.

 

https://testing.googleblog.com/2020/08/code-coverage-best-practices.html

 

Code Coverage Best Practices

By Carlos Arguelles, Marko Ivanković‎, and Adam Bender We have spent several decades driving software testing initiatives in various very la...

testing.googleblog.com

 

 

In general code coverage of a lot of products is below the bar; we should aim at significantly improving code coverage across the board. Although there is no “ideal code coverage number,” at Google we offer the general guidelines of 60% as “acceptable”, 75% as “commendable” and 90% as “exemplary.” However we like to stay away from broad top-down mandates and encourage every team to select the value that makes sense for their business needs.

 

 

gcov

 

여기서 우리는 gcov 를 알아야 한다.

gcov의 개념은 다음과 같다.

 

GNU CC와 함께 사용해서 프로그램에 대한 코드 커버리지(code coverage) 테스트를 수행할 수 있는 도구이다.
- http://korea.gnu.org/manual/release/gcov/gcov_1.ko.html

 

우리는 코드커버리지를 gcov 툴을 이용해서 구할 수 있다는 것을 의미한다.

 

그래서 어떻게 테스트하는가?

 

일단 gcov를 실행해보자. (참고: 실행환경은 맥북 프로 이다.)

 

$ gcov
gcov: Not enough positional command line arguments specified!
Must specify at least 1 positional argument: See: /Library/Developer/CommandLineTools/usr/bin/gcov -help

 

1개의 positional argument 가 필요하다고 한다.

메뉴얼 하나씩 읽어보는건 스트레스 받으니.. 바로 제대로된 사용법을 알아보자.

 

일단 코드 하나를 임의로 작성해 본다.  예전에 const 관련 글을 작성하면서 썼던 코드이다.

#include <iostream>

using namespace std;

int main() {

    int val = 10;
    const int *a = &val;

    // 10
    cout << *a << endl;

    int new_val = 20;
    a = &new_val;

    // 20
    cout << *a << endl;

    return 0;
}

 

빌드를 하고 이 코드를 이용해서 code coverage를 측정해 보자.

 

커버리지 측정을 위해서는 gcc / g++ 사용 시 GNU CC의 `-fprofile-arcs -ftest-coverage' 옵션을 사용해서 프로그램을 컴파일 해야 한다.

g++ -fprofile-arcs -ftest-coverage test_const.cc
이 옵션들은 GNU CC 컴파일러로 하여금 프로그램의 플로우 그래프(flow graph)를 포함한  gcov 의 사용에 필요한 부가적인 정보를 생성하도록 할 수 있으며, 프로파일링 정보를 만들기 위한 사항들을 오프젝트 파일에 추가시킬 수 있다. 이 파일들은 소스 코드가 있는 디렉토리 안에 생성된다.

- http://korea.gnu.org/manual/release/gcov/gcov_1.ko.html#SEC2

 

빌드가 완료되었으면 한번 실행해 본다. 옵션을 주지 않았을때와 별반 다르지 않다.

$ ./a.out 
10
20

 

이제 빌드 된 바이너리와 gcov를 이용해 code coverage를 확인한다.

 

아래 명령어를 사용하면 측정이 가능하다.

$ gcov test_const.cc
File '/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/__locale'
Lines executed:100.00% of 4
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/__locale:creating '__locale.gcov'

File '/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/ios'
Lines executed:66.67% of 3
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/ios:creating 'ios.gcov'

File '/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/ostream'
Lines executed:100.00% of 6
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/ostream:creating 'ostream.gcov'

File 'test_const.cc'
Lines executed:100.00% of 8
test_const.cc:creating 'test_const.cc.gcov'

 

test_const.cc 코드의 라인은 100% 실행되었음을 확인할 수 있습니다.

 

gcov 는 라인 커버리지 외에도 다른 유형의 커버리지 측정을 지원합니다.

branch, function 등의 커버리지도 확인할 수 있으니 아래 옵션을 참고해서 사용하는게 좋을것 같습니다.

USAGE: gcov [options] SOURCEFILE

OPTIONS:

Color Options:

  -color         - Use colors in output (default=autodetect)

General options:

  -a             - Display all basic blocks
  -b             - Display branch probabilities
  -c             - Display branch counts instead of percentages (requires -b)
  -f             - Show coverage for each function
  -l             - Prefix filenames with the main file
  -n             - Do not output any .gcov files
  -o=<DIR|FILE>  - Find objects in DIR or based on FILE's path
  -p             - Preserve path components
  -u             - Display unconditional branch info (requires -b)

 

참고자료

http://korea.gnu.org/manual/release/gcov/gcov_1.ko.html#SEC2