Implements --gtest_throw_on_failure for using gtest with other testing frameworks.

This commit is contained in:
zhanyong.wan 2009-03-06 20:05:23 +00:00
parent 4984c93490
commit 40e72a8a83
13 changed files with 501 additions and 29 deletions

View File

@ -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

View File

@ -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;

View File

@ -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_

View File

@ -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.

View File

@ -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, &GTEST_FLAG(list_tests)) ||
ParseStringFlag(arg, kOutputFlag, &GTEST_FLAG(output)) ||
ParseBoolFlag(arg, kPrintTimeFlag, &GTEST_FLAG(print_time)) ||
ParseInt32Flag(arg, kRepeatFlag, &GTEST_FLAG(repeat))
ParseInt32Flag(arg, kRepeatFlag, &GTEST_FLAG(repeat)) ||
ParseBoolFlag(arg, kThrowOnFailureFlag, &GTEST_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

View File

@ -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()

View File

@ -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

View File

@ -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')

View File

@ -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);

View 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;
}

View 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()

View 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;
}

View File

@ -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) {