Testing for Graceful Program Exits in Rust
The Problem
I was recently working on a compiler written in Rust, and ran into an annoying problem. I wanted nice error messaging for my users, but found it tricky to test. Take for instance the following section, where I check if we would possibly have a redeclared label:
This checks our declared labels, and gracefully exits the parser after printing a message to stdout. This works well, but it’s impossible to test.
Because Rust runs it’s test threads in the same as the code execution, this abort()
function will end the test entirely without returning a failure. That’s fine for users, but not for our needs
The Solution
Without rewriting our return values, we can use Rust’s annotations to trigger a branching code path based on the configuration. It’s a bit uglier to look at, but it allows us to make sure we are testing correctly:
Now we can properly check in our test that it’s failing where it should:
Nice! Now we can test for a panic while making sure that we are keeping that code out of sight for users.