개요
최근에서야 코드 커버리지에 대한 필요성이 언급되고 있습니다.
사실 이 개념은 정말 오래 된 개념이고 gcov 도 정말 엄청 오래전부터 사용되던 툴 입니다.
개발을 서두르다보니 이런 부분까지 신경을 미처 쓰지 못하고 있었는데, 시켜서 한 일이기는 하지만 그래도 프로젝트에 어떻게 적용해야 할 지 가늠을 잡게 된 것 같습니다.
Code coverage
코드 커버리지는 이전 포스팅에서 간략하게 나마 정리해 둔 글이 있다.
2022.01.10 - [CS] - [CS] 코드커버리지(Code coverage) 란?
다시한번 언급하자면, 기 작성 된 테스팅 코드들을 수행했을 때 얼마만큼의 코드를 실행하는지(커버하는지) 확인하기 위해서 코드 커버리지를 측정하게 된다.
코드커버리지는 테스트 의 Pass / Fail 개념과는 사뭇 다른 개념일 수 있으니 의미를 오해하는 일이 없었으면 한다.
코드를 100% 커버한다 하더라도 모든 Test결과가 예상과 다르다면 (Fail 이 많이 나온다면), 그 코드는 안전한 코드라고 할 수 없을 것이다.
코드 커버리지는 아래 구글 Best practice를 참고하면 좋을 것 같다.
https://testing.googleblog.com/2020/08/code-coverage-best-practices.html
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
'CS' 카테고리의 다른 글
[CS/SW설계] Basic principles of object oriented - 객체지향의 기본 원리에 대해 (0) | 2022.03.24 |
---|---|
윈도우 에서 리눅스처럼 hosts 를 바꾸는 방법 - hosts file in Windows 10 (0) | 2022.03.23 |
데브옵스(devops)와 개발자가 되려면 무엇을 배워야 하는가? - Developer Roadmaps / Devops roadmap (0) | 2022.03.08 |
[Linux] lsof 명령어의 개념 / 사용 방법에 대해 (0) | 2022.02.28 |
[도커] docker 버전 확인하고 신규 컨테이너 생성하기 (0) | 2022.02.23 |