mirror of
https://github.com/google/googletest.git
synced 2025-01-15 00:47:54 +08:00
Implements --gtest_throw_on_failure for using gtest with other testing frameworks.
This commit is contained in:
parent
4984c93490
commit
40e72a8a83
16
Makefile.am
16
Makefile.am
@ -13,7 +13,6 @@ EXTRA_DIST = \
|
||||
scons/SConscript \
|
||||
scripts/fuse_gtest_files.py \
|
||||
scripts/gen_gtest_pred_impl.py \
|
||||
src/gtest-all.cc \
|
||||
test/gtest_all_test.cc
|
||||
|
||||
# MSVC project files
|
||||
@ -263,6 +262,13 @@ check_PROGRAMS += test/gtest-test-part_test
|
||||
test_gtest_test_part_test_SOURCES = test/gtest-test-part_test.cc
|
||||
test_gtest_test_part_test_LDADD = lib/libgtest_main.la
|
||||
|
||||
TESTS += test/gtest_throw_on_failure_ex_test
|
||||
check_PROGRAMS += test/gtest_throw_on_failure_ex_test
|
||||
test_gtest_throw_on_failure_ex_test_SOURCES = \
|
||||
test/gtest_throw_on_failure_ex_test.cc \
|
||||
src/gtest-all.cc
|
||||
test_gtest_throw_on_failure_ex_test_CXXFLAGS = $(AM_CXXFLAGS) -fexceptions
|
||||
|
||||
TESTS += test/gtest-typed-test_test
|
||||
check_PROGRAMS += test/gtest-typed-test_test
|
||||
test_gtest_typed_test_test_SOURCES = test/gtest-typed-test_test.cc \
|
||||
@ -327,6 +333,14 @@ EXTRA_DIST += test/gtest_output_test_golden_lin.txt \
|
||||
test/gtest_output_test_golden_win.txt
|
||||
TESTS += test/gtest_output_test.py
|
||||
|
||||
check_PROGRAMS += test/gtest_throw_on_failure_test_
|
||||
test_gtest_throw_on_failure_test__SOURCES = \
|
||||
test/gtest_throw_on_failure_test_.cc \
|
||||
src/gtest-all.cc
|
||||
test_gtest_throw_on_failure_test__CXXFLAGS = $(AM_CXXFLAGS) -fno-exceptions
|
||||
check_SCRIPTS += test/gtest_throw_on_failure_test.py
|
||||
TESTS += test/gtest_throw_on_failure_test.py
|
||||
|
||||
check_PROGRAMS += test/gtest_uninitialized_test_
|
||||
test_gtest_uninitialized_test__SOURCES = test/gtest_uninitialized_test_.cc
|
||||
test_gtest_uninitialized_test__LDADD = lib/libgtest.la
|
||||
|
@ -101,20 +101,20 @@ GTEST_DECLARE_bool_(also_run_disabled_tests);
|
||||
// This flag brings the debugger on an assertion failure.
|
||||
GTEST_DECLARE_bool_(break_on_failure);
|
||||
|
||||
// This flag controls whether Google Test catches all test-thrown exceptions
|
||||
// and logs them as failures.
|
||||
// This flag controls whether Google Test catches all test-thrown exceptions
|
||||
// and logs them as failures.
|
||||
GTEST_DECLARE_bool_(catch_exceptions);
|
||||
|
||||
// This flag enables using colors in terminal output. Available values are
|
||||
// "yes" to enable colors, "no" (disable colors), or "auto" (the default)
|
||||
// This flag enables using colors in terminal output. Available values are
|
||||
// "yes" to enable colors, "no" (disable colors), or "auto" (the default)
|
||||
// to let Google Test decide.
|
||||
GTEST_DECLARE_string_(color);
|
||||
|
||||
// This flag sets up the filter to select by name using a glob pattern
|
||||
// This flag sets up the filter to select by name using a glob pattern
|
||||
// the tests to run. If the filter is not given all tests are executed.
|
||||
GTEST_DECLARE_string_(filter);
|
||||
|
||||
// This flag causes the Google Test to list tests. None of the tests listed
|
||||
// This flag causes the Google Test to list tests. None of the tests listed
|
||||
// are actually run if the flag is provided.
|
||||
GTEST_DECLARE_bool_(list_tests);
|
||||
|
||||
@ -122,11 +122,11 @@ GTEST_DECLARE_bool_(list_tests);
|
||||
// in addition to its normal textual output.
|
||||
GTEST_DECLARE_string_(output);
|
||||
|
||||
// This flags control whether Google Test prints the elapsed time for each
|
||||
// This flags control whether Google Test prints the elapsed time for each
|
||||
// test.
|
||||
GTEST_DECLARE_bool_(print_time);
|
||||
|
||||
// This flag sets how many times the tests are repeated. The default value
|
||||
// This flag sets how many times the tests are repeated. The default value
|
||||
// is 1. If the value is -1 the tests are repeating forever.
|
||||
GTEST_DECLARE_int32_(repeat);
|
||||
|
||||
@ -138,6 +138,11 @@ GTEST_DECLARE_bool_(show_internal_stack_frames);
|
||||
// printed in a failure message.
|
||||
GTEST_DECLARE_int32_(stack_trace_depth);
|
||||
|
||||
// When this flag is specified, a failed assertion will throw an
|
||||
// exception if exceptions are enabled, or exit the program with a
|
||||
// non-zero code otherwise.
|
||||
GTEST_DECLARE_bool_(throw_on_failure);
|
||||
|
||||
// The upper limit for valid stack trace depths.
|
||||
const int kMaxStackTraceDepth = 100;
|
||||
|
||||
|
@ -214,6 +214,8 @@ GtestBinary(env_with_exceptions,
|
||||
# - gtest_break_on_failure_unittest_
|
||||
# - gtest_filter_unittest_
|
||||
# - gtest_list_tests_unittest_
|
||||
# - gtest_throw_on_failure_ex_test
|
||||
# - gtest_throw_on_failure_test_
|
||||
# - gtest_xml_outfile1_test_
|
||||
# - gtest_xml_outfile2_test_
|
||||
# - gtest_xml_output_unittest_
|
||||
|
@ -84,6 +84,7 @@ const char kListTestsFlag[] = "list_tests";
|
||||
const char kOutputFlag[] = "output";
|
||||
const char kPrintTimeFlag[] = "print_time";
|
||||
const char kRepeatFlag[] = "repeat";
|
||||
const char kThrowOnFailureFlag[] = "throw_on_failure";
|
||||
|
||||
// This class saves the values of all Google Test flags in its c'tor, and
|
||||
// restores them in its d'tor.
|
||||
@ -103,6 +104,7 @@ class GTestFlagSaver {
|
||||
output_ = GTEST_FLAG(output);
|
||||
print_time_ = GTEST_FLAG(print_time);
|
||||
repeat_ = GTEST_FLAG(repeat);
|
||||
throw_on_failure_ = GTEST_FLAG(throw_on_failure);
|
||||
}
|
||||
|
||||
// The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS.
|
||||
@ -119,6 +121,7 @@ class GTestFlagSaver {
|
||||
GTEST_FLAG(output) = output_;
|
||||
GTEST_FLAG(print_time) = print_time_;
|
||||
GTEST_FLAG(repeat) = repeat_;
|
||||
GTEST_FLAG(throw_on_failure) = throw_on_failure_;
|
||||
}
|
||||
private:
|
||||
// Fields for saving the original values of flags.
|
||||
@ -135,6 +138,7 @@ class GTestFlagSaver {
|
||||
bool print_time_;
|
||||
bool pretty_;
|
||||
internal::Int32 repeat_;
|
||||
bool throw_on_failure_;
|
||||
} GTEST_ATTRIBUTE_UNUSED_;
|
||||
|
||||
// Converts a Unicode code point to a narrow string in UTF-8 encoding.
|
||||
|
67
src/gtest.cc
67
src/gtest.cc
@ -111,6 +111,10 @@
|
||||
|
||||
#endif // GTEST_OS_LINUX
|
||||
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
#include <stdexcept>
|
||||
#endif
|
||||
|
||||
// Indicates that this translation unit is part of Google Test's
|
||||
// implementation. It must come before gtest-internal-inl.h is
|
||||
// included, or there will be a compiler error. This trick is to
|
||||
@ -231,6 +235,13 @@ GTEST_DEFINE_bool_(
|
||||
"True iff " GTEST_NAME_ " should include internal stack frames when "
|
||||
"printing test failure stack traces.");
|
||||
|
||||
GTEST_DEFINE_bool_(
|
||||
throw_on_failure,
|
||||
internal::BoolFromGTestEnv("throw_on_failure", false),
|
||||
"When this flag is specified, a failed assertion will throw an exception "
|
||||
"if exceptions are enabled or exit the program with a non-zero code "
|
||||
"otherwise.");
|
||||
|
||||
namespace internal {
|
||||
|
||||
// GTestIsInitialized() returns true iff the user has initialized
|
||||
@ -2438,14 +2449,20 @@ static const char * TestPartResultTypeToString(TestPartResultType type) {
|
||||
return "Unknown result type";
|
||||
}
|
||||
|
||||
// Prints a TestPartResult to a String.
|
||||
static internal::String PrintTestPartResultToString(
|
||||
const TestPartResult& test_part_result) {
|
||||
return (Message()
|
||||
<< internal::FormatFileLocation(test_part_result.file_name(),
|
||||
test_part_result.line_number())
|
||||
<< " " << TestPartResultTypeToString(test_part_result.type())
|
||||
<< test_part_result.message()).GetString();
|
||||
}
|
||||
|
||||
// Prints a TestPartResult.
|
||||
static void PrintTestPartResult(
|
||||
const TestPartResult & test_part_result) {
|
||||
printf("%s %s%s\n",
|
||||
internal::FormatFileLocation(test_part_result.file_name(),
|
||||
test_part_result.line_number()).c_str(),
|
||||
TestPartResultTypeToString(test_part_result.type()),
|
||||
test_part_result.message());
|
||||
const TestPartResult& test_part_result) {
|
||||
printf("%s\n", PrintTestPartResultToString(test_part_result).c_str());
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
@ -3240,6 +3257,19 @@ Environment* UnitTest::AddEnvironment(Environment* env) {
|
||||
return env;
|
||||
}
|
||||
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
// A failed Google Test assertion will throw an exception of this type
|
||||
// when exceptions are enabled. We derive it from std::runtime_error,
|
||||
// which is for errors presumably detectable only at run time. Since
|
||||
// std::runtime_error inherits from std::exception, many testing
|
||||
// frameworks know how to extract and print the message inside it.
|
||||
class GoogleTestFailureException : public ::std::runtime_error {
|
||||
public:
|
||||
explicit GoogleTestFailureException(const TestPartResult& failure)
|
||||
: runtime_error(PrintTestPartResultToString(failure).c_str()) {}
|
||||
};
|
||||
#endif
|
||||
|
||||
// Adds a TestPartResult to the current TestResult object. All Google Test
|
||||
// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call
|
||||
// this to report their results. The user code should use the
|
||||
@ -3276,11 +3306,23 @@ void UnitTest::AddTestPartResult(TestPartResultType result_type,
|
||||
impl_->GetTestPartResultReporterForCurrentThread()->
|
||||
ReportTestPartResult(result);
|
||||
|
||||
// If this is a failure and the user wants the debugger to break on
|
||||
// failures ...
|
||||
if (result_type != TPRT_SUCCESS && GTEST_FLAG(break_on_failure)) {
|
||||
// ... then we generate a seg fault.
|
||||
*static_cast<int*>(NULL) = 1;
|
||||
if (result_type != TPRT_SUCCESS) {
|
||||
// gunit_break_on_failure takes precedence over
|
||||
// gunit_throw_on_failure. This allows a user to set the latter
|
||||
// in the code (perhaps in order to use Google Test assertions
|
||||
// with another testing framework) and specify the former on the
|
||||
// command line for debugging.
|
||||
if (GTEST_FLAG(break_on_failure)) {
|
||||
*static_cast<int*>(NULL) = 1;
|
||||
} else if (GTEST_FLAG(throw_on_failure)) {
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
throw GoogleTestFailureException(result);
|
||||
#else
|
||||
// We cannot call abort() as it generates a pop-up in debug mode
|
||||
// that cannot be suppressed in VC 7.1 or below.
|
||||
exit(1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4078,7 +4120,8 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
|
||||
ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) ||
|
||||
ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) ||
|
||||
ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) ||
|
||||
ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat))
|
||||
ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) ||
|
||||
ParseBoolFlag(arg, kThrowOnFailureFlag, >EST_FLAG(throw_on_failure))
|
||||
) {
|
||||
// Yes. Shift the remainder of the argv list left by one. Note
|
||||
// that argv has (*argc + 1) elements, the last one always being
|
||||
|
@ -42,7 +42,6 @@ __author__ = 'wan@google.com (Zhanyong Wan)'
|
||||
|
||||
import gtest_test_utils
|
||||
import os
|
||||
import signal
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
@ -55,13 +54,17 @@ BREAK_ON_FAILURE_ENV_VAR = 'GTEST_BREAK_ON_FAILURE'
|
||||
# The command line flag for enabling/disabling the break-on-failure mode.
|
||||
BREAK_ON_FAILURE_FLAG = 'gtest_break_on_failure'
|
||||
|
||||
# The environment variable for enabling/disabling the throw-on-failure mode.
|
||||
THROW_ON_FAILURE_ENV_VAR = 'GTEST_THROW_ON_FAILURE'
|
||||
|
||||
# Path to the gtest_break_on_failure_unittest_ program.
|
||||
EXE_PATH = os.path.join(gtest_test_utils.GetBuildDir(),
|
||||
'gtest_break_on_failure_unittest_');
|
||||
'gtest_break_on_failure_unittest_')
|
||||
|
||||
|
||||
# Utilities.
|
||||
|
||||
|
||||
def SetEnvVar(env_var, value):
|
||||
"""Sets an environment variable to a given value; unsets it when the
|
||||
given value is None.
|
||||
@ -74,8 +77,7 @@ def SetEnvVar(env_var, value):
|
||||
|
||||
|
||||
def Run(command):
|
||||
"""Runs a command; returns 1 if it was killed by a signal, or 0 otherwise.
|
||||
"""
|
||||
"""Runs a command; returns 1 if it was killed by a signal, or 0 otherwise."""
|
||||
|
||||
p = gtest_test_utils.Subprocess(command)
|
||||
if p.terminated_by_signal:
|
||||
@ -84,7 +86,8 @@ def Run(command):
|
||||
return 0
|
||||
|
||||
|
||||
# The unit test.
|
||||
# The tests.
|
||||
|
||||
|
||||
class GTestBreakOnFailureUnitTest(unittest.TestCase):
|
||||
"""Tests using the GTEST_BREAK_ON_FAILURE environment variable or
|
||||
@ -180,6 +183,16 @@ class GTestBreakOnFailureUnitTest(unittest.TestCase):
|
||||
flag_value='1',
|
||||
expect_seg_fault=1)
|
||||
|
||||
def testBreakOnFailureOverridesThrowOnFailure(self):
|
||||
"""Tests that gtest_break_on_failure overrides gtest_throw_on_failure."""
|
||||
|
||||
SetEnvVar(THROW_ON_FAILURE_ENV_VAR, '1')
|
||||
try:
|
||||
self.RunAndVerify(env_var_value=None,
|
||||
flag_value='1',
|
||||
expect_seg_fault=1)
|
||||
finally:
|
||||
SetEnvVar(THROW_ON_FAILURE_ENV_VAR, None)
|
||||
|
||||
if __name__ == '__main__':
|
||||
gtest_test_utils.Main()
|
||||
|
@ -54,7 +54,6 @@ TEST(Foo, Bar) {
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
#if GTEST_OS_WINDOWS
|
||||
// Suppresses display of the Windows error dialog upon encountering
|
||||
|
@ -103,6 +103,7 @@ def TestEnvVarAffectsFlag(command):
|
||||
TestFlag(command, 'output', 'tmp/foo.xml', '')
|
||||
TestFlag(command, 'print_time', '1', '0')
|
||||
TestFlag(command, 'repeat', '999', '1')
|
||||
TestFlag(command, 'throw_on_failure', '1', '0')
|
||||
|
||||
if IS_WINDOWS:
|
||||
TestFlag(command, 'catch_exceptions', '1', '0')
|
||||
|
@ -101,6 +101,11 @@ void PrintFlag(const char* flag) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(flag, "throw_on_failure") == 0) {
|
||||
cout << GTEST_FLAG(throw_on_failure);
|
||||
return;
|
||||
}
|
||||
|
||||
cout << "Invalid flag name " << flag
|
||||
<< ". Valid names are break_on_failure, color, filter, etc.\n";
|
||||
exit(1);
|
||||
|
92
test/gtest_throw_on_failure_ex_test.cc
Normal file
92
test/gtest_throw_on_failure_ex_test.cc
Normal file
@ -0,0 +1,92 @@
|
||||
// Copyright 2009, 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.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Tests Google Test's throw-on-failure mode with exceptions enabled.
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdexcept>
|
||||
|
||||
// Prints the given failure message and exits the program with
|
||||
// non-zero. We use this instead of a Google Test assertion to
|
||||
// indicate a failure, as the latter is been tested and cannot be
|
||||
// relied on.
|
||||
void Fail(const char* msg) {
|
||||
printf("FAILURE: %s\n", msg);
|
||||
fflush(stdout);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Tests that an assertion failure throws a subclass of
|
||||
// std::runtime_error.
|
||||
void TestFailureThrowsRuntimeError() {
|
||||
testing::GTEST_FLAG(throw_on_failure) = true;
|
||||
|
||||
// A successful assertion shouldn't throw.
|
||||
try {
|
||||
EXPECT_EQ(3, 3);
|
||||
} catch(...) {
|
||||
Fail("A successful assertion wrongfully threw.");
|
||||
}
|
||||
|
||||
// A failed assertion should throw a subclass of std::runtime_error.
|
||||
try {
|
||||
EXPECT_EQ(2, 3) << "Expected failure";
|
||||
} catch(const std::runtime_error& e) {
|
||||
if (strstr(e.what(), "Expected failure") != NULL)
|
||||
return;
|
||||
|
||||
printf("%s",
|
||||
"A failed assertion did throw an exception of the right type, "
|
||||
"but the message is incorrect. Instead of containing \"Expected "
|
||||
"failure\", it is:\n");
|
||||
Fail(e.what());
|
||||
} catch(...) {
|
||||
Fail("A failed assertion threw the wrong type of exception.");
|
||||
}
|
||||
Fail("A failed assertion should've thrown but didn't.");
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
// We want to ensure that people can use Google Test assertions in
|
||||
// other testing frameworks, as long as they initialize Google Test
|
||||
// properly and set the thrown-on-failure mode. Therefore, we don't
|
||||
// use Google Test's constructs for defining and running tests
|
||||
// (e.g. TEST and RUN_ALL_TESTS) here.
|
||||
|
||||
TestFailureThrowsRuntimeError();
|
||||
return 0;
|
||||
}
|
171
test/gtest_throw_on_failure_test.py
Executable file
171
test/gtest_throw_on_failure_test.py
Executable file
@ -0,0 +1,171 @@
|
||||
#!/usr/bin/python2.4
|
||||
#
|
||||
# Copyright 2009, 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.
|
||||
|
||||
"""Tests Google Test's throw-on-failure mode with exceptions disabled.
|
||||
|
||||
This script invokes gtest_throw_on_failure_test_ (a program written with
|
||||
Google Test) with different environments and command line flags.
|
||||
"""
|
||||
|
||||
__author__ = 'wan@google.com (Zhanyong Wan)'
|
||||
|
||||
import gtest_test_utils
|
||||
import os
|
||||
import unittest
|
||||
|
||||
|
||||
# Constants.
|
||||
|
||||
# The command line flag for enabling/disabling the throw-on-failure mode.
|
||||
THROW_ON_FAILURE = 'gtest_throw_on_failure'
|
||||
|
||||
# Path to the gtest_throw_on_failure_test_ program, compiled with
|
||||
# exceptions disabled.
|
||||
EXE_PATH = os.path.join(gtest_test_utils.GetBuildDir(),
|
||||
'gtest_throw_on_failure_test_')
|
||||
|
||||
|
||||
# Utilities.
|
||||
|
||||
|
||||
def SetEnvVar(env_var, value):
|
||||
"""Sets an environment variable to a given value; unsets it when the
|
||||
given value is None.
|
||||
"""
|
||||
|
||||
env_var = env_var.upper()
|
||||
if value is not None:
|
||||
os.environ[env_var] = value
|
||||
elif env_var in os.environ:
|
||||
del os.environ[env_var]
|
||||
|
||||
|
||||
def Run(command):
|
||||
"""Runs a command; returns True/False if its exit code is/isn't 0."""
|
||||
|
||||
print 'Running "%s". . .' % ' '.join(command)
|
||||
return gtest_test_utils.Subprocess(command).exit_code == 0
|
||||
|
||||
|
||||
# The tests. TODO(wan@google.com): refactor the class to share common
|
||||
# logic with code in gtest_break_on_failure_unittest.py.
|
||||
class ThrowOnFailureTest(unittest.TestCase):
|
||||
"""Tests the throw-on-failure mode."""
|
||||
|
||||
def RunAndVerify(self, env_var_value, flag_value, should_fail):
|
||||
"""Runs gtest_throw_on_failure_test_ and verifies that it does
|
||||
(or does not) exit with a non-zero code.
|
||||
|
||||
Args:
|
||||
env_var_value: value of the GTEST_BREAK_ON_FAILURE environment
|
||||
variable; None if the variable should be unset.
|
||||
flag_value: value of the --gtest_break_on_failure flag;
|
||||
None if the flag should not be present.
|
||||
should_fail: True iff the program is expected to fail.
|
||||
"""
|
||||
|
||||
SetEnvVar(THROW_ON_FAILURE, env_var_value)
|
||||
|
||||
if env_var_value is None:
|
||||
env_var_value_msg = ' is not set'
|
||||
else:
|
||||
env_var_value_msg = '=' + env_var_value
|
||||
|
||||
if flag_value is None:
|
||||
flag = ''
|
||||
elif flag_value == '0':
|
||||
flag = '--%s=0' % THROW_ON_FAILURE
|
||||
else:
|
||||
flag = '--%s' % THROW_ON_FAILURE
|
||||
|
||||
command = [EXE_PATH]
|
||||
if flag:
|
||||
command.append(flag)
|
||||
|
||||
if should_fail:
|
||||
should_or_not = 'should'
|
||||
else:
|
||||
should_or_not = 'should not'
|
||||
|
||||
failed = not Run(command)
|
||||
|
||||
SetEnvVar(THROW_ON_FAILURE, None)
|
||||
|
||||
msg = ('when %s%s, an assertion failure in "%s" %s cause a non-zero '
|
||||
'exit code.' %
|
||||
(THROW_ON_FAILURE, env_var_value_msg, ' '.join(command),
|
||||
should_or_not))
|
||||
self.assert_(failed == should_fail, msg)
|
||||
|
||||
def testDefaultBehavior(self):
|
||||
"""Tests the behavior of the default mode."""
|
||||
|
||||
self.RunAndVerify(env_var_value=None, flag_value=None, should_fail=False)
|
||||
|
||||
def testThrowOnFailureEnvVar(self):
|
||||
"""Tests using the GTEST_THROW_ON_FAILURE environment variable."""
|
||||
|
||||
self.RunAndVerify(env_var_value='0',
|
||||
flag_value=None,
|
||||
should_fail=False)
|
||||
self.RunAndVerify(env_var_value='1',
|
||||
flag_value=None,
|
||||
should_fail=True)
|
||||
|
||||
def testThrowOnFailureFlag(self):
|
||||
"""Tests using the --gtest_throw_on_failure flag."""
|
||||
|
||||
self.RunAndVerify(env_var_value=None,
|
||||
flag_value='0',
|
||||
should_fail=False)
|
||||
self.RunAndVerify(env_var_value=None,
|
||||
flag_value='1',
|
||||
should_fail=True)
|
||||
|
||||
def testThrowOnFailureFlagOverridesEnvVar(self):
|
||||
"""Tests that --gtest_throw_on_failure overrides GTEST_THROW_ON_FAILURE."""
|
||||
|
||||
self.RunAndVerify(env_var_value='0',
|
||||
flag_value='0',
|
||||
should_fail=False)
|
||||
self.RunAndVerify(env_var_value='0',
|
||||
flag_value='1',
|
||||
should_fail=True)
|
||||
self.RunAndVerify(env_var_value='1',
|
||||
flag_value='0',
|
||||
should_fail=False)
|
||||
self.RunAndVerify(env_var_value='1',
|
||||
flag_value='1',
|
||||
should_fail=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
gtest_test_utils.Main()
|
56
test/gtest_throw_on_failure_test_.cc
Normal file
56
test/gtest_throw_on_failure_test_.cc
Normal file
@ -0,0 +1,56 @@
|
||||
// Copyright 2009, 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.
|
||||
//
|
||||
// Author: wan@google.com (Zhanyong Wan)
|
||||
|
||||
// Tests Google Test's throw-on-failure mode with exceptions disabled.
|
||||
//
|
||||
// This program must be compiled with exceptions disabled. It will be
|
||||
// invoked by gtest_throw_on_failure_test.py, and is expected to exit
|
||||
// with non-zero in the throw-on-failure mode or 0 otherwise.
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
// We want to ensure that people can use Google Test assertions in
|
||||
// other testing frameworks, as long as they initialize Google Test
|
||||
// properly and set the thrown-on-failure mode. Therefore, we don't
|
||||
// use Google Test's constructs for defining and running tests
|
||||
// (e.g. TEST and RUN_ALL_TESTS) here.
|
||||
|
||||
// In the throw-on-failure mode with exceptions disabled, this
|
||||
// assertion will cause the program to exit with a non-zero code.
|
||||
EXPECT_EQ(2, 3);
|
||||
|
||||
// When not in the throw-on-failure mode, the control will reach
|
||||
// here.
|
||||
return 0;
|
||||
}
|
@ -48,7 +48,8 @@ TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) {
|
||||
|| testing::GTEST_FLAG(print_time)
|
||||
|| testing::GTEST_FLAG(repeat) > 0
|
||||
|| testing::GTEST_FLAG(show_internal_stack_frames)
|
||||
|| testing::GTEST_FLAG(stack_trace_depth) > 0;
|
||||
|| testing::GTEST_FLAG(stack_trace_depth) > 0
|
||||
|| testing::GTEST_FLAG(throw_on_failure);
|
||||
EXPECT_TRUE(dummy || !dummy); // Suppresses warning that dummy is unused.
|
||||
}
|
||||
|
||||
@ -115,6 +116,7 @@ using testing::GTEST_FLAG(print_time);
|
||||
using testing::GTEST_FLAG(repeat);
|
||||
using testing::GTEST_FLAG(show_internal_stack_frames);
|
||||
using testing::GTEST_FLAG(stack_trace_depth);
|
||||
using testing::GTEST_FLAG(throw_on_failure);
|
||||
using testing::IsNotSubstring;
|
||||
using testing::IsSubstring;
|
||||
using testing::Message;
|
||||
@ -1203,6 +1205,7 @@ class GTestFlagSaverTest : public Test {
|
||||
GTEST_FLAG(output) = "";
|
||||
GTEST_FLAG(print_time) = false;
|
||||
GTEST_FLAG(repeat) = 1;
|
||||
GTEST_FLAG(throw_on_failure) = false;
|
||||
}
|
||||
|
||||
// Restores the Google Test flags that the tests have modified. This will
|
||||
@ -1225,6 +1228,7 @@ class GTestFlagSaverTest : public Test {
|
||||
EXPECT_STREQ("", GTEST_FLAG(output).c_str());
|
||||
EXPECT_FALSE(GTEST_FLAG(print_time));
|
||||
EXPECT_EQ(1, GTEST_FLAG(repeat));
|
||||
EXPECT_FALSE(GTEST_FLAG(throw_on_failure));
|
||||
|
||||
GTEST_FLAG(also_run_disabled_tests) = true;
|
||||
GTEST_FLAG(break_on_failure) = true;
|
||||
@ -1236,6 +1240,7 @@ class GTestFlagSaverTest : public Test {
|
||||
GTEST_FLAG(output) = "xml:foo.xml";
|
||||
GTEST_FLAG(print_time) = true;
|
||||
GTEST_FLAG(repeat) = 100;
|
||||
GTEST_FLAG(throw_on_failure) = true;
|
||||
}
|
||||
private:
|
||||
// For saving Google Test flags during this test case.
|
||||
@ -4320,7 +4325,8 @@ struct Flags {
|
||||
list_tests(false),
|
||||
output(""),
|
||||
print_time(false),
|
||||
repeat(1) {}
|
||||
repeat(1),
|
||||
throw_on_failure(false) {}
|
||||
|
||||
// Factory methods.
|
||||
|
||||
@ -4396,6 +4402,14 @@ struct Flags {
|
||||
return flags;
|
||||
}
|
||||
|
||||
// Creates a Flags struct where the gtest_throw_on_failure flag has
|
||||
// the given value.
|
||||
static Flags ThrowOnFailure(bool throw_on_failure) {
|
||||
Flags flags;
|
||||
flags.throw_on_failure = throw_on_failure;
|
||||
return flags;
|
||||
}
|
||||
|
||||
// These fields store the flag values.
|
||||
bool also_run_disabled_tests;
|
||||
bool break_on_failure;
|
||||
@ -4406,6 +4420,7 @@ struct Flags {
|
||||
const char* output;
|
||||
bool print_time;
|
||||
Int32 repeat;
|
||||
bool throw_on_failure;
|
||||
};
|
||||
|
||||
// Fixture for testing InitGoogleTest().
|
||||
@ -4422,6 +4437,7 @@ class InitGoogleTestTest : public Test {
|
||||
GTEST_FLAG(output) = "";
|
||||
GTEST_FLAG(print_time) = false;
|
||||
GTEST_FLAG(repeat) = 1;
|
||||
GTEST_FLAG(throw_on_failure) = false;
|
||||
}
|
||||
|
||||
// Asserts that two narrow or wide string arrays are equal.
|
||||
@ -4447,6 +4463,7 @@ class InitGoogleTestTest : public Test {
|
||||
EXPECT_STREQ(expected.output, GTEST_FLAG(output).c_str());
|
||||
EXPECT_EQ(expected.print_time, GTEST_FLAG(print_time));
|
||||
EXPECT_EQ(expected.repeat, GTEST_FLAG(repeat));
|
||||
EXPECT_EQ(expected.throw_on_failure, GTEST_FLAG(throw_on_failure));
|
||||
}
|
||||
|
||||
// Parses a command line (specified by argc1 and argv1), then
|
||||
@ -4993,6 +5010,56 @@ TEST_F(InitGoogleTestTest, AlsoRunDisabledTestsFalse) {
|
||||
GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::AlsoRunDisabledTests(false));
|
||||
}
|
||||
|
||||
|
||||
// Tests parsing --gtest_throw_on_failure.
|
||||
TEST_F(InitGoogleTestTest, ThrowOnFailureNoDef) {
|
||||
const char* argv[] = {
|
||||
"foo.exe",
|
||||
"--gtest_throw_on_failure",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char* argv2[] = {
|
||||
"foo.exe",
|
||||
NULL
|
||||
};
|
||||
|
||||
GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true));
|
||||
}
|
||||
|
||||
// Tests parsing --gtest_throw_on_failure=0.
|
||||
TEST_F(InitGoogleTestTest, ThrowOnFailureFalse_0) {
|
||||
const char* argv[] = {
|
||||
"foo.exe",
|
||||
"--gtest_throw_on_failure=0",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char* argv2[] = {
|
||||
"foo.exe",
|
||||
NULL
|
||||
};
|
||||
|
||||
GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(false));
|
||||
}
|
||||
|
||||
// Tests parsing a --gtest_throw_on_failure flag that has a "true"
|
||||
// definition.
|
||||
TEST_F(InitGoogleTestTest, ThrowOnFailureTrue) {
|
||||
const char* argv[] = {
|
||||
"foo.exe",
|
||||
"--gtest_throw_on_failure=1",
|
||||
NULL
|
||||
};
|
||||
|
||||
const char* argv2[] = {
|
||||
"foo.exe",
|
||||
NULL
|
||||
};
|
||||
|
||||
GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::ThrowOnFailure(true));
|
||||
}
|
||||
|
||||
#if GTEST_OS_WINDOWS
|
||||
// Tests parsing wide strings.
|
||||
TEST_F(InitGoogleTestTest, WideStrings) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user