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();
    }
    

      

  • 相关阅读:
    mysql BETWEEN操作符 语法
    mysql IN操作符 语法
    mysql LIKE通配符 语法
    mysql TOP语句 语法
    mysql DELETE语句 语法
    mysql Update语句 语法
    mysql INSERT语句 语法
    mysql ORDER BY语句 语法
    mysql OR运算符 语法
    mysql AND运算符 语法
  • 原文地址:https://www.cnblogs.com/jycboy/p/gtest_handlingEvent.html
Copyright © 2011-2022 走看看