zoukankan      html  css  js  c++  java
  • Google C++单元测试框架GoogleTest---Extending Google Test by Handling Test Events

    Google TestExtending Google Test by Handling Test Events

    Google测试提供了一个事件侦听器API,让您接收有关测试程序进度和测试失败的通知。 可以监听的事件包括测试程序的开始和结束,测试用例或测试方法等。 您可以使用此API来扩充或替换标准控制台输出,替换XML输出,或提供完全不同的输出形式,例如GUI或数据库。 例如,您还可以使用测试事件作为检查点来实现资源泄漏检查器。

    一、定义事件侦听器

    要定义一个事件监听器,你需要继承testing :: TestEventListener或testing :: EmptyTestEventListener。前者是一个(抽象)接口,其中每个纯虚方法
    可以重写以处理测试事件(例如,当测试开始时,将调用OnTestStart()方法。)。后者提供了接​​口中所有方法的空实现,使得子类只需要覆盖它关心的方法。

    当一个事件触发时,它的上下文作为参数传递给处理函数。使用以下参数类型

    • UnitTest反映整个测试程序的状态,
    • TestCase包含关于一个测试用例的信息,它可以包含一个或多个测试,
    • TestInfo包含测试的状态,和
    • TestPartResult表示测试断言的结果。

    事件处理函数可以检查它接收的参数,以找到关于事件和测试程序状态的有趣信息。这里有一个例子:

    class MinimalistPrinter : public ::testing::EmptyTestEventListener {
        // Called before a test starts.
        virtual void OnTestStart(const ::testing::TestInfo& test_info) {
          printf("*** Test %s.%s starting.
    ",
                 test_info.test_case_name(), test_info.name());
        }
    
        // Called after a failed assertion or a SUCCEED() invocation.
        virtual void OnTestPartResult(
            const ::testing::TestPartResult& test_part_result) {
          printf("%s in %s:%d
    %s
    ",
                 test_part_result.failed() ? "*** Failure" : "Success",
                 test_part_result.file_name(),
                 test_part_result.line_number(),
                 test_part_result.summary());
        }
    
        // Called after a test ends.
        virtual void OnTestEnd(const ::testing::TestInfo& test_info) {
          printf("*** Test %s.%s ending.
    ",
                 test_info.test_case_name(), test_info.name());
        }
      };
    

    二、使用事件监听器

    要使用您定义的事件侦听器,请将其实例添加到Google Test事件侦听器列表中(由TestEventListeners类表示)

    • note the "s" at the end of the name) in your main() function, before calling RUN_ALL_TESTS():
    int main(int argc, char** argv) {
      ::testing::InitGoogleTest(&argc, argv);
      // Gets hold of the event listener list.
      ::testing::TestEventListeners& listeners =
          ::testing::UnitTest::GetInstance()->listeners();
      // Adds a listener to the end.  Google Test takes the ownership.
      listeners.Append(new MinimalistPrinter);
      return RUN_ALL_TESTS();
    }
    

      只有一个问题:默认测试结果打印机仍然有效,因此其输出将与您的简约打印机的输出混合。 要禁止默认打印机,只需从事件侦听器列表中释放它并删除它。 您可以添加一行:

    ...
      delete listeners.Release(listeners.default_result_printer());
      listeners.Append(new MinimalistPrinter);
      return RUN_ALL_TESTS();

    现在,坐下来享受与你的测试完全不同的输出。 有关更多详细信息,您可以阅读此示例 sample(sample9_unittest)。

    您可以向列表附加多个侦听器。 当On * Start()或OnTestPartResult()事件触发时,监听器将按它们在列表中显示的顺序接收它(因为新的监听器添加到列表的末尾,默认文本打印机和默认XML生成器 将第一时间接收事件)。 An On * End()事件将由侦听器以相反的顺序接收。 这允许稍后添加的侦听器的输出由之前添加的侦听器的输出构成。

    三、Generating Failures in Listeners

    在处理事件时,可以使用故障提升宏(EXPECT _ *(),ASSERT _ *(),FAIL()等)。 有一些限制:

    • 你不能在OnTestPartResult()中产生任何失败(否则会导致OnTestPartResult()被递归调用)。
    • 处理OnTestPartResult()的侦听器不允许生成任何失败。

    当您向侦听器列表添加侦听器时,应该在可能生成失败的侦听器之前放置处理OnTestPartResult()的侦听器。 这确保由后者产生的故障归因于前者的正确测试。

    我们在这里有一个失败监听器的示例here(sample10_unittest)。

    四、TestEventListener接口

    // The interface for tracing execution of tests. The methods are organized in
    // the order the corresponding events are fired.
    class TestEventListener {
     public:
      virtual ~TestEventListener() {}
    
      // Fired before any test activity starts.
      virtual void OnTestProgramStart(const UnitTest& unit_test) = 0;
    
      // Fired before each iteration of tests starts.  There may be more than
      // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration
      // index, starting from 0.
      virtual void OnTestIterationStart(const UnitTest& unit_test,
                                        int iteration) = 0;
    
      // Fired before environment set-up for each iteration of tests starts.
      virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0;
    
      // Fired after environment set-up for each iteration of tests ends.
      virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0;
    
      // Fired before the test case starts.
      virtual void OnTestCaseStart(const TestCase& test_case) = 0;
    
      // Fired before the test starts.
      virtual void OnTestStart(const TestInfo& test_info) = 0;
    
      // Fired after a failed assertion or a SUCCEED() invocation.
      virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0;
    
      // Fired after the test ends.
      virtual void OnTestEnd(const TestInfo& test_info) = 0;
    
      // Fired after the test case ends.
      virtual void OnTestCaseEnd(const TestCase& test_case) = 0;
    
      // Fired before environment tear-down for each iteration of tests starts.
      virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0;
    
      // Fired after environment tear-down for each iteration of tests ends.
      virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0;
    
      // Fired after each iteration of tests finishes.
      virtual void OnTestIterationEnd(const UnitTest& unit_test,
                                      int iteration) = 0;
    
      // Fired after all test activities have ended.
      virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0;
    };
    
    // The convenience class for users who need to override just one or two
    // methods and are not concerned that a possible change to a signature of
    // the methods they override will not be caught during the build.  For
    // comments about each method please see the definition of TestEventListener
    // above.一个空实现
    class EmptyTestEventListener : public TestEventListener {
     public:
      virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {}
      virtual void OnTestIterationStart(const UnitTest& /*unit_test*/,
                                        int /*iteration*/) {}
      virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {}
      virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {}
      virtual void OnTestCaseStart(const TestCase& /*test_case*/) {}
      virtual void OnTestStart(const TestInfo& /*test_info*/) {}
      virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {}
      virtual void OnTestEnd(const TestInfo& /*test_info*/) {}
      virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {}
      virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {}
      virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {}
      virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/,
                                      int /*iteration*/) {}
      virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {}
    };
    

    五、官方例子

    就是samples文件夹下的sample10_unittest.cpp

    // This sample shows how to use Google Test listener API to implement
    // a primitive leak checker.
    
    #include "stdafx.h"
    
    using ::testing::EmptyTestEventListener;
    using ::testing::InitGoogleTest;
    using ::testing::Test;
    using ::testing::TestCase;
    using ::testing::TestEventListeners;
    using ::testing::TestInfo;
    using ::testing::TestPartResult;
    using ::testing::UnitTest;
    
    namespace {
    
    	// We will track memory used by this class.
    	class Water {
    	public:
    		// Normal Water declarations go here.
    
    		// operator new and operator delete help us control water allocation.
    		void* operator new(size_t allocation_size) {
    			allocated_++;
    			return malloc(allocation_size);
    		}
    
    		void operator delete(void* block, size_t /* allocation_size */) {
    			allocated_--;
    			free(block);
    		}
    
    		static int allocated() { return allocated_; }
    
    	private:
    		static int allocated_;
    	};
    
    	int Water::allocated_ = 0;
    
    	// This event listener monitors how many Water objects are created and
    	// destroyed by each test, and reports a failure if a test leaks some Water
    	// objects. It does this by comparing the number of live Water objects at
    	// the beginning of a test and at the end of a test.
    	class LeakChecker : public EmptyTestEventListener {
    
    		
    	private:
    		// Called before a test starts.
    		virtual void OnTestStart(const TestInfo& /* test_info */) {
    			initially_allocated_ = Water::allocated();
    		}
    
    		// Called after a test ends.
    		virtual void OnTestEnd(const TestInfo& /* test_info */) {
    			int difference = Water::allocated() - initially_allocated_;
    
    			// You can generate a failure in any event handler except
    			// OnTestPartResult. Just use an appropriate Google Test assertion to do
    			// it.
    			EXPECT_LE(difference, 0) << "Leaked " << difference << " unit(s) of Water!";
    		}
    
    		int initially_allocated_;
    
    	};
    
    	TEST(ListenersTest, DoesNotLeak) {
    		Water* water = new Water;
    		delete water;
    	}
    
    	// This should fail when the --check_for_leaks command line flag is
    	// specified.
    	TEST(ListenersTest, LeaksWater) {
    		Water* water = new Water;
    		EXPECT_TRUE(water != NULL);
    	}
    
    }  // namespace
    
    int main(int argc, char **argv) {
    	InitGoogleTest(&argc, argv);
    
    	bool check_for_leaks = false;
    	if (argc > 1 && strcmp(argv[1], "--check_for_leaks") == 0)
    		check_for_leaks = true;
    	else
    		printf("%s
    ", "Run this program with --check_for_leaks to enable "
    			"custom leak checking in the tests.");
    
    	// If we are given the --check_for_leaks command line flag, installs the
    	// leak checker.
    	if (check_for_leaks) {
    		TestEventListeners& listeners = UnitTest::GetInstance()->listeners();
    
    		// Adds the leak checker to the end of the test event listener list,
    		// after the default text output printer and the default XML report
    		// generator.
    		//
    		// The order is important - it ensures that failures generated in the
    		// leak checker's OnTestEnd() method are processed by the text and XML
    		// printers *before* their OnTestEnd() methods are called, such that
    		// they are attributed to the right test. Remember that a listener
    		// receives an OnXyzStart event *after* listeners preceding it in the
    		// list received that event, and receives an OnXyzEnd event *before*
    		// listeners preceding it.
    		//
    		// We don't need to worry about deleting the new listener later, as
    		// Google Test will do it.
    		listeners.Append(new LeakChecker);
    	}
    	return RUN_ALL_TESTS();
    }
    

      

  • 相关阅读:
    Java应用开发中的SQL注入攻击
    TOSCA自动化测试工具ppt
    SQL Server怎么备份数据库
    翻翻git之---一个丰富的通知工具类 NotifyUtil
    ZOJ
    高速掌握Lua 5.3 —— Lua与C之间的交互概览
    poj1649 Rescue(BFS+优先队列)
    面向对象在JavaScript中的接口实现
    dedecms织梦后台password忘记了怎么办?dedecms织梦后台password忘记怎样找回password?
    [ACM] POJ 3233 Matrix Power Series (求矩阵A+A^2+A^3...+A^k,二分求和或者矩阵转化)
  • 原文地址:https://www.cnblogs.com/jycboy/p/gtest_handlingEvent.html
Copyright © 2011-2022 走看看