jFunky : a small functional testing framework
Requirements
I recently needed to write tests for an application. This application takes loads of time to process a lot of data, and tests are required to be on real-life data. A first attempt has been made to use jUnit, but the result was that for each functionality to be tested, the application would be started again from zero, resulting in tests lasting for hours, or even days.
So I decided to switch to another library but a quick search did not give me much results. I decided to create my own set of tools for the task, thinking it would be good exercise and a fun experience.
Result
So jFunky’s github repository as a result.
Similarities with jUnit
A very first try coded in a few hours, this library contains utilities looking a lot like jUnit’s features :
- a
BaseTestCase, to be extended and containing tests, - a
BaseTestSuite, to be extended or not, allowing to run a set ofBaseTestCaseinstances, - a default renderer, mimicking the default jUnit XML reports done via ant (so that you can use the
junitreporttarget on them), - annotations for running methods of a
BaseTestCasebefore all the tests, or after.
Differences with jUnit
But although there are a lot of similarities, there are also some notable differences.
- the tests put the focus on business requirements : what is tested is whether a business requirement is met or not,
- all the tests are effectuated. One failure within a method does not stop the method’s execution, it records the failure and simply goes on,
- only one instance of each
BaseTestCaseis created, and all the methods are called on this instance. This allows very heavy fixtures to be setup once, and even shared betweenBaseTestCaseinstances (e.g. by creating a caching system).
Test example
Here is a small example of a method which can be found in a BaseTestCase :
@Test public void testGutter(){
requirement("BR0001")
.implyingThat("8 gutter means no point")
.isMetWithCheck(new Checker(){
public boolean check() {
Bowling b = new Bowling();
for (int i=0;i<8;i++){
b.hit(0);
}
return b.result() == 0;
}
});
}
Tests work by referring to a requirement (here named “BR0001”), optionnally (but preferably) providing a description through the implyingThat method for this test, and then providing the implementation of a test. In this case, a whole inner classes is used, but simpler tests can be done via the other more classical methods isMetWithTrue(boolean), isMetWithNotNull(Object), etc.
The architecture is very loosely borrowed from RSpec, adapted to Java’s verbosity.
The code is still not very well documented but very short. Anybody willing to share thoughts about it is very welcome to do so.