At CITCON I wanted to demo Jester in the session on mutation testing. I tried to run Jester on Nat Pryce and Steve Freeman's JMock2 code but couldn't get it to work in the time I had available, so I gave up and wrote some simple code specifically for the demo.
As a result of this bad experience, I thought I'd make Jester much simpler to use. I've called the result "simple-jester" and the first release of it is available from the Jester sourceforge site.
This article describes an example of how to run simple-jester, by showing how to run it on JMock2. I have chosen JMock2 because I know that it'll be well written and well tested (because I know Nat Pryce and Steve Freeman), it's not too small and not too big, the build is fast, it wasn't written with Jester in mind, and I didn't write it.
This article describes what I did - on windows, on a machine which I've already got Java, ant, Python and subversion installed on. This is what really happened ... warts and all, so I hope the hints and tips that arise from the problems described here will help you get simple-jester working for yourself.
Sorry if you find the writing style odd (even by my standards) - it's a mix of the instructions that I thought I should write, what is happening as I'm trying to follow them and then instructions to fix the mistakes I made with the earlier instructions. I've written it like this because in practice you will end up going through something similar to get Jester to work - the mistakes weren't deliberate and are instructional.
Check that everything is OK by executing, in a command prompt:
Then:
run.tests:
[mkdir] Created dir: C:\temp\jmock2\build\reports\tests
[junit] Testsuite: org.jmock.example.announcer.AnnouncerTests
[junit] Tests run: 4, Failures: 0, Errors: 0, Time elapsed: 0.031 sec
[junit] Testsuite: org.jmock.example.qcon.DJTests
[junit] Tests run: 1, Failures: 1, Errors: 0, Time elapsed: 0 sec
[junit] Testcase: warning(junit.framework.TestSuite$1): FAILED
[junit] No tests found in org.jmock.example.qcon.DJTests
[junit] junit.framework.AssertionFailedError: No tests found in org.jmock.ex
ample.qcon.DJTests
BUILD FAILED
C:\temp\jmock2\build.xml:208: Tests failed
Sorry Nat and Steve. Maybe I've got something wrong with the environment. I don't have time to investigate. Almost certainly something I've got wrong and I'm not worried anyway, because the fix is simple and I don't expect the side-effects of the fix to be too bad.
so:
Jesting failed!
jester.SourceChangeException: couldn't run tests
at jester.RealTestRunner.testsRunWithoutFailures(RealTestRunner.java:26)
at jester.TestTester.run(TestTester.java:144)
at jester.TestTester.doMain(TestTester.java:127)
at jester.TestTester.main(TestTester.java:81)
Caused by: java.io.IOException: CreateProcess: ant error=2
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.<init>(ProcessImpl.java:81)
at java.lang.ProcessImpl.start(ProcessImpl.java:30)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:451)
at java.lang.Runtime.exec(Runtime.java:591)
at java.lang.Runtime.exec(Runtime.java:429)
at java.lang.Runtime.exec(Runtime.java:326)
at jester.Util.runCommand(Util.java:10)
at jester.RealTestRunner.testsRunWithoutFailures(RealTestRunner.java:21)
... 3 more
Doh! I made the mistake that I now remember documenting in the README.html for Jester. You have to tell Jester to run ant.bat on windows, rather than just ant.
To prove this, execute "java jester.RealTestRunner ant" which runs the code that Jester will run for executing your build command. This produces the same output as above. If you now execute "java jester.RealTestRunner ant.bat" instead, then the result is:
C:\temp\jmock2>java jester.RealTestRunner ant.bat true
which means that this build passes for Jester.
So - trying again:
I've gone back to the machine - the progress bar showing not much progress. Not much seems to be happening, but after waiting about 30 seconds I see some more stuff in the "progress" dialog and return to the important task of drinking the tea that I've just made.
I go back to the machine much later - it really does look stuck now. One of the cores is maxed out running a java process, and the "progress" dialog has shown: "src\org\jmock\lib\concurrent\SynchronousScheduledExecutor.java - changed source on line 54 (char index=2029) from if ( to if (false &&" for several minutes.
So:
BUILD FAILED C:\temp\jmock2\build.xml:15: Unable to delete file C:\temp\jmock2\build\jmock-2- SNAPSHOT\jmock-2-SNAPSHOT.jar
I open the task manager and find a java process that is hanging around that I wouldn't expect so:
One of the least endearing features of Jester is that if the whole run isn't successful then you can't easily get anything out of Jester - i.e. mostly either the complete run of Jester works or doesn't work, if it crashes or is killed before it's finished then you don't get much useful out of it. I might fix this in the future. In the meantime, it's safest to run Jester on subsets of your code base (e.g. at most a package) at a time. But I won't follow my own advice here because I'm determined to get Jester to work for all the source files of JMock2 in one run.
To try to get Jester to work for JMock2, I'll get Jester to ignore the part of the source file where it made the mutation that caused the hang problem.
43 mutations survived out of 284 changes. Score = 85 took 42 minutes
I'd expect that having deleted one of the tests (which might not have been the best way to get the build to pass) will have slightly worsened the results. Nevertheless, these results indeed show that the tests for JMock2 are impressively good. Jester often gives lower "scores" than code coverage tools. I'd be interested to know what the results are for a code coverage tool on the same code but my time has run out for this and my tea has gone cold.
However - I still have time for one thing, which is possibly the most important output from Jester:
I'm pleased with both the code and usage simplifications to Jester in "simple-jester". The downside is that it's now even slower than before; but that doesn't worry me unduly because at least now I and others will be able to get it to work for many more projects. There are still some areas of improvement (e.g. if your build calls ant multiple times then Jester can think the build was successful even if it wasn't) - but generally it's much improved thanks to some judicious deletion of code.
If someone wants to pay me to do it, I'd be interested in making Jester faster by having it clustered on multiple machines. There are alternative approaches - e.g. jumble which uses byte code mutation (it's Java specific) which is much faster than Jester's approach.
I'm not planning on spending lots more time on Jester (unless someone pays me to do it) because I'm now happy that Jester is both simplified and improved (as simple-jester) such that it's much more usable, as I hope this article shows with it's "warts and all" commentary, because the warts really weren't very large.