marimo notebooks are pure Python, making them fully testable with standard Python testing frameworks. marimo provides first-class pytest integration with reactive test execution.
# Run all tests in a notebookpytest test_notebook.py# Run with verbose outputpytest -v test_notebook.py# Run specific testpytest test_notebook.py::test_addition# Run with coveragepytest --cov=. test_notebook.py
# ✓ Good: One test per cell or related tests together@app.celldef test_addition(): assert add(2, 3) == 5 return# ❌ Avoid: Mixing tests with application logic@app.celldef compute_and_test(): result = expensive_computation() assert result > 0 # Test mixed with computation return result
Use descriptive test names
Follow pytest conventions for test naming:
def test_user_authentication_with_valid_credentials(): # Clear what's being tested passdef test_data_loading_handles_missing_file(): # Clear error condition being tested pass
Test edge cases
Cover boundary conditions and error cases:
import pytestdef test_division_by_zero(): with pytest.raises(ZeroDivisionError): result = 1 / 0def test_empty_list_input(): assert process_list([]) == []def test_negative_input_validation(): with pytest.raises(ValueError): validate_positive(-1)
Use fixtures for setup/teardown
Avoid duplication with pytest fixtures:
@pytest.fixturedef temp_database(): # Setup db = create_test_database() populate_test_data(db) yield db # Teardown db.drop_all_tables() db.close()
import marimo as moapp = mo.App()@app.functiondef inc(x): """Increment a number by 1.""" return x + 1@app.celldef test_answer(): # This test intentionally fails to demonstrate failure reporting assert inc(3) == 5, "This test fails" return@app.celldef test_sanity(): # This test passes assert inc(3) == 4, "This test passes" returnif __name__ == "__main__": app.run()
When tests fail, marimo provides detailed tracebacks:
import marimo as moimport pytest@app.celldef test_with_debug(): # Use pytest.set_trace() for interactive debugging value = compute_something() # Add informative assertion messages assert value > 0, f"Expected positive value, got {value}" # Use pytest.approx for floating point assert value == pytest.approx(3.14, rel=1e-2) return