I've been busy reading my Pragmatic Unit Testing book. I've got the following unit tests that run successfully, but I'd like to know how to automate the running of the tests cases in ant. Here is my first unit test module:
I can run this successfully from the command line by saying:
I have a very simple build.xml file, and I think that this is what I need to do to run the test code automatically at the end of each build:
Does this look like the correct way to set it up so that my tests are run automatically at the end of each build?
I can't resist jumping in with a few comments; I hope you don't mind.
Don't hard-code data like
"i:\\Apps\\Apache\\Tomcat\\webapps\\robinapp\\WEB-INF\\utt\\5137233711" into your tests. How will anyone else ever be able to run these tests? A URL like this should be composed from pieces at runtime; the machine-dependent piece ought to come from a properties file.
Don't include redundant data in a test. This is important in normal coding, but it's even more so in testing. The string "513723" appears in several places here; put it in a String constant and reuse it. There are other, longer strings that include this as a substring; build those up with "+" using this same constant. You may have to change the test. More importantly, someone may want to read this test to help them learn about the Session class.
I really appreciate your input. I've been struggling with unit testing issues for years. Here is the method I am testing:
Let me tell you a bit about the Session object. It keeps track of a list of audio filenames that are in a directory. It has the following private member variables: uttDestination -- this is the full pathname to where the audio files are stored trueSpeakerStr -- string representing the 10 digit phone number of a person pretending to be the trueSpeaker sessionID -- string like "S01" that the session # When you put the uttDestination, the trueSpeakerStr and the sessionID together with a bit of other magic, you can re-create the full pathname of the audio file. Are you suggesting that instead of hard-coding these values in the test cases I should put them in a separate file and read them in?
Are you suggesting that instead of hard-coding these values in the test cases I should put them in a separate file and read them in?
Well, perhaps not. If that's all that happens with the paths, then the actual value of the path doesn't matter. I do tend to use paths like "/value/doesnt/matter.txt" in tests to indicate this to a person reading the test. See, as I read your code, it seemed as though it meant that a complicated directory hierarchy needed to be set up to run the test. In any case, if Session doesn't actually create a File out of the path, and you know that when the class is changed in the future, it still won't, then there's no reason to make the path an external parameter. But my other point -- that the redundant strings, and the strings contained inside other strings, should be made into constants so that it's easy to see what's supposed to be equal to what -- stands. [ February 20, 2004: Message edited by: Ernest Friedman-Hill ]
I think that this is much nicer. Instead of hard-coding a filename that I know exists, I create a file in the setUp method and then delete it in the tearDown method. What other improvements can I make:
Robin, I would create an instance variable for file f. That way you aren't creating the file object in both the setup and tear down methods. More importantly, it is clearer that you are referring to the same file object. You don't really need to catch the IOException in setup. If the setup method throws an exception, the tests will automatically fail (with a message about an IO exception.) Right now, it will fail without telling you why. In testRetrieveUtterance(), you have assertEquals(actual, expected); It should be assertEquals(expected, actual); The error message junit gives will be clearer that way.