Testing Exceptions
Exceptions are not just error messages that appear when something goes wrong. Exceptions signal specific conditions that might deviate from a program's usual flow. Fundamentally, they are integral to understanding the behavior of a system.
Why Test Exceptions?
1. Verify the Exception Raised
It's essential to test exceptions to ensure that the system raises the expected exception under certain conditions or with specific inputs. These verifications ensure that the program can correctly detect and respond to anomalies.
2. Check Exception Messages
Clear, accurate exception messages are crucial for debugging. By testing exceptions, we confirm that these messages provide the necessary information to engineers about the underlying issue.
3. Validate Control Flow
While using exceptions for control flow is a topic of debate, it's not uncommon in Python. For example, iterators raise StopIteration
exceptions when they have no more items to return, and the for
statement relies on this exception to stop iterating.
Testing Exceptions in Vedro
Vedro provides the catched
function designed to assist in testing exceptions.
Below is an example where we test the scenario of attempting to open a non-existing file. We expect a FileNotFoundError
to be raised, and the test verifies the exception's type and message.
import vedro
from vedro import catched
class Scenario(vedro.Scenario):
subject = "try to open non-existing file"
def given_non_existing_file(self):
self.filename = "non-existing.file"
def when_user_opens_file(self):
with catched(Exception) as self.exc_info:
open(self.filename)
def then_it_should_raise_exception(self):
assert self.exc_info.type is FileNotFoundError
assert str(self.exc_info.value) == f"[Errno 2] No such file or directory: {self.filename!r}"
The exc_info
object encapsulates details about the exception. If an exception is raised within the catched
block, the following attributes are populated:
type
— the type of the exception that was raisedvalue
— the actual exception instancetraceback
— the traceback object containing details about the exception's context
If no exception is raised, all these attributes are set to None
.
Explicit Over Implicit
One of the guiding principles of Vedro is "Explicit is better than implicit". This philosophy extends to exception testing as well. The catched
context manager does not implicitly check whether an exception has occurred or not. Engineers must explicitly include this verification in the test. This approach ensures that tests are transparent and free from assumptions.
Conclusion
In conclusion, while exceptions may seem like disturbances disrupting the smooth flow of a program, they are vital to understanding a system's behavior.