I am writing a small utility class that will run from the command line. It requires certain options to be specified. I have already written the a few tests for the first required option. However, when I go on to add tests for the next required option, I find myself having to go back and modify the tests for the first one. Here's a sample:
This is the first test. It fails, I write the code to make it pass, run the test again, see that it passes, then I refactor, rerun test, still green. So far so good.
The problem is if I go ahead and write a separate test for the next required option, I'll have to modify the existing test to keep it working. As I add tests for other required options, I'll have to do the same thing again, only there will be more and more tests to redo. Should I just test for all required options in one test case or is there a clean way to keep the tests for each required option separated? Or am I going about testing this thing the wrong way?
Originally posted by Lasse Koskela: I tend to do this kind of things the other way around: don't add options until you've got your combination you want to test, remove one from a full set of options instead.
Good to hear because that's exactly the way I was going. Thanks!
Another approach that might be even cleaner is to write a "command line parser" (something like http://jargs.sourceforge.net/), which should be rather straight forward to test.
Then, in the actual application, you just need to use a mock parser to see wether your application is configuring it correctly.
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
OK, just making sure I wasn't missing anything ... Regarding the mock parser, I'm still not clear on where that comes into the picture. As I mentioned above, I'm using the jakarta-commons-cli to parse command line options. However, the parser is an implementation-specific detail. My test cases are not aware that a command line parser is being used.
Here's what happened while I was developing the utility: I started out writing test cases that exercised the main() method. After a couple cycles, I saw that I was writing more and more static methods. Not good. So I switched gears. Forget about the main() method first. I refactored my tests so that I was dealing with an instance of the class instead. First thing I did was to change calls to main() into calls to the constructor. Since main was being passed a String, I made the constructor accept a String. This lead to a processOptions() method that delegated parsing to jakarta-commons-cli. After parsing the options, I set the various switches in the class. All this happened under the covers. When parsing and setup succeeded, the class was ready to be exercised.
So coming back to my question, how would a mock parser help?
BTW, the first few tests that I wrote were all checking for required options:
As an aside, in case you are curious, the utility I wrote generates a report to help us identify Tiles page definitions that have not been configured with a context -sensitive help topic. Our Help system is written with RoboHelp and context-sensitive help topics are mapped in a properties file. All the Java developers need to do is to add an attribute to their Tiles page definitions and our Tiles-RoboHelp component will know which Help topic to display when the link is clicked. The RoboHelp content is being developed iteratively as use cases are developed and so in every iteration we will get a new HelpMap file that contains new help topics. The utility will help us determine which pages have been hooked up to Help, which pages have obsolete or invalid topics, and which topics are still not hooked up.
Here's a summary of the required options:
Probably not relevant to the question, just being the "proud father" [ January 27, 2005: Message edited by: Junilu Lacar ]