Android 源码单体测试 -2 C++ gtest 测试

  • 第一步安装lcov与gcov用来去实现覆盖率统计:
 sudo apt-get install lcov
 sudo apt-get install ggcov
 lcov --version  //查看lcov ,正确输出版本号即安装成功
 gcov --version  //查看gcov版本号 ,与g++ ,gcc版本号一致
  • gtest Code编写,在所测试的Service文件夹下创建tests文件夹,编写gtestcode.一般就是Android.mk文件以及测试cpp文件
    demo代码(MediaPlayerService.cpp新增函数测试):
    Android.mk
# Build the unit tests.
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := gtstmediaplayerservice

LOCAL_SRC_FILES := \
    TestMain.cpp \
    TestMediaPlayerService.cpp \

LOCAL_STATIC_LIBRARIES := libgtest_main libgtest

LOCAL_SHARED_LIBRARIES := \
    liblog \
    libmedia \
    libmediaplayerservice \
    libmediadrm \
    libutils \
    libaudioclient \
    android.hardware.drm@1.0 \

LOCAL_C_INCLUDES := \
            external/googlemock/include/ \
            external/googletest/include/ \
            external/icu4c/common \
            external/protobuf/src/ \
            system/core/include \
            system/media/audio/include \
            frameworks/av/media/libaudioclient/include \
        frameworks/av/include \
        frameworks/av/media/libmediaplayerservice \

LOCAL_CFLAGS := -O2 -fno-access-control -Wno-unused-parameter

LOCAL_LDLIBS := -ldl

LOCAL_32_BIT_ONLY := true

LOCAL_MODULE_TAGS := tests

include $(BUILD_EXECUTABLE)

TestMain.cpp

#include <gtest/gtest.h>

namespace android
{
    int main(int argc, char** argv)
    {
        ::testing::InitGoogleTest(&argc, argv);
        int ret = RUN_ALL_TESTS();
        return ret;
    }
}

TestMediaPlayerService.h

#ifndef TESTMEDIAPLAYERSERVICE_H
#define TESTMEDIAPLAYERSERVICE_H


#ifndef __cplusplus
#   error ERROR: This file requires C++ compilation (use a .cpp suffix)
#endif

#include <gtest/gtest.h>

#ifndef ANDROID_MEDIAPLAYERSERVICE_H
#include "MediaPlayerService.h"
#endif

#include <media/mediaplayer.h>

namespace android
{

    /**
     * class TestMediaPlayerService
     *
     * @brief gtst
     */

    class TestMediaPlayerService : public testing::Test 
    {
        public:
            TestMediaPlayerService() {}
            virtual ~TestMediaPlayerService() {}

            void SetUp();
            void TearDown();

            static void SetUpTestCase();
            static void TearDownTestCase();

        private:
            sp<MediaPlayerService> m_MediaPLayerService;
            sp<MediaPlayer> m_MediaPLayer;
            sp<IMediaPlayer> m_Client;

    };
};

#endif

TestMediaPlayerService.cpp

#include <cutils/log.h>
#ifndef TESTMEDIAPLAYERSERVICE_H
#include "TestMediaPlayerService.h"
#endif

#include <media/AudioSystem.h>

#ifdef LOG_TAG
#undef LOG_TAG
#endif
#define LOG_TAG "MediaPlayerServiceTest"

#define FLAGS O_RDWR | O_APPEND

namespace android
{
    void TestMediaPlayerService::SetUp()
    {
        m_MediaPLayer = new MediaPlayer();
        m_MediaPLayerService = new MediaPlayerService();
        audio_session_t session_id = (audio_session_t) AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
        m_Client = m_MediaPLayerService->create(m_MediaPLayer, session_id);
    }

    void TestMediaPlayerService::TearDown()
    {
    }

    void TestMediaPlayerService::SetUpTestCase()
    {

    }

    void TestMediaPlayerService::TearDownTestCase()
    {

    }

    TEST_F(TestMediaPlayerService, setTokenName)
    {
        EXPECT_EQ(UNKNOWN_ERROR, m_Client->setTokenName(String8("com.suntec.test")));
        int fd = open("/storage/emulated/0/a.mp3", FLAGS);
        m_Client->setDataSource(fd, 0, 0x7fffffffffLL);
        m_Client->prepareAsync();
        sleep(2);
        EXPECT_EQ(NO_ERROR, m_Client->setTokenName(String8("com.suntec.test")));
        m_Client->start();
        sleep(2);
    }

    TEST_F(TestMediaPlayerService, enableAutoFadeForUnderRun)
    {
        EXPECT_EQ(UNKNOWN_ERROR, m_Client->enableAutoFadeForUnderRun(true, 0));
        int fd = open("/storage/emulated/0/a.mp3", FLAGS);
        m_Client->setDataSource(fd, 0, 0x7fffffffffLL);
        m_Client->prepareAsync();
        sleep(2);
        EXPECT_EQ(NO_ERROR, m_Client->enableAutoFadeForUnderRun(true, 0));
        m_Client->start();
        sleep(2);
    }

    TEST_F(TestMediaPlayerService, setFadeIn)
    {
        EXPECT_EQ(UNKNOWN_ERROR, m_Client->setFadeIn(true));
        int fd = open("/storage/emulated/0/a.mp3", FLAGS);
        m_Client->setDataSource(fd, 0, 0x7fffffffffLL);
        m_Client->prepareAsync();
        sleep(2);
        EXPECT_EQ(NO_ERROR, m_Client->setFadeIn(true));
        m_Client->start();
        sleep(2);
    }

}
  • 所测试的Service的Android.mk文件需要新增编译选项,是lcov生效
ifeq ($(utcoverage), yes)
LOCAL_STATIC_LIBRARIES += libgcov libprofile_rt
LOCAL_CFLAGS += -g3 -o0 -fprofile-arcs -ftest-coverage -Xclang -coverage-cfg-checksum -Xclang -coverage-no-function-names-in-data -Xclang -coverage-version='504*'
LOCAL_CLINKER := -fprofile-arcs -ftest-coverage
endif
  • 添加完毕后进行编译,会在out目录下生成相应的*.gcno文件,如MediaPlayerService.gcno文件
  • 将编译出来的test可执行文件push进机器中,运行,会生成相应的*.gcda文件(需要在测试mk文件中将文件include进来)
  • 将gcno文件与gcda文件放入同一目录下(测试代码目录下),执行如下两个命令
lcov -c -d ./ -o index.info //生成中间文件
genhtml index.info -o result //生成HTML文件
  • 至此就可以打开HTML文件查看覆盖率了.
    原文作者:伪乐观的W先生
    原文地址: https://www.jianshu.com/p/74b3439131b6
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞