Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use assertions to verify that a program’s assumptions hold—not to handle ordinary failures. In tests, assert observable behavior; in runtime code, reserve assertions for programmer-controlled invariants whose violation indicates a defect. Validate user input and handle missing files, permissions, timeouts, and unavailable services through explicit, recoverable error paths.

What an assertion is for

An assertion is an executable check of an expected condition. In a test, it compares actual behavior with the test’s contract. In application code, it can express a programmer-controlled invariant: a condition the design says should always be true at that point. If the condition fails, that signals a bug or an impossible state—not a routine problem the program should quietly recover from.

Assertions are not a general-purpose error-handling mechanism. A user entering invalid data, a file not existing, a permission being denied, a network timeout, or a service being unavailable are operational possibilities. Validate or handle these cases explicitly, and return an appropriate error when the application needs to continue or explain the problem.

How to write useful assertions in tests

Assert the behavior that matters

Keep an assertion close to the behavior it checks, and express the expected result directly. For example, if a function should return a total:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
assert calculate_total([3, 4]) == 7

This catches an incorrect result. In pytest, ordinary Python assert statements are supported for verifying expectations and values, and pytest can rewrite them to show intermediate values when comparisons fail. That often makes a direct expression more informative than a generic failure call. See the pytest assertion documentation.

Add a message when it contributes context that the expression alone does not provide, but keep the condition itself meaningful. A vague condition or message can make a failure harder to diagnose rather than easier.

Use approximate comparisons for floating-point results

Floating-point arithmetic can introduce rounding differences, so exact equality may fail even when a result is acceptably close. Pytest’s pytest.approx() supports tolerance-aware comparisons for values including scalars, lists, dictionaries, and NumPy arrays. Choose a tolerance based on the domain and make clear why it is appropriate.

assert measured_value == pytest.approx(expected_value, abs=0.01)

This checks that the measured value is within an absolute tolerance of 0.01 of the expected value. The tolerance is an example, not a universal recommendation: select one that fits the precision your application requires. See the pytest documentation on assertions and approximate comparisons.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Check expected exceptions narrowly

When a test expects an operation to raise, use the framework’s exception assertion rather than allowing any failure to count as success. Pytest’s pytest.raises() context manager captures the exception so the test can inspect its type and value.

with pytest.raises(ValueError):
    parse_quantity("not-a-number")

This catches the intended invalid-quantity failure. Assert the narrowest meaningful exception condition: an overly broad expectation can let an unrelated error pass the test. Pytest also exposes the exception’s traceback for additional checks. See pytest’s exception assertion guidance.

When runtime assertions are appropriate

A runtime assertion can document and enforce an internal invariant—for example, that an algorithm has reached a state its design requires before continuing. If that condition is false, the program has violated its own assumptions. Decide deliberately what the language does on failure, since it may panic, terminate, or behave differently according to build configuration.

Do not put required side effects inside an assertion expression. Some languages or build configurations can skip assertion evaluation, and tools may treat assertions differently. A program must not depend on a check being evaluated to perform essential work.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

What to use instead for ordinary failures

For invalid input or environmental problems, use explicit checks and propagate or recover from errors. The caller may need to show a helpful message, request corrected input, retry, or continue with a fallback; an assertion does not provide that normal control flow.

if not input_path.exists():
    return Error("Input file does not exist")

return process(input_path)

This handles a missing file as an expected operational failure rather than treating it as an impossible program state. Apply the same distinction to permissions, timeouts, and unavailable dependencies. Python guidance likewise cautions against using assertions to test failure cases caused by bad user input or operating-system and environment failures; see Python’s assert statement documentation.

Assertion behavior depends on the language and build

Do not assume assertions are universally removed in release builds or universally retained. Check the target language and toolchain. Rust’s stable core documentation, for example, states that assertions are checked in both debug and release builds and cannot be disabled; a false assert! condition invokes panic!. That is Rust-specific guidance, not a rule for Python, Java, C, or C++.

For Python, follow the boundary between assertions about programmer expectations and checks for user or environmental failures, and confirm behavior for the interpreter and deployment mode your application actually uses. See the Rust assert! documentation and Python’s assert statement documentation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A quick decision check

  • Is this a test expectation? Assert the observable result, state change, or documented exception.
  • Is this an internal invariant? A runtime assertion may be appropriate if failure means a defect or impossible state under the design.
  • Could this happen during normal operation? Validate it or use explicit error handling, rather than an assertion.
  • Does the comparison involve floating-point values? Use a domain-appropriate tolerance if rounding is expected.
  • Could assertion evaluation vary by language or build? Check the specific toolchain and never hide required side effects in the expression.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.