# How GoogleTest Handles Fatal and Non-Fatal Failures: The Complete Guide to ASSERT and EXPECT

> Understand how GoogleTest handles fatal and non-fatal failures using ASSERT and EXPECT macros. Learn to control test execution and manage results effectively for robust testing.

- Repository: [Google/googletest](https://github.com/google/googletest)
- Tags: deep-dive
- Published: 2026-08-30

---

**GoogleTest distinguishes fatal failures from non-fatal failures by throwing a `GoogleTestFailureException` for `ASSERT_*` macros to immediately abort test execution, while `EXPECT_*` macros record `TestPartResult` objects with type `kNonFatalFailure` and allow the test function to continue running.**

GoogleTest (the `google/googletest` repository) is the industry-standard C++ testing framework used by millions of developers to validate code behavior. Understanding how GoogleTest handles fatal and non-fatal failures is essential for writing test suites that either halt immediately on critical invariant violations or collect multiple soft assertion failures for comprehensive debugging. This mechanism relies on a sophisticated interplay between macro expansion, the `TestPartResult` type system, and exception-based control flow.

## The Two Categories of Test Failures

GoogleTest classifies assertion failures into two distinct categories that determine execution flow:

**Fatal failures** are generated by the `ASSERT_*` macro family (e.g., `ASSERT_TRUE`, `ASSERT_EQ`). When a fatal failure occurs, the framework immediately aborts the current test function, skipping all subsequent code. These are recorded as `TestPartResult` objects with type `kFatalFailure`.

**Non-fatal failures** are generated by the `EXPECT_*` macro family (e.g., `EXPECT_TRUE`, `EXPECT_EQ`). These record the failure details but allow the test to continue executing subsequent assertions. These map to `TestPartResult` type `kNonFatalFailure`.

Both categories propagate to test listeners through the `TestPartResultReporterInterface`, but only fatal failures trigger the exception mechanism that unwinds the stack.

## Internal Architecture of Failure Handling

### TestPartResult and the Type Enumeration

At the core of the failure classification system is the `TestPartResult` class defined in [`googletest/include/gtest/gtest-test-part.h`](https://github.com/google/googletest/blob/main/googletest/include/gtest/gtest-test-part.h). This class encapsulates individual assertion outcomes and uses the `TestPartResult::Type` enumeration to distinguish severity:

- `kFatalFailure` – Indicates the test cannot continue
- `kNonFatalFailure` – Indicates a failed assertion that should be logged without stopping execution

Every assertion failure, whether fatal or non-fatal, creates a `TestPartResult` object containing the file path, line number, failure message, and type classification.

### Recording Failures in gtest.cc

The actual creation of failure records occurs in `googletest/src/gtest.cc` through the `AddFailureAt` function. This function constructs a `TestPartResult` from the failure details and forwards it to the current test's result reporter:

```cpp
void AddFailureAt(const char* file, 
                  int line, 
                  const std::string& message,
                  TestPartResult::Type result_type) {
  const TestPartResult result(result_type, file, line, message);
  GetUnitTestImpl()->current_test_result()->AddTestPartResult(result);
}

```

This unified recording mechanism ensures both fatal and non-fatal failures are stored in the test history, making them available for output formatting and analysis tools regardless of whether execution continues.

## Macro Implementation and Control Flow

### How ASSERT and EXPECT Macros Expand

The distinction between fatal and non-fatal behavior originates in the macro definitions found in [`googletest/include/gtest/gtest.h`](https://github.com/google/googletest/blob/main/googletest/include/gtest/gtest.h). The `GTEST_ASSERT_` and `GTEST_EXPECT_` macro families handle failures differently:

**`GTEST_ASSERT_`** generates fatal failures by passing `TestPartResult::kFatalFailure` to the assertion helper:

```cpp
#define GTEST_ASSERT_(expression, fail) \
  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
  if (const ::testing::AssertionResult gtest_ar_ = (expression)) \
    ; \
  else \
    ::testing::internal::AssertHelper(::testing::TestPartResult::kFatalFailure, \
                                      __FILE__, __LINE__, fail).operator= \
                                       (gtest_ar_)

```

**`GTEST_EXPECT_`** generates non-fatal failures using `TestPartResult::kNonFatalFailure`:

```cpp
#define GTEST_EXPECT_(expression, fail) \
  GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
  if (const ::testing::AssertionResult gtest_ar_ = (expression)) \
    ; \
  else \
    ::testing::internal::AssertHelper(::testing::TestPartResult::kNonFatalFailure, \
                                      __FILE__, __LINE__, fail).operator= \
                                       (gtest_ar_)

```

Both macros instantiate an `AssertHelper` object with the appropriate type enum, but the critical difference emerges in how that helper handles the assignment operator.

### The AssertHelper Class and Exception Throwing

The `AssertHelper` class in [`googletest/include/gtest/gtest.h`](https://github.com/google/googletest/blob/main/googletest/include/gtest/gtest.h) serves as the execution control point. Its constructor stores the failure type, and its `operator=` implements the fatal vs non-fatal logic:

```cpp
class AssertHelper {
 public:
  AssertHelper(TestPartResult::Type type, const char* file, int line,
               const std::string& message)
      : type_(type), file_(file), line_(line), message_(message) {}
  
  void operator=(const AssertionResult& ar) const {
    if (!ar) {
      AddFailureAt(file_, line_, message_ + ar.message(), type_);
      if (type_ == TestPartResult::kFatalFailure) {
        throw ::testing::internal::GoogleTestFailureException();
      }
    }
  }
};

```

When the `AssertionResult` indicates failure, `AddFailureAt` records the result. Immediately afterward, the code checks if `type_` equals `kFatalFailure`. If so, it throws `GoogleTestFailureException`, which propagates up the stack and terminates the current test function. Non-fatal failures skip this exception throw, allowing execution to fall through to the next statement.

## Practical Code Examples

### Example 1: Fatal Failure Stops Execution

```cpp
TEST(MathOperations, FatalDivisionByZero) {
  int denominator = 0;
  
  EXPECT_EQ(denominator, 0);  // Non-fatal: continues
  
  // Fatal assertion: if this fails, the test aborts immediately
  ASSERT_NE(denominator, 0) << "Cannot divide by zero";
  
  // This line never executes if denominator is 0
  int result = 100 / denominator;
  EXPECT_EQ(result, 50);  // Never reached
}

```

In this example, if `denominator` is 0, the `ASSERT_NE` records a fatal failure and throws `GoogleTestFailureException`, preventing the division operation that would crash the process.

### Example 2: Non-Fatal Failures Collect Multiple Errors

```cpp
TEST(ConfigParser, ValidatesAllFields) {
  Config config = LoadConfig("test.conf");
  
  // All three assertions run regardless of failure
  EXPECT_FALSE(config.host.empty()) << "Host must be specified";
  EXPECT_GT(config.port, 0) << "Port must be positive";
  EXPECT_LT(config.port, 65536) << "Port must be valid";
  
  // Test continues to validate optional fields
  EXPECT_NO_THROW(config.Validate());
}

```

Here, `EXPECT_*` macros generate three separate `TestPartResult` entries with type `kNonFatalFailure` if the conditions fail, but the test executes through to completion, providing a complete report of all validation errors.

## Summary

- **Fatal failures** (`ASSERT_*` macros) immediately abort test execution by throwing `GoogleTestFailureException` after recording a `TestPartResult` with type `kFatalFailure` in `googletest/src/gtest.cc`.
- **Non-fatal failures** (`EXPECT_*` macros) record `TestPartResult` objects with type `kNonFatalFailure` via `AddFailureAt` but allow the test function to continue executing subsequent statements.
- The `AssertHelper` class in [`googletest/include/gtest/gtest.h`](https://github.com/google/googletest/blob/main/googletest/include/gtest/gtest.h) serves as the control gate, checking the `TestPartResult::Type` enum to determine whether to throw the terminating exception.
- Both failure types propagate to registered listeners through `TestPartResultReporterInterface::ReportTestPartResult`, ensuring comprehensive logging regardless of severity.

## Frequently Asked Questions

### What is the difference between ASSERT and EXPECT in GoogleTest?

`ASSERT_*` macros generate fatal failures that stop the current test function immediately, while `EXPECT_*` macros generate non-fatal failures that allow the test to continue. Use `ASSERT` when subsequent code depends on the assertion being true (like checking a pointer before dereferencing), and use `EXPECT` when you want to collect multiple independent failure points (like validating several object properties).

### How does GoogleTest stop execution after a fatal failure?

After recording the failure through `AddFailureAt` in `googletest/src/gtest.cc`, the `AssertHelper::operator=` method checks if the `TestPartResult` type is `kFatalFailure`. If so, it throws `::testing::internal::GoogleTestFailureException`, which unwinds the stack and terminates the current test function without executing remaining code.

### Can I customize how fatal failures are handled?

Yes, you can implement custom `TestPartResultReporterInterface` subclasses to modify how failures are reported, but the control-flow behavior (throwing exception for fatal failures) is hardcoded in the `AssertHelper` class. To change termination behavior, you would need to fork the framework and modify the `operator=` implementation in [`googletest/include/gtest/gtest.h`](https://github.com/google/googletest/blob/main/googletest/include/gtest/gtest.h).

### Do non-fatal failures affect the final test result?

Yes, non-fatal failures mark the test as failed even though execution continues. The test process exits with a non-zero status code if any `EXPECT_*` assertion fails, making them functionally equivalent to fatal failures for CI/CD pipeline pass/fail determination—the only difference is the granularity of feedback within a single test function.