# Assertions Reference

This page lists the assertion macros provided by GoogleTest for verifying code
behavior. To use them, include the header `gtest/gtest.h`.

The majority of the macros listed below come as a pair with an `EXPECT_` variant
and an `ASSERT_` variant. Upon failure, `EXPECT_` macros generate nonfatal
failures and allow the current function to continue running, while `ASSERT_`
macros generate fatal failures and abort the current function.

All assertion macros support streaming a custom failure message into them with
the `<<` operator, for example:

```cpp
EXPECT_TRUE(my_condition) << "My condition is not true";
```

Anything that can be streamed to an `ostream` can be streamed to an assertion
macro—in particular, C strings and string objects. If a wide string (`wchar_t*`,
`TCHAR*` in `UNICODE` mode on Windows, or `std::wstring`) is streamed to an
assertion, it will be translated to UTF-8 when printed.

## Explicit Success and Failure {#success-failure}

The assertions in this section generate a success or failure directly instead of
testing a value or expression. These are useful when control flow, rather than a
Boolean expression, determines the test's success or failure, as shown by the
following example:

```c++
switch(expression) {
  case 1:
    ... some checks ...
  case 2:
    ... some other checks ...
  default:
    FAIL() << "We shouldn't get here.";
}
```

### SUCCEED {#SUCCEED}

`SUCCEED()`

Generates a success. This *does not* make the overall test succeed. A test is
considered successful only if none of its assertions fail during its execution.

The `SUCCEED` assertion is purely documentary and currently doesn't generate any
user-visible output. However, we may add `SUCCEED` messages to GoogleTest output
in the future.

### FAIL {#FAIL}

`FAIL()`

Generates a fatal failure, which returns from the current function.

Can only be used in functions that return `void`. See
[Assertion Placement](../advanced.md#assertion-placement) for more information.

### ADD_FAILURE {#ADD_FAILURE}

`ADD_FAILURE()`

Generates a nonfatal failure, which allows the current function to continue
running.

### ADD_FAILURE_AT {#ADD_FAILURE_AT}

`ADD_FAILURE_AT(`*`file_path`*`,`*`line_number`*`)`

Generates a nonfatal failure at the file and line number specified.

## Generalized Assertion {#generalized}

The following assertion allows [matchers](matchers.md) to be used to verify
values.

### EXPECT_THAT {#EXPECT_THAT}

`EXPECT_THAT(`*`value`*`,`*`matcher`*`)` \
`ASSERT_THAT(`*`value`*`,`*`matcher`*`)`

Verifies that *`value`* matches the [matcher](matchers.md) *`matcher`*.

For example, the following code verifies that the string `value1` starts with
`"Hello"`, `value2` matches a regular expression, and `value3` is between 5 and
10:

```cpp
#include "gmock/gmock.h"

using ::testing::AllOf;
using ::testing::Gt;
using ::testing::Lt;
using ::testing::MatchesRegex;
using ::testing::StartsWith;

...
EXPECT_THAT(value1, StartsWith("Hello"));
EXPECT_THAT(value2, MatchesRegex("Line \\d+"));
ASSERT_THAT(value3, AllOf(Gt(5), Lt(10)));
```

Matchers enable assertions of this form to read like English and generate
informative failure messages. For example, if the above assertion on `value1`
fails, the resulting message will be similar to the following:

```
Value of: value1
  Actual: "Hi, world!"
Expected: starts with "Hello"
```

GoogleTest provides a built-in library of matchers—see the
[Matchers Reference](matchers.md). It is also possible to write your own
matchers—see [Writing New Matchers Quickly](../gmock_cook_book.md#NewMatchers).
The use of matchers makes `EXPECT_THAT` a powerful, extensible assertion.

*The idea for this assertion was borrowed from Joe Walnes' Hamcrest project,
which adds `assertThat()` to JUnit.*

## Boolean Conditions {#boolean}

The following assertions test Boolean conditions.

### EXPECT_TRUE {#EXPECT_TRUE}

`EXPECT_TRUE(`*`condition`*`)` \
`ASSERT_TRUE(`*`condition`*`)`

Verifies that *`condition`* is true.

### EXPECT_FALSE {#EXPECT_FALSE}

`EXPECT_FALSE(`*`condition`*`)` \
`ASSERT_FALSE(`*`condition`*`)`

Verifies that *`condition`* is false.

## Binary Comparison {#binary-comparison}

The following assertions compare two values. The value arguments must be
comparable by the assertion's comparison operator, otherwise a compiler error
will result.

If an argument supports the `<<` operator, it will be called to print the
argument when the assertion fails. Otherwise, GoogleTest will attempt to print
them in the best way it can—see
[Teaching GoogleTest How to Print Your Values](../advanced.md#teaching-googletest-how-to-print-your-values).

Arguments are always evaluated exactly once, so it's OK for the arguments to
have side effects. However, the argument evaluation order is undefined and
programs should not depend on any particular argument evaluation order.

These assertions work with both narrow and wide string objects (`string` and
`wstring`).

See also the [Floating-Point Comparison](#floating-point) assertions to compare
floating-point numbers and avoid problems caused by rounding.

### EXPECT_EQ {#EXPECT_EQ}

`EXPECT_EQ(`*`val1`*`,`*`val2`*`)` \
`ASSERT_EQ(`*`val1`*`,`*`val2`*`)`

Verifies that *`val1`*`==`*`val2`*.

Does pointer equality on pointers. If used on two C strings, it tests if they
are in the same memory location, not if they have the same value. Use
[`EXPECT_STREQ`](#EXPECT_STREQ) to compare C strings (e.g. `const char*`) by
value.

When comparing a pointer to `NULL`, use `EXPECT_EQ(`*`ptr`*`, nullptr)` instead
of `EXPECT_EQ(`*`ptr`*`, NULL)`.

### EXPECT_NE {#EXPECT_NE}

`EXPECT_NE(`*`val1`*`,`*`val2`*`)` \
`ASSERT_NE(`*`val1`*`,`*`val2`*`)`

Verifies that *`val1`*`!=`*`val2`*.

Does pointer equality on pointers. If used on two C strings, it tests if they
are in different memory locations, not if they have different values. Use
[`EXPECT_STRNE`](#EXPECT_STRNE) to compare C strings (e.g. `const char*`) by
value.

When comparing a pointer to `NULL`, use `EXPECT_NE(`*`ptr`*`, nullptr)` instead
of `EXPECT_NE(`*`ptr`*`, NULL)`.

### EXPECT_LT {#EXPECT_LT}

`EXPECT_LT(`*`val1`*`,`*`val2`*`)` \
`ASSERT_LT(`*`val1`*`,`*`val2`*`)`

Verifies that *`val1`*`<`*`val2`*.

### EXPECT_LE {#EXPECT_LE}

`EXPECT_LE(`*`val1`*`,`*`val2`*`)` \
`ASSERT_LE(`*`val1`*`,`*`val2`*`)`

Verifies that *`val1`*`<=`*`val2`*.

### EXPECT_GT {#EXPECT_GT}

`EXPECT_GT(`*`val1`*`,`*`val2`*`)` \
`ASSERT_GT(`*`val1`*`,`*`val2`*`)`

Verifies that *`val1`*`>`*`val2`*.

### EXPECT_GE {#EXPECT_GE}

`EXPECT_GE(`*`val1`*`,`*`val2`*`)` \
`ASSERT_GE(`*`val1`*`,`*`val2`*`)`

Verifies that *`val1`*`>=`*`val2`*.

## String Comparison {#c-strings}

The following assertions compare two **C strings**. To compare two `string`
objects, use [`EXPECT_EQ`](#EXPECT_EQ) or [`EXPECT_NE`](#EXPECT_NE) instead.

These assertions also accept wide C strings (`wchar_t*`). If a comparison of two
wide strings fails, their values will be printed as UTF-8 narrow strings.

To compare a C string with `NULL`, use `EXPECT_EQ(`*`c_string`*`, nullptr)` or
`EXPECT_NE(`*`c_string`*`, nullptr)`.

### EXPECT_STREQ {#EXPECT_STREQ}

`EXPECT_STREQ(`*`str1`*`,`*`str2`*`)` \
`ASSERT_STREQ(`*`str1`*`,`*`str2`*`)`

Verifies that the two C strings *`str1`* and *`str2`* have the same contents.

### EXPECT_STRNE {#EXPECT_STRNE}

`EXPECT_STRNE(`*`str1`*`,`*`str2`*`)` \
`ASSERT_STRNE(`*`str1`*`,`*`str2`*`)`

Verifies that the two C strings *`str1`* and *`str2`* have different contents.

### EXPECT_STRCASEEQ {#EXPECT_STRCASEEQ}

`EXPECT_STRCASEEQ(`*`str1`*`,`*`str2`*`)` \
`ASSERT_STRCASEEQ(`*`str1`*`,`*`str2`*`)`

Verifies that the two C strings *`str1`* and *`str2`* have the same contents,
ignoring case.

### EXPECT_STRCASENE {#EXPECT_STRCASENE}

`EXPECT_STRCASENE(`*`str1`*`,`*`str2`*`)` \
`ASSERT_STRCASENE(`*`str1`*`,`*`str2`*`)`

Verifies that the two C strings *`str1`* and *`str2`* have different contents,
ignoring case.

## Floating-Point Comparison {#floating-point}

The following assertions compare two floating-point values.

Due to rounding errors, it is very unlikely that two floating-point values will
match exactly, so `EXPECT_EQ` is not suitable. In general, for floating-point
comparison to make sense, the user needs to carefully choose the error bound.

GoogleTest also provides assertions that use a default error bound based on
Units in the Last Place (ULPs). To learn more about ULPs, see the article
[Comparing Floating Point Numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).

### EXPECT_FLOAT_EQ {#EXPECT_FLOAT_EQ}

`EXPECT_FLOAT_EQ(`*`val1`*`,`*`val2`*`)` \
`ASSERT_FLOAT_EQ(`*`val1`*`,`*`val2`*`)`

Verifies that the two `float` values *`val1`* and *`val2`* are approximately
equal, to within 4 ULPs from each other.

### EXPECT_DOUBLE_EQ {#EXPECT_DOUBLE_EQ}

`EXPECT_DOUBLE_EQ(`*`val1`*`,`*`val2`*`)` \
`ASSERT_DOUBLE_EQ(`*`val1`*`,`*`val2`*`)`

Verifies that the two `double` values *`val1`* and *`val2`* are approximately
equal, to within 4 ULPs from each other.

### EXPECT_NEAR {#EXPECT_NEAR}

`EXPECT_NEAR(`*`val1`*`,`*`val2`*`,`*`abs_error`*`)` \
`ASSERT_NEAR(`*`val1`*`,`*`val2`*`,`*`abs_error`*`)`

Verifies that the difference between *`val1`* and *`val2`* does not exceed the
absolute error bound *`abs_error`*.

## Exception Assertions {#exceptions}

The following assertions verify that a piece of code throws, or does not throw,
an exception. Usage requires exceptions to be enabled in the build environment.

Note that the piece of code under test can be a compound statement, for example:

```cpp
EXPECT_NO_THROW({
  int n = 5;
  DoSomething(&n);
});
```

### EXPECT_THROW {#EXPECT_THROW}

`EXPECT_THROW(`*`statement`*`,`*`exception_type`*`)` \
`ASSERT_THROW(`*`statement`*`,`*`exception_type`*`)`

Verifies that *`statement`* throws an exception of type *`exception_type`*.

### EXPECT_ANY_THROW {#EXPECT_ANY_THROW}

`EXPECT_ANY_THROW(`*`statement`*`)` \
`ASSERT_ANY_THROW(`*`statement`*`)`

Verifies that *`statement`* throws an exception of any type.

### EXPECT_NO_THROW {#EXPECT_NO_THROW}

`EXPECT_NO_THROW(`*`statement`*`)` \
`ASSERT_NO_THROW(`*`statement`*`)`

Verifies that *`statement`* does not throw any exception.

## Predicate Assertions {#predicates}

The following assertions enable more complex predicates to be verified while
printing a more clear failure message than if `EXPECT_TRUE` were used alone.

### EXPECT_PRED* {#EXPECT_PRED}

`EXPECT_PRED1(`*`pred`*`,`*`val1`*`)` \
`EXPECT_PRED2(`*`pred`*`,`*`val1`*`,`*`val2`*`)` \
`EXPECT_PRED3(`*`pred`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`)` \
`EXPECT_PRED4(`*`pred`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`,`*`val4`*`)` \
`EXPECT_PRED5(`*`pred`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`,`*`val4`*`,`*`val5`*`)`

`ASSERT_PRED1(`*`pred`*`,`*`val1`*`)` \
`ASSERT_PRED2(`*`pred`*`,`*`val1`*`,`*`val2`*`)` \
`ASSERT_PRED3(`*`pred`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`)` \
`ASSERT_PRED4(`*`pred`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`,`*`val4`*`)` \
`ASSERT_PRED5(`*`pred`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`,`*`val4`*`,`*`val5`*`)`

Verifies that the predicate *`pred`* returns `true` when passed the given values
as arguments.

The parameter *`pred`* is a function or functor that accepts as many arguments
as the corresponding macro accepts values. If *`pred`* returns `true` for the
given arguments, the assertion succeeds, otherwise the assertion fails.

When the assertion fails, it prints the value of each argument. Arguments are
always evaluated exactly once.

As an example, see the following code:

```cpp
// Returns true if m and n have no common divisors except 1.
bool MutuallyPrime(int m, int n) { ... }
...
const int a = 3;
const int b = 4;
const int c = 10;
...
EXPECT_PRED2(MutuallyPrime, a, b);  // Succeeds
EXPECT_PRED2(MutuallyPrime, b, c);  // Fails
```

In the above example, the first assertion succeeds, and the second fails with
the following message:

```
MutuallyPrime(b, c) is false, where
b is 4
c is 10
```

Note that if the given predicate is an overloaded function or a function
template, the assertion macro might not be able to determine which version to
use, and it might be necessary to explicitly specify the type of the function.
For example, for a Boolean function `IsPositive()` overloaded to take either a
single `int` or `double` argument, it would be necessary to write one of the
following:

```cpp
EXPECT_PRED1(static_cast<bool (*)(int)>(IsPositive), 5);
EXPECT_PRED1(static_cast<bool (*)(double)>(IsPositive), 3.14);
```

Writing simply `EXPECT_PRED1(IsPositive, 5);` would result in a compiler error.
Similarly, to use a template function, specify the template arguments:

```cpp
template <typename T>
bool IsNegative(T x) {
  return x < 0;
}
...
EXPECT_PRED1(IsNegative<int>, -5);  // Must specify type for IsNegative
```

If a template has multiple parameters, wrap the predicate in parentheses so the
macro arguments are parsed correctly:

```cpp
ASSERT_PRED2((MyPredicate<int, int>), 5, 0);
```

### EXPECT_PRED_FORMAT* {#EXPECT_PRED_FORMAT}

`EXPECT_PRED_FORMAT1(`*`pred_formatter`*`,`*`val1`*`)` \
`EXPECT_PRED_FORMAT2(`*`pred_formatter`*`,`*`val1`*`,`*`val2`*`)` \
`EXPECT_PRED_FORMAT3(`*`pred_formatter`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`)` \
`EXPECT_PRED_FORMAT4(`*`pred_formatter`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`,`*`val4`*`)`
\
`EXPECT_PRED_FORMAT5(`*`pred_formatter`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`,`*`val4`*`,`*`val5`*`)`

`ASSERT_PRED_FORMAT1(`*`pred_formatter`*`,`*`val1`*`)` \
`ASSERT_PRED_FORMAT2(`*`pred_formatter`*`,`*`val1`*`,`*`val2`*`)` \
`ASSERT_PRED_FORMAT3(`*`pred_formatter`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`)` \
`ASSERT_PRED_FORMAT4(`*`pred_formatter`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`,`*`val4`*`)`
\
`ASSERT_PRED_FORMAT5(`*`pred_formatter`*`,`*`val1`*`,`*`val2`*`,`*`val3`*`,`*`val4`*`,`*`val5`*`)`

Verifies that the predicate *`pred_formatter`* succeeds when passed the given
values as arguments.

The parameter *`pred_formatter`* is a *predicate-formatter*, which is a function
or functor with the signature:

```cpp
testing::AssertionResult PredicateFormatter(const char* expr1,
                                            const char* expr2,
                                            ...
                                            const char* exprn,
                                            T1 val1,
                                            T2 val2,
                                            ...
                                            Tn valn);
```

where *`val1`*, *`val2`*, ..., *`valn`* are the values of the predicate
arguments, and *`expr1`*, *`expr2`*, ..., *`exprn`* are the corresponding
expressions as they appear in the source code. The types `T1`, `T2`, ..., `Tn`
can be either value types or reference types; if an argument has type `T`, it
can be declared as either `T` or `const T&`, whichever is appropriate. For more
about the return type `testing::AssertionResult`, see
[Using a Function That Returns an AssertionResult](../advanced.md#using-a-function-that-returns-an-assertionresult).

As an example, see the following code:

```cpp
// Returns the smallest prime common divisor of m and n,
// or 1 when m and n are mutually prime.
int SmallestPrimeCommonDivisor(int m, int n) { ... }

// Returns true if m and n have no common divisors except 1.
bool MutuallyPrime(int m, int n) { ... }

// A predicate-formatter for asserting that two integers are mutually prime.
testing::AssertionResult AssertMutuallyPrime(const char* m_expr,
                                             const char* n_expr,
                                             int m,
                                             int n) {
  if (MutuallyPrime(m, n)) return testing::AssertionSuccess();

  return testing::AssertionFailure() << m_expr << " and " << n_expr
      << " (" << m << " and " << n << ") are not mutually prime, "
      << "as they have a common divisor " << SmallestPrimeCommonDivisor(m, n);
}

...
const int a = 3;
const int b = 4;
const int c = 10;
...
EXPECT_PRED_FORMAT2(AssertMutuallyPrime, a, b);  // Succeeds
EXPECT_PRED_FORMAT2(AssertMutuallyPrime, b, c);  // Fails
```

In the above example, the final assertion fails and the predicate-formatter
produces the following failure message:

```
b and c (4 and 10) are not mutually prime, as they have a common divisor 2
```

## Windows HRESULT Assertions {#HRESULT}

The following assertions test for `HRESULT` success or failure. For example:

```cpp
CComPtr<IShellDispatch2> shell;
ASSERT_HRESULT_SUCCEEDED(shell.CoCreateInstance(L"Shell.Application"));
CComVariant empty;
ASSERT_HRESULT_SUCCEEDED(shell->ShellExecute(CComBSTR(url), empty, empty, empty, empty));
```

The generated output contains the human-readable error message associated with
the returned `HRESULT` code.

### EXPECT_HRESULT_SUCCEEDED {#EXPECT_HRESULT_SUCCEEDED}

`EXPECT_HRESULT_SUCCEEDED(`*`expression`*`)` \
`ASSERT_HRESULT_SUCCEEDED(`*`expression`*`)`

Verifies that *`expression`* is a success `HRESULT`.

### EXPECT_HRESULT_FAILED {#EXPECT_HRESULT_FAILED}

`EXPECT_HRESULT_FAILED(`*`expression`*`)` \
`EXPECT_HRESULT_FAILED(`*`expression`*`)`

Verifies that *`expression`* is a failure `HRESULT`.

## Death Assertions {#death}

The following assertions verify that a piece of code causes the process to
terminate. For context, see [Death Tests](../advanced.md#death-tests).

These assertions spawn a new process and execute the code under test in that
process. How that happens depends on the platform and the variable
`::testing::GTEST_FLAG(death_test_style)`, which is initialized from the
command-line flag `--gtest_death_test_style`.

*   On POSIX systems, `fork()` (or `clone()` on Linux) is used to spawn the
    child, after which:
    *   If the variable's value is `"fast"`, the death test statement is
        immediately executed.
    *   If the variable's value is `"threadsafe"`, the child process re-executes
        the unit test binary just as it was originally invoked, but with some
        extra flags to cause just the single death test under consideration to
        be run.
*   On Windows, the child is spawned using the `CreateProcess()` API, and
    re-executes the binary to cause just the single death test under
    consideration to be run - much like the `"threadsafe"` mode on POSIX.

Other values for the variable are illegal and will cause the death test to fail.
Currently, the flag's default value is
**`"fast"`**.

If the death test statement runs to completion without dying, the child process
will nonetheless terminate, and the assertion fails.

Note that the piece of code under test can be a compound statement, for example:

```cpp
EXPECT_DEATH({
  int n = 5;
  DoSomething(&n);
}, "Error on line .* of DoSomething()");
```

### EXPECT_DEATH {#EXPECT_DEATH}

`EXPECT_DEATH(`*`statement`*`,`*`matcher`*`)` \
`ASSERT_DEATH(`*`statement`*`,`*`matcher`*`)`

Verifies that *`statement`* causes the process to terminate with a nonzero exit
status and produces `stderr` output that matches *`matcher`*.

The parameter *`matcher`* is either a [matcher](matchers.md) for a `const
std::string&`, or a regular expression (see
[Regular Expression Syntax](../advanced.md#regular-expression-syntax))—a bare
string *`s`* (with no matcher) is treated as
[`ContainsRegex(s)`](matchers.md#string-matchers), **not**
[`Eq(s)`](matchers.md#generic-comparison).

For example, the following code verifies that calling `DoSomething(42)` causes
the process to die with an error message that contains the text `My error`:

```cpp
EXPECT_DEATH(DoSomething(42), "My error");
```

### EXPECT_DEATH_IF_SUPPORTED {#EXPECT_DEATH_IF_SUPPORTED}

`EXPECT_DEATH_IF_SUPPORTED(`*`statement`*`,`*`matcher`*`)` \
`ASSERT_DEATH_IF_SUPPORTED(`*`statement`*`,`*`matcher`*`)`

If death tests are supported, behaves the same as
[`EXPECT_DEATH`](#EXPECT_DEATH). Otherwise, verifies nothing.

### EXPECT_DEBUG_DEATH {#EXPECT_DEBUG_DEATH}

`EXPECT_DEBUG_DEATH(`*`statement`*`,`*`matcher`*`)` \
`ASSERT_DEBUG_DEATH(`*`statement`*`,`*`matcher`*`)`

In debug mode, behaves the same as [`EXPECT_DEATH`](#EXPECT_DEATH). When not in
debug mode (i.e. `NDEBUG` is defined), just executes *`statement`*.

### EXPECT_EXIT {#EXPECT_EXIT}

`EXPECT_EXIT(`*`statement`*`,`*`predicate`*`,`*`matcher`*`)` \
`ASSERT_EXIT(`*`statement`*`,`*`predicate`*`,`*`matcher`*`)`

Verifies that *`statement`* causes the process to terminate with an exit status
that satisfies *`predicate`*, and produces `stderr` output that matches
*`matcher`*.

The parameter *`predicate`* is a function or functor that accepts an `int` exit
status and returns a `bool`. GoogleTest provides two predicates to handle common
cases:

```cpp
// Returns true if the program exited normally with the given exit status code.
::testing::ExitedWithCode(exit_code);

// Returns true if the program was killed by the given signal.
// Not available on Windows.
::testing::KilledBySignal(signal_number);
```

The parameter *`matcher`* is either a [matcher](matchers.md) for a `const
std::string&`, or a regular expression (see
[Regular Expression Syntax](../advanced.md#regular-expression-syntax))—a bare
string *`s`* (with no matcher) is treated as
[`ContainsRegex(s)`](matchers.md#string-matchers), **not**
[`Eq(s)`](matchers.md#generic-comparison).

For example, the following code verifies that calling `NormalExit()` causes the
process to print a message containing the text `Success` to `stderr` and exit
with exit status code 0:

```cpp
EXPECT_EXIT(NormalExit(), testing::ExitedWithCode(0), "Success");
```
