Using Tests for Requirements Management
Everybody who gets excited about requirements management and documentation – raise your hand. Okay. Thank you. You’re free to go. For those left – you can mate automated tests with a bit of convention and scripting magic to simplify your requirements management life. Here’s how.
I recently did some embedded software work for a client in the automotive market. Good people. I had the opportunity to do a bit of coaching, consulting, and development with them – all aimed at incorporating Continuous Integration and Test-Driven Development into their process.
Among the handful of goals we had to accomplish, we also had an ill-defined charge to demonstrate how automated tests could support requirements management, documentation, and verification. The basic approach we assembled was quite simple but effective.
As already mentioned, we relied on code convention and a script to achieve our results. First, we used behavioral naming for all of our unit tests. Test function names include the name of the source function under test and a “should” statement explaining the behavior of the source code the test was exercising. We also introduced a simple comment convention for associating requirements with a test.
In the sample test that follows, note the naming convention of the test function and the inline comment following the function name.
1 2 3 4 5 6 7 8 9 10 |
// TestSourceModule.c void test_SourceModule_Function_should_Produce_BUS_RESULT_Upon_BUS_INPUT(void) //reqs: T23, T101 { /* perform some test setup goodness ... */ TEST_ASSERT( BUS_RESULT, SourceModule_Function(BUS_INPUT) ); } |
Second, we created a small (perhaps 20 lines) Ruby script that executes at the conclusion of a build. The script parses all test files and functions with knowledge of our conventions. It produces a sorted CSV (comma separated values) file suitable to be parsed by essentially anything else or opened in a spreadsheet application. Each line of the CSV file includes the requirement identifier; the requirement’s associated source function; test file and line number; and behavior as a (mostly) intelligible plain language sentence. The contents of a sample CSV file follows.
1 2 |
T23, SourceModule_Function(), TestSourceModule.c, 3, Should Produce BUS_RESULT Upon BUS_INPUT T100, SourceModule_Function(), TestSourceModule.c, 3, Should Produce BUS_RESULT Upon BUS_INPUT |
The build dumps the CSV report into an artifacts directory the Continuous Integration tool makes available to users through its web-based interface. Anybody with access to the CI tool can download the CSV report and manipulate it in whatever way they need – usually with something like Excel. At some point in the future we plan to work on linking the contents of the file to the enterprise-grade requirements management tool our client uses.
With automated tests and a bit of convention, all the information necessary to produce code-to-requirement tracking is readily available. Because all the data is up to date via automation and the conventions are quite simple, developers are motivated to maintain requirements-related information in the code. Maintenance, verification, requirements coverage, etc. all become quite manageable tasks.


Leave a Reply