Expecttest
Expecttest is a Python library that implements 'expect tests' (also known as 'golden tests' or 'snapshot tests'). Unlike traditional asserts, it automatically populates the expected output of a test. When the test output changes, the library facilitates updating the expected output directly within the Python source file by modifying it in-place. The current version is 0.3.0, released in December 2024, indicating active development with a fairly rapid release cadence.
Warnings
- breaking The primary mechanism of `expecttest` involves directly modifying your source code files when `EXPECTTEST_ACCEPT=1` is set. This is a deliberate feature, but it means test runs can alter committed files, requiring careful use and potentially source control review of changes.
- gotcha Tests using `expecttest` will fail if the actual output differs from the stored expected value, even if the change is valid (e.g., due to a new feature). You must explicitly run tests with `EXPECTTEST_ACCEPT=1` to update the expected values in the source code.
- gotcha The effectiveness of `expecttest` heavily relies on designing the output format of your test results. Poorly structured or verbose output can lead to 'spurious changes' (e.g., minor whitespace variations, irrelevant details) that frequently cause tests to fail and require re-acceptance, diminishing their value.
- gotcha Over-reliance on `EXPECTTEST_ACCEPT=1` without thorough review of the updated expected values can lead to 'locking in' an implementation rather than verifying desired behavior, potentially masking bugs.
Install
-
pip install expecttest
Imports
- TestCase
from expecttest import TestCase
- assert_expected_inline
from expecttest import assert_expected_inline
Quickstart
import unittest
import os
from expecttest import TestCase, assert_expected_inline
# Example for unittest integration
class TestMyFunction(TestCase):
def test_basic_output(self):
result = f"Hello, {1 + 2}!\nMultiline output." # Simulate some function output
# On first run, leave expected blank. Run with EXPECTTEST_ACCEPT=1 to populate.
# self.assertExpectedInline(result, """)"""
self.assertExpectedInline(result, """Hello, 3!\nMultiline output.""")
# Example for pytest or general use
def test_another_function():
data = {'key': 'value', 'number': 123}
result = str(data)
# On first run, leave expected blank. Run with EXPECTTEST_ACCEPT=1 to populate.
# assert_expected_inline(result, """)"""
assert_expected_inline(result, """{'key': 'value', 'number': 123}""")
if __name__ == '__main__':
# To update the expected values in the source file, run:
# EXPECTTEST_ACCEPT=1 python your_test_file.py
# or EXPECTTEST_ACCEPT=1 pytest your_test_file.py
if os.environ.get('EXPECTTEST_ACCEPT') == '1':
print("Running in ACCEPT mode. Expected values will be updated.")
unittest.main()