We were able to significantly reduce the running time of all the GWT test cases in our build by simply placing them in a
TestSuite
. Unfortunately, TestSuite
is not one of the classes that is extended by the GWT's implementation of JUnit, but we didn't notice any real problems while using it.Of course, since TANSTAAFL is one of the laws which governs our universe there is a trade-off to be made. When running a
TestSuite
you have to allocate enough memory for all the tests in all the TestCases
in that TestSuite
. GWT is quite a memory hog and can easily require over a Gigabyte of memory allocated to it. However this shouldn't pose a big problem and the reduction in build feedback time is more than worth it.Using
TestSuite
creates a new problem though. People routinely forget to add the TestCases
they create to the TestSuite
which is run by the build. Consequently you end up with bits of functionality being broken but not being detected simply because the relevant tests are not being run during a build.Around the third time this happened, I got frustrated and decided to automate the process. We used Ruby to write a little script which would pick up all the
TestCases
in a particular directory and add it to a template. It's pretty rough but it works, so whatever...Just remember that it doesn't auto-generate imports, so you'll have to add those to the template manually. It isn't hard to modify the script to do this too, but it happened sufficiently rarely in our case that I didn't bother.
On Windows, we needed to check in just two files to use Ruby -
msvcrt-ruby18.dll
and ruby.exe
Here's the code listing:suite.template
import junit.framework.TestSuite;
import junit.framework.Test;
import com.whatever.imports.you.need.*;
public class GWTTestSuite extends TestSuite {
public static Test suite() {
// Five hashes are what the ruby code replaces
Class[] tests = {
#####
};
TestSuite suite = new TestSuite();
for (int i = 0; i < tests.length; i++) {
suite.addTestSuite(tests[i]);
}
return suite;
}
}
gen.rb
java_files = Array.new
gwttestfiles = Array.new
jfiles = File.join("**", "*.java")
#Change working directory to the GWT test directory
Dir.chdir("\\your\\project\\path\\testgwt")
Dir.glob(jfiles) {|x|
java_files<<x if "#{x}".include?("Test")
}
java_files.each do |element|
file = File.new(element)
matched_lines = file.select{|line| line.match('\s*public\s+void\s+test.*')}
if matched_lines.size > 0
name = File.basename(file.path)
gwttestfiles<<name.gsub("\.java","\.class")
puts "Located: " + name
end
end
classes_string = gwttestfiles.inject { |result, klass| result + ",\n" + klass }
file = File.new("\\your\\project\\tools\\ruby\\suite.template")
File.open("GWTTestSuite.java","w") do |output|
file.each do |line|
line.include?("#####") ? output.write(classes_string) : output.write(line)
end
end
The Ant target to run the ruby script:
<target xmlns="" name="generate.gwt.test.suite">
<exec dir="\your\project\tools\ruby\" executable="\your\project\tools\ruby\ruby.exe" failonerror="true">
<arg value="gen.rb"/>
</exec>
</target>
7 comments:
I use the DirectorySuiteBuilder to build test suites dynamically. This comes as a part of the Junit Addons library
Using TestSuite, how do u run the test before?
I'm trying with the same script that gwt made (with the TestSuite class instead of the individual GWTTestCase class), but it fails :(
@seiju,
Make the testSuite class out of the gwt module, for example if u have a package com.urcompany.App, create test.com.urcompany.App.TestSuite, in that class follow the instructions of this wonderful post, and then execute it with the script that generates the junitCreator. it just works :D
@seiju,
Yup, exactly as blaxter said. Remember, TestSuite isn't a part of GWT so you need to locate in such a way that the GWT compiler doesn't try to compile it. Then you should be able to run it easily from within IntelliJ or Eclipse.
Hi Sidu,
Interesting tip. I'm not noticing any speed improvement over just running all of the GWTTestCaes independently -- is there perhaps something I'm missing?
(FYI, I'm running these through Eclipse)
Dave, I'm somewhat out of touch - I haven't looked at this since GWT 1.2 was in beta. I know that one of the significant optimisations in 1.3 and 1.4 was in the area of test performance. I'm guessing you'd need several hundred tests to tell the difference with 1.4 - but unfortunately I don't have the time to do a unit test performance comparison between 1.2 and 1.4 so I can quote hard numbers. If you're able to do this, I'd be grateful if you'd let me know the outcome so I can decide if this post is no longer applicable to newer versions of the GWT.
Now there is a GWTTestSuite class in GWT.
Post a Comment