LiveViewTestClient.send_event() catches all handler exceptions and returns {"success": False, "error": "..."} instead of raising them. The existing fuzz test test_fuzz_no_unhandled_crash() only catches exceptions that escape send_event(), so handler-level bugs pass silently.
Added a new test method test_fuzz_handlers_succeed() to the LiveViewSmokeTest mixin that inspects the response from send_event() to detect handler exceptions.
Added test_fuzz_handlers_succeed() method to LiveViewSmokeTest class:
def test_fuzz_handlers_succeed(self):
"""Fuzz payloads should be handled gracefully by handlers (no success=False).
Unlike test_fuzz_no_unhandled_crash which only catches exceptions that escape
send_event(), this test checks that handlers properly handle fuzz input without
raising exceptions. Handlers that fail return {"success": False}, indicating
a bug in validation or error handling.
"""Key Logic:
- Iterates through all discovered views and their handlers
- Sends fuzz payloads to each handler
- Checks if
result["success"] == FalseANDresult["error"]is not None - If both conditions are true, records a failure (handler raised an exception)
- Graceful validation failures (
success=Falsebuterror=None) are acceptable
Updated class docstring to list all test methods:
test_smoke_render- Basic render testtest_smoke_queries- Query count threshold testtest_fuzz_xss- XSS escaping testtest_fuzz_no_unhandled_crash- Exceptions escaping send_event()test_fuzz_handlers_succeed- Handler-level exception detection (NEW)
Updated test_fuzz_no_unhandled_crash() docstring to clarify its scope:
- Only catches exceptions that escape
send_event() - Complements the new
test_fuzz_handlers_succeed()test
Added 4 new tests for the new functionality:
-
test_fuzz_handlers_succeed_detects_handler_exceptions- Verifies detection of handler exceptions (success=False with error)
-
test_fuzz_handlers_succeed_passes_when_handlers_graceful- Verifies passing when handlers handle all input gracefully
-
test_fuzz_handlers_succeed_ignores_validation_errors- Verifies graceful validation failures (success=False, error=None) are acceptable
-
test_fuzz_handlers_succeed_skips_when_fuzz_false- Verifies the test is skipped when
fuzz=False
- Verifies the test is skipped when
Created comprehensive documentation covering:
- Problem description with code examples
- Solution explanation
- How it works (before/after comparison)
- When to use each test
- Validation vs. exception distinction
- Migration guide
- Testing recommendations
All 54 tests in test_smoke_test.py pass:
- 12 tests for
_check_xss_in_html - 13 tests for
_make_fuzz_params - 7 tests for
_get_handlers - 22 tests for
LiveViewSmokeTestmixin (including 4 new tests)
✅ Fully backward compatible
- New test is automatically included in existing
LiveViewSmokeTestsubclasses - No changes needed to existing test code
- Users can disable by setting
fuzz=Falseor overriding the method
class SearchView(LiveView):
def search(self, query: str = ""):
results = query.split(",") # Crashes on None
self.results = results
# test_fuzz_no_unhandled_crash PASSES (bug missed)
# Exception caught by send_event(), doesn't escape# test_fuzz_handlers_succeed FAILS (bug detected)
# AssertionError: Handler exceptions from fuzz input (1):
# - myapp.views.SearchView.search [type(query=None)]:
# AttributeError: 'NoneType' object has no attribute 'split'- Detects more bugs - Handler-level exceptions are now caught
- Complementary tests - Both tests serve different purposes
- Clear feedback - Failures show exact handler, payload, and error
- No false positives - Distinguishes validation failures from exceptions
- Easy to use - Automatically included, no code changes needed
python/djust/testing.py- Added new test method, updated docstringspython/tests/test_smoke_test.py- Added 4 new testsdocs/HANDLER_EXCEPTION_DETECTION.md- Comprehensive documentation (new)IMPLEMENTATION_SUMMARY.md- This file (new)
- ✅ Implementation complete
- ✅ Tests passing
- ✅ Documentation written
- 🔲 Update CHANGELOG.md
- 🔲 Consider adding example to demo project