准备环境:
qt-creator5.2.1 , gcov(gcc 默认安装),lcov(gcov 的图形化显示界面),qt_testlib
各环境介绍:
1.gcov
gcov
是一个可用于C/C++的代码覆盖工具,是gcc的内建工具。下面介绍一下如何利用gcov来收集代码覆盖信息。
想要用gcov收集代码覆盖信息,需要在gcc编译代码的时候加上这2个选项:
“-fprofile-arcs -ftest-coverage”,把这个简单的程序编译一下
gcc -fprofile-arcs -ftest-coverage hello.c -o hello
编译后会得到一个可执行文件hello和hello.gcno文件,当用gcc编译文件的时候,如果带有“-ftest-coverage”参数,就会生成这个.gcno文件,它包含了程序块和行号等信息
接下来可以运行这个hello的程序
./hello 5
./hello 12
运行结束以后会生成一个hello.gcda文件,如果一个可执行文件带有“-fprofile-arcs”参数编译出来,并且运行过至少一次,就会生成。
这个文件包含了程序基本块跳转的信息。接下来可以用gcov生成代码覆盖信息:
gcov hello.c 运行结束以后会生成2个文件hello.c.gcov和myfunc.c.gcov。打开看里面的信息:
-: 0:Source:myfunc.c
-: 0:Graph:hello.gcno
-: 0:Data:hello.gcda
-: 0:Runs:1
-: 0:Programs:1
-: 1:#include
-: 2:
-: 3:void test(int count)
1: 4:{
-: 5: int i;
10: 6: for (i = 1; i < count; i++)
-: 7: {
9: 8: if (i % 3 == 0)
3: 9: printf (“%d is divisible by 3
\
n”, i);
9: 10: if (i % 11 == 0)
#
####: 11: printf (“%d is divisible by 11
\
n”, i);
9: 12: if (i % 13 == 0)
#####: 13: printf (“%d is divisible by 13
\
n”, i);
-: 14: }
1: 15:}
被标记为#####的代码行就是没有被执行过的,代码覆盖的信息是正确的.
1.2 使用gcov的3个阶段
(1) 编译
# gcc -f=profile-arcs -f test-coverage -o test test.c
# ls
test test.c test.gcno
-f profile-arcs -f test-coverage告诉编译器生成gcov需要的额外信息,并在目标文件中插入gcov需要的extra profiling information。因此,该命令在生成可执行文件test
的同时生成test.gcno文件(gcov note文件)。
(2) 收集信息
# ./test
Success
# ls
test test.c test.gcda test.gcno
执行该程序,生成test.gcda文件(gcov data文件)。
(3)
报告
# gcov test.c
File 'test.c'
Lines executed:87.50% of 8
test.c:creating 'test.c.gcov'
# ls
test test.c
test.c.gcov
test.gcda test.gcno
生成test.c.gcov文件,该文件记录了每行代码被执行的次数。
test.c.gcov
文件内容如下,蓝色表示笔者添加的注释。
-: 0:Source:test.c
-: 0:Graph:test.gcno
-: 0:Data:test.gcda
-: 0:Runs:1
-: 0:Programs:1
-: 1:#include //前面的数字表明该clause被执行的次数,下同
-: 2:
-: 3:int main (void)
1: 4:{
-: 5: int i, total;
-: 6:
1: 7: total = 0;
-: 8:
11: 9: for (i = 0; i < 10; i++) //前面的数字11表明该clause被执行11次
10: 10: total += i;
-: 11:
1: 12: if (total != 45)
#####: 13: printf ("Failure/n");
-: 14: else
1: 15: printf ("Success/n");
1: 16: return 0;
-: 17:}
-: 18:
1.2 gcov的选项
gcov
的选项不多,也好理解,此处选3个典型的选项并结合例子加以说明。
(1) -a, --all-blocks
在.gcov文件中输出每个基本快(basic block)的执行次数。如果没有-a选项,则输出'main'函数这个block的执行次数,如上所示。使用该选项可以
Write individual execution counts for every basic block. Normally gcov outputs execution counts only for the main blocks of a line. With
this option you can determine if blocks within a single line are not being executed.
# gcov -a test.c File 'test.c'
Lines executed:87.50% of 8 //
代码覆盖率
test.c:creating 'test.c.gcov'
Test.c.gcov
文件内容。
-: 0:Source:test.c
-: 0:Graph:test.gcno
-: 0:Data:test.gcda
-: 0:Runs:1
-: 0:Programs:1
-: 1:#include
-: 2:
-: 3:int main (void)
1: 4:{
-: 5: int i, total;
-: 6:
1: 7: total = 0;
-: 8:
11: 9: for (i = 0; i < 10; i++)
1: 9-block 0
10: 9-block 1
11: 9-block 2
10: 10: total += i;
-: 11:
1: 12: if (total != 45)
1: 12-block 0
#####: 13: printf ("Failure/n");
$$$$$: 13-block 0
-: 14: else
1: 15: printf ("Success/n");
1: 15-block 0
1: 16: return 0;
1: 16-block 0
-: 17:}
-: 18:
(2) -b, --branch-probabilities
在.gcov文件中输出每个分支的执行频率,并有分支统计信息。
# gcov -b test.c
File 'test.c'
Lines executed:87.50% of 8
Branches executed:100.00% of 4
Taken at least once:75.00% of 4
Calls executed:50.00% of 2
test.c:creating 'test.c.gcov'
-: 0:Source:test.c
-: 0:Graph:test.gcno
-: 0:Data:test.gcda
-: 0:Runs:1
-: 0:Programs:1
-: 1:#include
-: 2:
-: 3:int main (void)
function main called 1 returned 100% blocks executed 86%
1: 4:{
-: 5: int i, total;
-: 6:
1: 7: total = 0;
-: 8:
11: 9: for (i = 0; i < 10; i++)
branch 0 taken 91%
branch 1 taken 9% (fallthrough)
10: 10: total += i;
-: 11:
1: 12: if (total != 45)
branch 0 taken 0% (fallthrough)
branch 1 taken 100%
#####: 13: printf ("Failure/n");
call 0 never executed
-: 14: else
1: 15: printf ("Success/n");
call 0 returned 100%
1: 16: return 0;
-: 17:}
-: 18:
(3) -c, --branch-counts
在
.gcov
文件中输出每个分支的执行次数。
# gcov -c test.c
File 'test.c'
Lines executed:87.50% of 8
test.c:creating 'test.c.gcov'
-c是默认选项,其结果与"gcov test.c"执行结果相同。
2.lcov
lcov -d . -t ‘Hello test’ -o ‘hello_test.info’ -b . -c 指定lcov
在当前目录“.”去找代码覆盖的信息,输出为’hello_test.info’ ,这个hello_test.info是一个中间结果,需要把它用genhtml来处理一下,genhtml是lcov里面的一个工具。
genhtml -o result hello_test.info 指定输出目录是result。
一个完整的html报告就生成了,做一个连接,把这个目录连到随便一个web server的目录下,就可以看报告了。
3.总结:
gcov是配合gcc产生覆盖信息报告的工具;
lcov是将gcov产生的报告信息,以更直观的方式显示出来工具 基本的使用方法分为4个阶段:
(一)、gcc编译:产生插装后的目标文件test、gcov结点文件 test.gcno #gcc -fprofile-arcs -ftest-coverage -o test test.c # ls
test test.c test.gcno
说明:参数 fprofile-arcs 和 ftest-coverage 告诉gcc编译器:(1)在目标文件test 插装跟踪代码;(2)生成供gcov使用 test.gcno [gcov node 文件]。
因此,这里的生成的目标文件比正常编译的文件大。
(二)、运行目标文件:收集运行覆盖信息 test.gcda # ./test
Success -- 这里是运行结果。 # ls
test test.c test.gcno test.gcda 这里test.gcda运行结果,
(三)、gcov产生报告信息: test.c.gcov #gcov test.c File 'test.c'
Lines executed: 87.50% of 8 test.c: creating 'test.c.gcov' #ls
test test.c test.c.gcov test.gcda test.gcno
(四)、lcov:格式化test.c.gcov ,输出到 test.info文件 #lcov -d . -t 'test' -o 'test.info' -b . -c 说明:
-d . :参数 d指路径, "." 指当前路径 -t "name" :指目标文件,这里 是 test
-o "filename" :输出格式化后的信息文件名
(五)、genhtml:根据信息文件(.info)产生html 文档,输出到一个文件夹中
#genhtml -o result test.info
说明: -o directory :参数o (output)后面跟路径名称,在当前目录下创建指定目录,本例中是result
至此: 可以在result目录中打开index.html 浏览覆盖信息
一.创建测试用例
1.new project->other project ->Qt unit test 2.编写一个单元测试程序 文件列表:
qtestlib/tutorial1/testqstring.cpp qtestlib/tutorial1/tutorial1.pro
假设你要测试QString类的行为。首先,你需要一个用于包含测试函数的类。这个类必须从QObject继承:
class TestQString: public QObject {
Q_OBJECT private slots:
void toUpper(); };
注意你需要包含QTest头文件,并且测试函数必须声明为私有槽,这样测试框架才可以找到并执行他们。
然后你需要实现测试函数。实现看起来类似这样:
QVERIFY()宏将计算传入的表达式的值。如果为真,则测试函数继续进行;否则会向测试日志中增加一条描述错误的信息,并且该测试函数会停止执行。
但是如果需要向测试日志中增加更多的输出信息,你应该使用QCOMPARE()宏: void TestQString::toUpper() {
QString str = “Hello”;
QVERIFY(str.toUpper() == “HELLO”); }
如果两个字符串不相等,他们的值都会追加到测试日志中,这样失败的原因就一目了然了。
最后,为使我们的测试程序能够单独执行,需要加入下列两行: QTEST_MAIN(TestQString)
#include “testqstring.moc”
QTEST_MAIN()宏将扩展成一个简单的main()函数,该main()函数会执行所有的测试函数。注意:如果测试类的声明和实现都在同一个cpp文件中,需要包含产生的moc文件,以使Qt的内省机制起作用。 执行测试程序
运行生成的可执行文件,你会看到下列输出:
********* Start testing of TestQString ********* Config: Using QTest library 4.5.1, Qt 4.5.1 PASS : TestQString::initTestCase() PASS : TestQString::toUpper()
PASS : TestQString::cleanupTestCase() Totals: 3 passed, 0 failed, 0 skipped
********* Finished testing of TestQString *********
三.Mac 下具体配置
1.确保 gcol ,lcol,genhtml 已经安装 2.在工程文件pro中添加
QMAKE_CXXFLAGS += -g -Wall -fprofile-arcs -ftest-coverage -O0 QMAKE_LFLAGS += -g -Wall -fprofile-arcs -ftest-coverage -O0
LIBS += \ -lgcov
3. 创建processCoverage.sh #!/bin/bash
##############################################################################
# Copyright (c) 2013, Robert Wloch
# All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License v1.0 # which accompanies this distribution, and is available at # http://www.eclipse.org/legal/epl-v10.html #
# Contributors:
# Robert Wloch - initial API and implementation
##############################################################################
if [ ! $# -eq 3 ]; then
echo "usage: ${0} <gcov-files-dir> \"<file-pattern>\" <target-dir>" exit 0 fi
lcov -d ${1} -c -o ${1}/coverage.info
lcov --list-full-path -e ${1}/coverage.info ${2} –o ${1}/coverage-stripped.info
genhtml -o ${3} ${1}/coverage-stripped.info
lcov -d ${1} –z
exit 0
QT unit test code coverage的更多相关文章
-
Qt代码覆盖率code coverage(VS版)
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt代码覆盖率code coverage(VS版) 本文地址:http://techi ...
-
Code Coverage and Unit Test in SonarQube
概念 https://blog.ndepend.com/guide-code-coverage-tools/ Code Coverage Results Import (C#, VB.NET) Uni ...
-
10 Code Coverage Tools for C &; C++
Code coverage is a measure used in software testing that describes the degree to which the source co ...
-
Gumshoe - Microsoft Code Coverage Test Toolset
Gumshoe - Microsoft Code Coverage Test Toolset 2014-07-17 What is Gumshoe? How to instrument a binar ...
-
iOS 9 学习系列: Xcode Code Coverage
Code coverage 是一个计算你的单元測试覆盖率的工具. 高水平的覆盖给你的单元測试带来信心.也表明你的应用被彻底的測试过了. 你可能写了几千个单元測试,但假设覆盖率不高.那么你写的这套測试可 ...
-
使用Visual Studio Code Coverage和nunit上传单元测试覆盖率和单元测试结果到SonarQube上
SonarQube.Scanner.MSBuild.exe begin /k:"OMDCCQuotes" /d:sonar.host.url="http://myip:9 ...
-
[Jest] Track project code coverage with Jest
Jest comes pre-packaged with the ability to track code coverage for the modules you're testing, but ...
-
Effective Java提升Code Coverage代码涵盖率 - 就是爱Java
虽然我们已经有了测试程序,但是如何得知是否已完整测试了主程序?,透过Code Coverage代码涵盖率,我们可以快速地得知,目前系统中,有多少程序中被测试过,不考虑成本跟投资效益比,涵盖率越高,代表 ...
-
CI集成phpunit Error: No code coverage driver is available 的解决
CI集成phpunit时,运行报No code coverage driver is available的错误,如下图: yanglingdeMacBook-Pro:tests yangling$ p ...
随机推荐
-
word search puzzle
package WordSearch; import java.util.ArrayList; import java.util.HashMap; import java.io.*; public c ...
-
eclipse中jre system library ,web app libraries,referenced libraries,user libraries
在eclipse ide中进行开发时,为了方面jar的管理用了user libraries,但是遇到了一些问题,对于其中jre system library ,web app libraries,re ...
-
普通View的measure流程
对于普通的view,其测量在ViewGroup中的measureChildWithMargins函数中调用child view的measure开始测量. 1:从measure函数开始 public f ...
-
MySQL数据库恢复(使用mysqlbinlog命令)
binlog是通过记录二进制文件方式来备份数据,然后在从二进制文件将数据恢复到某一时段或某一操作点. 1:开启binlog日志记录 修改mysql配置文件mysql.ini,在[mysqld]节点下添 ...
-
FastRPC 3.2 发布,高性能 C++ 协程 RPC 框架
用过go erlang gevent的亲们应该都会知道协程在应用中带来的方便. 如果对协程不理解的同学,通过阅读下面例子可以快速了解我们框架的协程的意义,已了解的可以跳过这部分. 协程例子:假设我们要 ...
-
Lazy Scheduler
Lazy Scheduler:我的轻量级任务调度框架 一.背景 工作中经常涉及任务调度,一直都是采用while(true) => if hitted DO => Thread.Slee ...
-
Linux将端口设置进防火墙的白名单
1.先检查linux服务器的端口是否被防火墙拦住 `telnet 172.168.1.101 8080后面跟端口号,如果连接上证明是防火墙白名单.如果没有配置 vi /etc/sysconfig/ip ...
-
Centos7上vsftp脚本-->; sh vsftp.sh 用户名 密码 -->; sh vsftp.sh install
#!/bin/bash #vsftp install . /etc/rc.d/init.d/functions users=/etc/vsftpd/vftpuser.txt login=/etc/vs ...
-
JavaScript:Array属性方法
,,,,]; console.dir(arr); var pro=Object.getPrototypeOf(arr); console.dir(pro); 来一个个的查看数组的属性,方法 1.Arr ...
-
php--------删除数组的第一个元素和最后一个元素
对于一个php数组,该如何删除该数组的第一个元素或者最后一个元素呢?其实这两个过程都可以通过php自带的函数 array_pop 和 array_shift 来完成,下面就具体介绍一下如何来操作. ( ...