Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
yangql
googletest
Commits
9737e63c
Unverified
Commit
9737e63c
authored
Feb 09, 2018
by
Gennadiy Civil
Committed by
GitHub
Feb 09, 2018
Browse files
Merge pull request #1439 from DarthGandalf/assert
Add ability to throw from ASSERT
parents
22a11505
b324a36c
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
171 additions
and
8 deletions
+171
-8
googletest/docs/AdvancedGuide.md
googletest/docs/AdvancedGuide.md
+25
-5
googletest/include/gtest/gtest.h
googletest/include/gtest/gtest.h
+15
-1
googletest/src/gtest.cc
googletest/src/gtest.cc
+5
-2
googletest/test/BUILD.bazel
googletest/test/BUILD.bazel
+7
-0
googletest/test/gtest_assert_by_exception_test.cc
googletest/test/gtest_assert_by_exception_test.cc
+119
-0
No files found.
googletest/docs/AdvancedGuide.md
View file @
9737e63c
...
...
@@ -872,13 +872,33 @@ TEST(FooTest, Bar) {
}
```
Since we don't use exceptions, it is technically impossible to
implement the intended behavior here. To alleviate this, Google Test
provides two solutions. You could use either the
`(ASSERT|EXPECT)_NO_FATAL_FAILURE`
assertions or the
`HasFatalFailure()`
function. They are described in the following two
To alleviate this, gUnit provides three different solutions. You could use
either exceptions, the
`(ASSERT|EXPECT)_NO_FATAL_FAILURE`
assertions or the
`HasFatalFailure()`
function. They are described in the following two
subsections.
#### Asserting on Subroutines with an exception
The following code can turn ASSERT-failure into an exception:
```
c++
class
ThrowListener
:
public
testing
::
EmptyTestEventListener
{
void
OnTestPartResult
(
const
testing
::
TestPartResult
&
result
)
override
{
if
(
result
.
type
()
==
testing
::
TestPartResult
::
kFatalFailure
)
{
throw
testing
::
AssertionException
(
result
);
}
}
};
int
main
(
int
argc
,
char
**
argv
)
{
...
testing
::
UnitTest
::
GetInstance
()
->
listeners
().
Append
(
new
ThrowListener
);
return
RUN_ALL_TESTS
();
}
```
This listener should be added after other listeners if you have any, otherwise
they won't see failed
`OnTestPartResult`
.
### Asserting on Subroutines ###
As shown above, if your test calls a subroutine that has an
`ASSERT_*`
...
...
googletest/include/gtest/gtest.h
View file @
9737e63c
...
...
@@ -138,7 +138,7 @@ 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.
// non-zero code otherwise.
For use with an external test framework.
GTEST_DECLARE_bool_
(
throw_on_failure
);
// When this flag is set with a "host:port" string, on supported
...
...
@@ -1004,6 +1004,18 @@ class Environment {
virtual
Setup_should_be_spelled_SetUp
*
Setup
()
{
return
NULL
;
}
};
#if GTEST_HAS_EXCEPTIONS
// Exception which can be thrown from TestEventListener::OnTestPartResult.
class
GTEST_API_
AssertionException
:
public
internal
::
GoogleTestFailureException
{
public:
explicit
AssertionException
(
const
TestPartResult
&
result
)
:
GoogleTestFailureException
(
result
)
{}
};
#endif // GTEST_HAS_EXCEPTIONS
// The interface for tracing execution of tests. The methods are organized in
// the order the corresponding events are fired.
class
TestEventListener
{
...
...
@@ -1032,6 +1044,8 @@ class TestEventListener {
virtual
void
OnTestStart
(
const
TestInfo
&
test_info
)
=
0
;
// Fired after a failed assertion or a SUCCEED() invocation.
// If you want to throw an exception from this function to skip to the next
// TEST, it must be AssertionException defined above, or inherited from it.
virtual
void
OnTestPartResult
(
const
TestPartResult
&
test_part_result
)
=
0
;
// Fired after the test ends.
...
...
googletest/src/gtest.cc
View file @
9737e63c
...
...
@@ -293,7 +293,7 @@ GTEST_DEFINE_bool_(
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."
);
"otherwise.
For use with an external test framework.
"
);
#if GTEST_USE_OWN_FLAGFILE_FLAG_
GTEST_DEFINE_string_
(
...
...
@@ -2435,6 +2435,8 @@ Result HandleExceptionsInMethodIfSupported(
#if GTEST_HAS_EXCEPTIONS
try
{
return
HandleSehExceptionsInMethodIfSupported
(
object
,
method
,
location
);
}
catch
(
const
AssertionException
&
)
{
// NOLINT
// This failure was reported already.
}
catch
(
const
internal
::
GoogleTestFailureException
&
)
{
// NOLINT
// This exception type can only be thrown by a failed Google
// Test assertion with the intention of letting another testing
...
...
@@ -5201,7 +5203,8 @@ static const char kColorEncodedHelpMessage[] =
" @G--"
GTEST_FLAG_PREFIX_
"break_on_failure@D
\n
"
" Turn assertion failures into debugger break-points.
\n
"
" @G--"
GTEST_FLAG_PREFIX_
"throw_on_failure@D
\n
"
" Turn assertion failures into C++ exceptions.
\n
"
" Turn assertion failures into C++ exceptions for use by an external
\n
"
" test framework.
\n
"
" @G--"
GTEST_FLAG_PREFIX_
"catch_exceptions=0@D
\n
"
" Do not report exceptions as test failures. Instead, allow them
\n
"
" to crash the program or throw a pop-up (on Windows).
\n
"
...
...
googletest/test/BUILD.bazel
View file @
9737e63c
...
...
@@ -219,6 +219,13 @@ py_test(
deps
=
[
":gtest_test_utils"
],
)
cc_test
(
name
=
"gtest_assert_by_exception_test"
,
size
=
"small"
,
srcs
=
[
"gtest_assert_by_exception_test.cc"
],
deps
=
[
"//:gtest"
],
)
cc_binary
(
name
=
"gtest_throw_on_failure_test_"
,
testonly
=
1
,
...
...
googletest/test/gtest_assert_by_exception_test.cc
0 → 100644
View file @
9737e63c
// 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 assert-by-exception mode with exceptions enabled.
#include "gtest/gtest.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdexcept>
class
ThrowListener
:
public
testing
::
EmptyTestEventListener
{
void
OnTestPartResult
(
const
testing
::
TestPartResult
&
result
)
override
{
if
(
result
.
type
()
==
testing
::
TestPartResult
::
kFatalFailure
)
{
throw
testing
::
AssertionException
(
result
);
}
}
};
// 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
);
}
static
void
AssertFalse
()
{
ASSERT_EQ
(
2
,
3
)
<<
"Expected failure"
;
}
// Tests that an assertion failure throws a subclass of
// std::runtime_error.
TEST
(
Test
,
Test
)
{
// A successful assertion shouldn't throw.
try
{
EXPECT_EQ
(
3
,
3
);
}
catch
(...)
{
Fail
(
"A successful assertion wrongfully threw."
);
}
// A successful assertion shouldn't throw.
try
{
EXPECT_EQ
(
3
,
4
);
}
catch
(...)
{
Fail
(
"A failed non-fatal assertion wrongfully threw."
);
}
// A failed assertion should throw.
try
{
AssertFalse
();
}
catch
(
const
testing
::
AssertionException
&
e
)
{
if
(
strstr
(
e
.
what
(),
"Expected failure"
)
!=
NULL
)
throw
;
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
kTestForContinuingTest
=
0
;
TEST
(
Test
,
Test2
)
{
// FIXME(sokolov): how to force Test2 to be after Test?
kTestForContinuingTest
=
1
;
}
int
main
(
int
argc
,
char
**
argv
)
{
testing
::
InitGoogleTest
(
&
argc
,
argv
);
testing
::
UnitTest
::
GetInstance
()
->
listeners
().
Append
(
new
ThrowListener
);
int
result
=
RUN_ALL_TESTS
();
if
(
result
==
0
)
{
printf
(
"RUN_ALL_TESTS returned %d
\n
"
,
result
);
Fail
(
"Expected failure instead."
);
}
if
(
kTestForContinuingTest
==
0
)
{
Fail
(
"Should have continued with other tests, but did not."
);
}
return
0
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment