gtest基础使用12:Google Test自带示例九:Custom

本文档介绍了如何利用GoogleTest的listener API自定义控制台输出,以及使用reflection API检查测试用例执行结果。示例代码展示了如何创建TersePrinter类以简化测试输出,并尝试剔除预期失败的用例不影响整体测试结果。在Visual Studio 2019环境下,由于缺少特定参数导致定制功能未能生效,同时文章也提及了对多个main()函数的疑惑。
摘要由CSDN通过智能技术生成

Google Test Sample09:定制化控制台输出_listener API 及 检查用例执行结果_reflection API v0.6

一、环境信息

  1. Visual Studio 2019
  2. Windows 10

二、Google Test Sample09

1. 示例概述

1.1 sample09演示了如何使用Google Test的两个API:listener 和 reflection
1.2 listener API可以用于实现控制台的定制化输出。这里的 console output就是指用例的执行结果窗体打印的信息(如下所示),按示例的方法可以进行定制化
在这里插入图片描述
1.3 reflection API可以检查测试用例的执行结果。sample09展示了如何在统计中剔除 预期结果触发Fail的用例,以便保障 注定失败的测试不会影响测试程序的结果

2. 目前的问题(原因已查明,待解决)

2.1 sample09目前可以编译并正常执行,但是代码中的两个预定目标均没有实现:(1) 定制控制台输出 (2) 剔除 预期结果是触发Fail的用例 。
原因分析:需要带参数运行gtest(文中定义的是 --terse_output),但是在VS 2019默认条件下,不会带参数执行
2.2 示例9并没有讲解具体的单元测试、主要是gtest API的使用,因此个人决定先跳过遇到的问题,等实际用到了再说
2.3 示例9中撰写了 main()函数 int main(int argc, char** argv) {…} ,他为什么没有造成多main()函数的冲突:VS gtest工程自带main(),这个在后面也需要研究一下
在这里插入图片描述

3. sample09UnitTest.cpp

3.1 详细代码及个人注释如下
3.2 执行结果:并未实现定制化打印信息、预期触发Fail的用例也没有排除 ╮(╯▽╰)╭
在这里插入图片描述

#include "pch.h"
// This sample shows how to use Google Test listener API to implement an alternative console output
// and how to use the UnitTest reflection API to enumerate test cases and tests and to inspect their results.
// 示例展示了如何使用gtest监听接口去实现一个替换的控制台输出、如何使用gtest reflection接口去枚举测试用例和检查测试结果?
#include <stdio.h>

using ::testing::EmptyTestEventListener;
using ::testing::InitGoogleTest;
using ::testing::Test;
using ::testing::TestCase;
using ::testing::TestEventListeners; // TestEventListeners and EmptyTestEventListener
using ::testing::TestInfo; //TestInfo?
using ::testing::TestPartResult; //TestPartResult
using ::testing::UnitTest; //UnitTest?

namespace
{
    //Provides alternative output mode which produces minimal amount of information about tests.
    //提供可改变的输出模式,该模式生成最小数量的测试信息

    class TersePrinter : public EmptyTestEventListener  //Terse equal brief ,类TersePrinter是为定制化控制台输出而创建的
    { 
    private:
        // Called before any test activity starts. //任何测试活动启动前调用
        void OnTestProgramStart(const UnitTest& /* unit_test */) override {} //此处没有任何信息输出

        // Called after all test activities have ended. //所有测试结束后调用
        void OnTestProgramEnd(const UnitTest &unit_test) override // 用到了引用。reference是i的引用 int i; int &reference = i; 
        {
            fprintf(stdout, "TEST 123 456 789 %s\n", unit_test.Passed() ? "PASSED" : "FAILED"); 
            fflush(stdout);
        }

        // Called before a test starts.//在一条测试用例开始前调用
        void OnTestStart(const TestInfo& test_info) override
        {
            fprintf(stdout, "Test %s.%s starting\n", test_info.test_case_name(), test_info.name());
            fflush(stdout);
        }

        // Called after a failed assertion or a SUCCEED() invocation. //在 一个失败的断言 或 SUCCEED()函数触发 后调用
        void OnTestPartResult(const TestPartResult &test_part_result) override
        {
            fprintf(stdout,
                "%s in %s:%d\n%s\n",
                test_part_result.failed() ? "Failure" : "Success",
                test_part_result.file_name(),
                test_part_result.line_number(),
                test_part_result.summary());

            fflush(stdout);
        }

        // Called after a test ends.
        void OnTestEnd(const TestInfo &test_info) override
        {
            fprintf(stdout, "Test %s.%s ending.\n",
                test_info.test_case_name(),
                test_info.name());
            fflush(stdout);
        }
    };  // class TersePrinter 重新定义了控制台输出信息

    TEST(CustomOutputTest, PrintsMessage) //通过宏TEST撰写的用例
    {
        printf("Printing something from the test body...\n");
    }

    TEST(CustomOutputTest, Succeeds)
    {
        SUCCEED() << "SUCCEED() has been invoked from here";
    }

    TEST(CustomOutputTest, Fails) //本条用例预期结果一定Fail,他用来配合gtest reflection接口定制化演示。 //但是实际未达成预定效果 原因不清楚
    {
        EXPECT_EQ(2, 3) << "This test fails in order to demonstrate alternative failure messages.";
    }
}  // namespace

int main(int argc, char** argv) // char** argv?  argc,argv?  //上面的类TersePrinter重新定义了控制台输出信息
{
    InitGoogleTest(&argc, argv); //InitGoogleTest?   &argc, argv?

    bool terse_output = false; //terse mean brief
    if (argc > 1 && strcmp(argv[1], "--terse_output") == 0)
        terse_output = true; //strcmp(str1,str2),若str1=str2,则返回零;若str1<str2,则返回负数;若str1>str2,则返回正数
    else
        printf("%s\n", "Run this program with --terse_output to change the way it prints its output.");

    UnitTest &unit_test = *UnitTest::GetInstance(); //?

    // If we are given the --terse_output command line flag, suppresses the standard output and attaches own result printer.
    // 如果按自定义的输出格式打印测试结果,需要阻止gtest的标准输出并attach自定义的result printer
    if (terse_output)
    {
        TestEventListeners &listeners = unit_test.listeners(); 

        // Removes the default console output listener from the list so it will not receive events from Google Test and won't print any output. 
        // Since this operation transfers ownership of the listener to the caller we have to delete it as well.
        // 从listeners列表中删除默认的控制台输出监听器
        delete listeners.Release(listeners.default_result_printer());

        // Adds the custom output listener to the list. It will now receive events from Google Test and print the alternative output.
        // We don't have to worry about deleting it since Google Test assumes ownership over it after adding it to the list.
        // 添加自定义的用例的输出信息 TersePrinter 到listeners列表,以便进行定制化输出打印。不需要考虑TersePrinter的释放

        listeners.Append(new TersePrinter);
    }
    //上面就是gtest listener API的示例。listener接口可用于定制化控制台输出,以便打印定制化的用例执行信息


    //下面是 gtest reflection接口使用演示:要达成一个什么样的目的,还不是很清楚
    // -- reflection API : enumerate test cases and tests and to inspect their results
    // reflection接口可以用于检查测试结果。但是目前不明确reflection接口包含哪些子类、函数
    int ret_val = RUN_ALL_TESTS(); //RUN_ALL_TESTS()统计了测试用例条数吧?
    // This is an example of using the UnitTest reflection API to inspect test results. Here we discount failures from the tests we expected to fail.
    // 使用 gtest reflection接口检查测试结果。不理会测试中的失败用例 (这些用例的预期就是失败的) discount 不理会
    int unexpectedly_failed_tests = 0; // unexpectedly_failed_tests 未预期失败的用例个数
    
    //for循环应该是用来遍历所有用例的执行结果
    for (int i = 0; i < unit_test.total_test_case_count(); ++i) //under VS2019,use total_test_case_count
    {
        const TestCase &test_suite = *unit_test.GetTestCase(i); //赋值操作 但用义不明?  unit_test 对应测试用例集?

        for (int j = 0; j < test_suite.total_test_count(); ++j)
        {
            const TestInfo &test_info = *test_suite.GetTestInfo(j);//赋值操作 但用义不明? test_suite对应单条测试用例?
            // Counts failed tests that were not meant to fail (those without 'Fails' in the name).
            
            // 统计执行失败的用例(不包括已知预期失败的用例 这些用例已打上了标签Fails)
            if (test_info.result()->Failed() && strcmp(test_info.name(), "Fails") != 0) // TEST(CustomOutputTest, Fails){}
                unexpectedly_failed_tests++;
        }
    }

    // Test that were meant to fail should not affect the test program outcome.
    // 注定失败的测试不应该影响测试程序的结果
    if (unexpectedly_failed_tests == 0)
        ret_val = 0;

    return ret_val;
} //End

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值