在上一篇我们讲到单元测试时,可用gcov来做代码覆盖率检查,但有时候我们不仅需要知道代码覆盖率,而且还要判断它是否达到我们实现设定的阈值,比如90%,如果没有达到,就打印警告信息。我们可以自己写一个脚本来实现此功能,并集成到make文件中运行。这里是作者用python编写的处理脚本: 点击(此处)折叠或打开#!/usr/bin/env python##gcov_checker#Usage: gcov_checker threshold --objects A.o B.o ...import sysimport osimport subprocessdef parse_command_line():    if len(sys.argv) 3:        sys.exit(1)    threshold = float(sys.argv[1])    if '--objects' not in sys.argv[2:]:        usage()        sys.exit(1)    gcov_options = sys.argv[2:sys.argv.index('--objects')]    gcov_objects = sys.argv[sys.argv.index('--objects') + 1:]    if len(gcov_objects) == 0:        usage()        sys.exit(1)    return threshold, gcov_options, gcov_objectsdef usage():    print 'gcov_checker threshold [gcov options] --objects object_file ... 'def main():    threshold, gcov_options, gcov_objects = parse_command_line()    print "Code coverage:"    for i in gcov_objects:        command = 'gcov %s' % ' '.join(gcov_options)        command += (' -o %s' % i.replace('_stubbed', ''))        command += ' %s' % \            os.path.basename(i).replace('_stubbed', '').replace('.o', '.cpp')        gcov_process = subprocess.Popen(command,                                        stdout=subprocess.PIPE,                                        shell=True)        gcov_stdout_data = gcov_process.communicate()[0]        if gcov_process.returncode != 0:            print 'Coverage check for %s failed' % i            sys.exit(gcov_process.returncode)        coverage_info_per_file = [t for t in gcov_stdout_data.split('\n\n')                                  if t != '']        for file_info in coverage_info_per_file:            lines = file_info.split('\n')            if len(lines) not in [2, 3]:                raise SyntaxError('Unable to parse gcov output')            name_line = lines[0]            coverage_line = lines[1]# print '============0=============%s' %(name_line)# name = name_line.split('\'')[0];            name = name_line.split('\'')[1];#.replace( \ # os.environ['C_COMPONENT_OUTPUT_PATH'], '')            coverage = float(coverage_line.split(':')[1].split('% ')[0])            coverage_msg = '%s:%s%%' % (name, coverage)            warning_msg = 'WARNING: code coverage % \                threshold# print '============1=============%s' %(name)            if name.endswith('.cpp'):                if coverage >= threshold:                    print coverage_msg                else:                    print '%s - %s' %(coverage_msg, warning_msg)    print "See *.gcov files for details."main()同时我们需要把make文件中的目标UT改成: 点击(此处)折叠或打开UT:UTest.out ./UTest.out ./gcov_checker 90 --objects $(OBJS)运行"make UT"后的结果为: 点击(此处)折叠或打开[root@tivu25 utcov]# make UTg++ -I/home/haoqf/src/UTest/utcov -c -g -fprofile-arcs -ftest-coverage Main.cpp -o Main.og++ -I/home/haoqf/src/UTest/utcov -c -g -fprofile-arcs -ftest-coverage A.cpp -o A.og++ -o UTest.out Main.o A.o -lgcov./UTest.outSum test passed!./gcov_checker 90 --objects Main.o A.o Code coverage:Main.cpp:71.43% - WARNING: code coverage A.cpp:50.0% - WARNING: code coverage See *.gcov files for details.可以看到,由于A.cpp的代码覆盖率不满90%,所以gcov_checker报出了warning。而Main.cpp也同时被报warning,因为它被包含在$(OBJS)中。如果我们修改Main.cpp,增加代码测试A::Multiply如下: 点击(此处)折叠或打开        result = a.Multiply(5,6);        if(result != 30)        {                printf("Multiply test failed!\n");                exit(-1);        }        printf("Multiply test passed!\n");那么编译链接后的结果是: 点击(此处)折叠或打开[root@tivu25 utcov]# make clean;make UTrm -f *.o *.gcno *.gcda *.gcov UTest.outg++ -I/home/haoqf/src/UTest/utcov -c -g -fprofile-arcs -ftest-coverage Main.cpp -o Main.og++ -I/home/haoqf/src/UTest/utcov -c -g -fprofile-arcs -ftest-coverage A.cpp -o A.og++ -o UTest.out Main.o A.o -lgcov./UTest.outSum test passed!Multiply test passed!./gcov_checker 90 --objects Main.o A.o Code coverage:Main.cpp:66.67% - WARNING: code coverage A.cpp:100.0%See *.gcov files for details.这时A.cpp代码覆盖率达到100%,所以gcov_checker没有报警(warning)。《返璞归真--UNIX技术内幕》在全国各大书店及网城均有销售:京东亚马逊                          China pub上学吧                          1号店
11-23 04:09
查看更多