java单元测试覆盖率_android单元测试覆盖率

java单元测试覆盖率_android单元测试覆盖率一、简介之所以叫温故而知新,是因为将这两个工具结合起来作为单元测试工具的想法在上一个项目中应用了,好像还没有人将这两种工具结合使用,或者没有写成博客供大家参考,现在重新温习下将想法写下来。gtest单元测试工具接触过的人都很熟悉了,它是一款google提供的强大的测试框架,测试案例的编写也比较简单,gtest案例的编写可以参考系列博文:http://www.cn…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

一、简介  

     之所以叫温故而知新,是因为将这两个工具结合起来作为单元测试工具的想法在上一个项目中应用了,好像还没有人将这两种工具结合使用,或者没有写成博客供大家参考,现在重新温习下将想法写下来。

    gtest单元测试工具接触过的人都很熟悉了,它是一款google提供的强大的测试框架,测试案例的编写也比较简单,gtest案例的编写可以参考系列博文:http://www.cnblogs.com/coderzh/archive/2009/03/31/1426758.html

    lcov代码覆盖率统计工具,是gcov的延伸版本,提供程序实际执行的信息(统计某行代码被执行的次数),其基于HTML的输出通过浏览器以清晰的图表形式呈现覆盖率统计结果。locv相关详细介绍可以参考博文:https://my.oschina.net/alphajay/blog/33725

二、gtest环境的搭建步骤:

(1)下载源码包搭建:

参考博文:http://www.linuxidc.com/Linux/2015-05/116894.htm。

我是按照这篇博客的步骤下载源码将多余的目录删除最后在gtest_tool目录下只剩下两个核心代码目录:

java单元测试覆盖率_android单元测试覆盖率

(2)直接输入命令安装: sudo apt-get install libgtest-dev

三、lcov工具的安装:

(1)下载源码包:http://ltp.sourceforge.net/coverage/lcov.php

(2)解压:tar xvzf lcov-1.11.tar.gz

(3)cd lcov-1.11

(4)如果是交叉编译移植到实机上需要执行这步:

修改文件:lcov-1.11/bin/genifo
                    vim lcov-1.11/bin/genifo
然后将第65行的:our $gcov_tool = “gcov” 改为自己的交叉编译器的gcov

比如我的交叉编译工具是/usr/local/arm/4.3.2/bin/arm-linux-gcc
那么就改为:our $gcov_tool = “/usr/local/arm/4.3.2/bin/arm-linux-gcov”

可以使用:find / -name *gcov来查找下自己的交叉编译工具在什么目录下

(5)sudo make install

注:除了下载源码包还可以执行下面两条命令安装:

           sudo apt-get install lcov

           sudo apt-get install ggcov

四、将两者结合使用实例

环境搭建好后可以开心得玩耍了 哈哈

(1)首先了解下我需要测试的代码模型:

代码到我的github上下载:https://github.com/fanchenxinok/gtest-lcov

java单元测试覆盖率_android单元测试覆盖率

说明:这是我自己写的简单的消息传递及监听模型测试代码。messageModelLib目录是消息传递模型的核心代码,

编译出来一个.so库供该目录的其他模块使用。messageModelLib目录内容如下:

java单元测试覆盖率_android单元测试覆盖率

(2)重点是gtest_lcov目录,该目录是专门用来进行单元测试的,目录内容如下:

java单元测试覆盖率_android单元测试覆盖率

说明:gtest_tool 为gtest源码的删减版,lcov-1.11为lcov源码包编译后的目录,lcov_out为自己建的目录用来存放lcov工具统计出的结果的输出。test_case.c为编写的测试用例,内容如下:

// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// A sample program demonstrating using Google C++ testing framework.
//
// Author: wan@google.com (Zhanyong Wan)


// This sample shows how to write a simple unit test for a function,
// using Google C++ testing framework.
//
// Writing a unit test using Google C++ testing framework is easy as 1-2-3:


// Step 1. Include necessary header files such that the stuff your
// test logic needs is declared.
//
// Don't forget gtest.h, which declares the testing framework.

#include <limits.h>
#include "gtest/gtest.h"

#include "myComDef.h"
#include "responser12.h"
#include "listener12.h"

extern "C" {
	#include "log_out.h"
}



// Step 2. Use the TEST macro to define your tests.
//
// TEST has two parameters: the test case name and the test name.
// After using the macro, you should define your test logic between a
// pair of braces.  You can use a bunch of macros to indicate the
// success or failure of a test.  EXPECT_TRUE and EXPECT_EQ are
// examples of such macros.  For a complete list, see gtest.h.
//
// <TechnicalDetails>
//
// In Google Test, tests are grouped into test cases.  This is how we
// keep test code organized.  You should put logically related tests
// into the same test case.
//
// The test case name and the test name should both be valid C++
// identifiers.  And you should not use underscore (_) in the names.
//
// Google Test guarantees that each test you define is run exactly
// once, but it makes no guarantee on the order the tests are
// executed.  Therefore, you should write your tests in such a way
// that their results don't depend on their order.
//
// </TechnicalDetails>


// Tests Factorial().

// Tests factorial of negative numbers.

static responser1 res1_instance;
static responser2 res2_instance;

static listener1 lis1_instance;
static listener2 lis2_instance;


TEST(apl_registResponserTest, isTrue)
{
	ASSERT_EQ(TRUE, apl_registResponser(RES1, RES_MID, &res1_instance));
       ASSERT_EQ(TRUE, apl_registResponser(RES2, RES_HIGH, &res2_instance));
}


TEST(apl_registListenerTest, isTrue)
{
    ASSERT_EQ(TRUE, apl_registListener(RES1, &res1_instance, &lis1_instance));
    ASSERT_EQ(TRUE, apl_registListener(RES2, &res2_instance, &lis2_instance));
}


TEST(loop_send_test, isRight)
{
    int n = 0;
    while(n < 10)
    {
        MSG_INFO msgInfo;
        char msgData[128];

        msgInfo.resType = RES1;  //设置动作对象
        msgInfo.msg.eventID = R1_FUN1; //设置应该做什么动作
        EXPECT_EQ(TRUE, apl_sendMessage(RES1, R1_FUN1, msgData)); //发送开始消息及动作参数

        //apl_unRegistResponser(RES1);

        msgInfo.msg.eventID = R1_FUN2;
        int a = 10, b = 122;
        apl_msgPacker(msgData,sizeof(int), &a,sizeof(int), &b, -1);
        EXPECT_EQ(TRUE, apl_sendMessage(RES1, R1_FUN2, msgData));

        msgInfo.resType = RES2;
        msgInfo.msg.eventID = R2_FUN1;
        double c = 4.23, d = 2.32;
        apl_msgPacker(msgData,sizeof(double), &c,sizeof(double), &d, -1);
        EXPECT_EQ(TRUE, apl_sendMessage(RES2, R2_FUN1, msgData));

        msgInfo.msg.eventID = R2_FUN2;
        a = 20;
        b = 30;
        apl_msgPacker(msgData,sizeof(int), &a,sizeof(int), &b, -1);
        EXPECT_EQ(TRUE, apl_sendMessage(RES2, R2_FUN2, msgData));

        sleep(1);
        ++n;
    }
}


// Step 3. Call RUN_ALL_TESTS() in main().
//
// We do this by linking in src/gtest_main.cc file, which consists of
// a main() function which calls RUN_ALL_TESTS() for us.
//
// This runs all the tests you've defined, prints the result, and
// returns 0 if successful, or 1 otherwise.
//
// Did you notice that we didn't register the tests?  The
// RUN_ALL_TESTS() macro magically knows about all the tests we
// defined.  Isn't this convenient?

主要测试三个case,消息回应者、对应监听器的注册和消息的传递和监听。

编写好test_case.c以后文件以后,关键的关键就是makefile的编写了,我的makefile是gtest源码包example测试makefile基础上修改的,内容如下:

# A sample Makefile for building Google Test and using it in user
# tests.  Please tweak it to suit your environment and project.  You
# may want to move it to your project’s root directory.
#
# SYNOPSIS:
#
#   make [all]  – makes everything.
#   make TARGET – makes the given target.
#   make clean  – removes all files generated by make.

# Please tweak the following variable definitions as needed by your
# project, except GTEST_HEADERS, which you can use in your own targets
# but shouldn’t modify.

# Points to the root of Google Test, relative to where this file is.
# Remember to tweak this if you move this file.
GTEST_DIR = ./gtest_tool  #gtest 源码所在目录
XX = g++
CC = gcc
# Where to find user code.
USER_DIR = ..  #测试代码所在目录

# Flags passed to the preprocessor.
# Set Google Test’s header directory as a system directory, such that
# the compiler doesn’t generate warnings in Google Test headers.
CPPFLAGS += -isystem $(GTEST_DIR)/include

# Flags passed to the C++ compiler.
CXXFLAGS += -g -Wall -Wextra -pthread
CXXFLAGS2 += -g -Wall -Wextra -pthread -fprofile-arcs -ftest-coverage #多了两个编译选项
# All tests produced by this Makefile.  Remember to add new tests you
# created to the list.
TARGET = appMain

# the link library you should change according to your need
LINK_LIB = -L$(USER_DIR)/lib -lSendMsgModel -lpthread -lrt

# All Google Test headers.  Usually you shouldn’t change this
# definition.
GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \
                $(GTEST_DIR)/include/gtest/internal/*.h

# House-keeping build targets.

all : $(TARGET)

# Builds gtest.a and gtest_main.a.

# Usually you shouldn’t tweak such internal variables, indicated by a
# trailing _.
GTEST_SRCS_ = $(GTEST_DIR)/src/*.cc $(GTEST_DIR)/src/*.h $(GTEST_HEADERS)

# For simplicity and to avoid depending on Google Test’s
# implementation details, the dependencies specified below are
# conservative and not optimized.  This is fine as Google Test
# compiles fast and for ordinary users its source rarely changes.
gtest-all.o : $(GTEST_SRCS_)
    g++ $(CPPFLAGS) -I$(GTEST_DIR) -c \
            $(GTEST_DIR)/src/gtest-all.cc

gtest_main.o : $(GTEST_SRCS_)
    g++ $(CPPFLAGS) -I$(GTEST_DIR) -c \
            $(GTEST_DIR)/src/gtest_main.cc

gtest.a : gtest-all.o
    $(AR) $(ARFLAGS) $@ $^

gtest_main.a : gtest-all.o gtest_main.o
    $(AR) $(ARFLAGS) $@ $^

# Builds a sample test.  A test should link with either gtest.a or
# gtest_main.a, depending on whether it defines its own main()
# function.
    
XX_SOURCES = $(wildcard $(USER_DIR)/myListeners/*.cpp $(USER_DIR)/myResponsers/*.cpp)
CC_SOURCES = $(wildcard $(USER_DIR)/logout/*.c)

XX_OBJECTS = $(patsubst %.cpp,%.o,$(XX_SOURCES))
CC_OBJECTS = $(patsubst %.c,%.o,$(CC_SOURCES))

INCLUDE_DIRS = -I$(USER_DIR)/include -I$(USER_DIR)/myListeners -I$(USER_DIR)/myResponsers -I$(USER_DIR)/logout

TEST_CASE_O = ./test_case.o #gtest 测试案例

 $(TEST_CASE_O) : %.o : %.c
    $(XX) -c $(CPPFLAGS) $< -o $@ $(INCLUDE_DIRS)
    
$(CC_OBJECTS) : %.o : %.c
    $(CC) -c $(CXXFLAGS2) $< -o $@ $(INCLUDE_DIRS)  #需要用lcov查看哪个文件的代码覆盖率,编译的时候就加上-fprofile-arcs -ftest-coverage编译选项

$(XX_OBJECTS) : %.o : %.cpp
    $(XX) -c $(CXXFLAGS2) $< -o $@ $(INCLUDE_DIRS)

$(TARGET) : $(XX_OBJECTS) $(CC_OBJECTS) $(TEST_CASE_O) gtest_main.a
    $(XX) $(CXXFLAGS2) $^ -o $@ $(LINK_LIB)

#删除代码目录的 *.gcda,*.gcno和*.o文件
SUBDIRS = $(USER_DIR)/myListeners $(USER_DIR)/myResponsers $(USER_DIR)/logout
GCDA_FILES = $(foreach dir, $(SUBDIRS), $(wildcard $(dir)/*.gcda))
GCNO_FILES = $(foreach dir, $(SUBDIRS), $(wildcard $(dir)/*.gcno))
OBJS_FILES = $(foreach dir, $(SUBDIRS), $(wildcard $(dir)/*.o))

clean :
    rm -rf $(TARGET) gtest.a gtest_main.a *.o *.gcno *.gcda *.info lcov_out/* \
    $(GCDA_FILES) $(GCNO_FILES) $(OBJS_FILES)

java单元测试覆盖率_android单元测试覆盖率

java单元测试覆盖率_android单元测试覆盖率

执行完后也会在生成gcon文件的目录下生成gcda文件。

java单元测试覆盖率_android单元测试覆盖率

(6)最后把测试的命令(1~5)命令写到run.sh脚本里,执行./run.sh就ok了。

#! /bin/bash
cd ..
make clean
cd ./gtest_lcov
make clean
sudo rm -rf ./lcov_out/*
make
./appMain

./lcov-1.11/bin/lcov -d ../ -t ‘appMain’ -o’appMain.info’ -b . -c
./lcov-1.11/bin/genhtml appMain.info –quiet –output-directory lcov_out–title “appMain”
firefox ./lcov_out/index.html

(7)覆盖率统计图表:

java单元测试覆盖率_android单元测试覆盖率

java单元测试覆盖率_android单元测试覆盖率

至此,gtest单元测试工具和lcov覆盖率统计工具的结合使用介绍完毕,共同学习进步。

代码github仓库:https://github.com/fanchenxinok/gtest-lcov

2022/6/20: 更新run.sh脚本,将不需要关心覆盖率的头文件去掉。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/187834.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • win32API中文参考手册[通俗易懂]

    win32API中文参考手册[通俗易懂]中文在线手册:http://www.yfvb.com/help/win32sdk/下面也是中文手册chm版,排版不是很好蓝奏云下载:https://wws.lanzous.com/iw8E3fhlz5icsdn下载:https://download.csdn.net/download/weixin_43833642/12434848[会自动长积分]如果是初学,上面的api勉强够用,建议参考着原版英文一起学习!最后如果帮到你可以点个赞!感谢!…

    2022年10月11日
  • 局域网与广域网详解区别_广域网有哪些

    局域网与广域网详解区别_广域网有哪些1.局域网  局域网,英文名字LocalAreaNetwork,缩写为LAN。是指在某一区域内由多台计算机互联成的计算机组。一般是方圆几千米以内。局域网是封闭型的,可以由办公室内的两台计算机组成,也可以由一个公司内的上千台计算机组成。生活中我们的每一个学校、公司都是一个局域网局域网可以理解为我们自己使用路由器、交换机组成的内部网络这个网络实现的是内部机器的通信,比如咱们访问学校的…

    2022年10月19日
  • SQL SERVER 中的smalldatetime和datetime区别「建议收藏」

    SQL SERVER 中的smalldatetime和datetime区别「建议收藏」SQLSERVER中的smalldatetime和datetime区别Postedon 2011-01-0410:43 Rainbow.ding 阅读(2371)评论(0) 编辑 收藏 smalldatetime不能到秒. 不過它占的空間小.(4位) datetime(8位) 而且兩者的時間範圍不一樣.   datetime占8字节,精度3.3

  • 深入理解Java虚拟机——JVM垃圾回收机制和垃圾收集器详解

    深入理解Java虚拟机——JVM垃圾回收机制和垃圾收集器详解说起垃圾回收(GarbageCollection,GC),很多人就会自然而然地把它和Java联系起来。在Java中,程序员不需要去关心内存动态分配和垃圾回收的问题,顾名思义,垃圾回收就是释放垃圾占用的空间,这一切都交给了JVM来处理。本文主要解答三个问题:1、哪些内存需要回收?(对象是否可以被回收的两种经典算法:引用计数法和可达性分析算法) 2、如何回收?

  • sd/tf卡槽是什么_usb电源线接法图解

    sd/tf卡槽是什么_usb电源线接法图解SDIO接线作为SD的4-bit传输模式下的接法,在RK3399上的应用,实现双TF卡无法识别闪迪卡解决办法1.硬件接线图如上图是SDIO接口接为TF接口的电路实现双TF卡功能,模式是4-bit,注意22R电阻要加上,尽量靠近3399摆放,但是调试的时候遇到一个问题,其他类型卡都可以识别,唯独闪迪卡无法识别,找了很久,最后发现TF卡电源VDD需要接3V0才可以解决。2,查看了资料,发现VDD关系到读卡的电压问题,如下图,闪迪卡在插入的时候会告知系统是否需要切换1.8…

  • 使用Ubuntu搭建Web服务器

    使用Ubuntu搭建Web服务器Docker是一个开源的应用容器引擎,基于Go语言并遵从Apache2.0协议开源。Docker可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似iPhone的app),更重要的是容器性能开销极低。总而言之,Docker相当于在你的电脑上建了一个虚拟机…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号