Hello everybody,
As promised, here is a post about how I generate sequence diagrams from unit tests. These are still quite early efforts and can think of lots of improvements, so I’ll be really happy if someone wants to team up with me to explore the problem and develop a more advanced solution! Please let me know if you are interested!
In a nutshell, what I do is use a number of special macros to write the unit test. Then I paste the body of the unit test (I know, I’ll make it read form a file later ;-) into a simple Python script and execute the script. The script uses a bunch of regular expressions to convert the unit test code to the description language of MSCGen. MSCGen is a tool from the company I currently work at ( http://www.itesys-gmbh.de). The tool generates images for sequence diagrams, which are described in that specific language. MSCGen requires .NET 2.0 and the sources for the open source version can be downloaded from http://www.itesys-gmbh.de/home/download/count.php?id=MSCGEN2.
I was thinking about how to extract a sequence diagram from the unit tests and that seemed to me quite difficult at first simply because it is difficult for a machine to “understand” the semantics of a piece of code. The compiler can perfectly understand the syntax but little more than that. Therefore I needed to add some meta-information to each line of code, so that the conversion tool would understand the semantics as well. Furthermore if we are clever in choosing how to represent the meta-information in code, then the compiler could help us verify to correctness of the meta-information as well!
You’ll understand more about the current implementation of these ideas by looking at ConnectionTest.cpp from the latest revision of my public branch http://bzr.calitko.org/developers/peter/calitko-BitTorrent . I’ll just show a single example here. Suppose the test function calls connectToNode(). Normally in pure C++ one would write:
connection.connectToNode (connectAddress);
Instead, we write:
TEST_INVOKE (connection.connectToNode (connectAddress));
Actually, when you see the definition of TEST_INVOKE
#define TEST_INVOKE(fncall) fncall
you’ll understand that that’s all syntactic sugar, which adds some meta-information to provide the semantics of this function call!
Next, the Python script makes a number of string substitutions using a bunch of regular expressions like this one (search pattern, replace pattern):
('INVOKE ?\\(\\w*\\.(.*)\\)', 'msg: ENV_LEFT, __OUT__, "\\1"'),
You can check the other regular expressions in the attached regexps.py file. Finally the scrip invokes mscgen which converts the converted C++ source code to the attached png graphic.
Bo suggested that we discuss this really interesting topic in our next conference call (probably the first week of the new year). I have lots of thoughts about unit testing in general, generating sequence diagrams, generating the test drivers/stubs/mocks and I’ll be really happy to be able to discuss these issues and exchange ideas!
Who would like to participate?
Best regards,
Peter
