I have a class that consume an XML file and produce text output based on the input. Both the input and output are rather complex and the output can also include things not in the input: e.g. include timestamps and the results from live data that are not controlled by the input - with other words: the class is not a pure input-output transformation.
I would like to test the resulting text output using JUnit. As the produced text can vary in many different ways based on the input, I would like to be able to match specific parts of the output against some sort of template in each test. Each template should allow for some simple text substitutions and also for ranges in the text that should not be matched.
The question is whether any such frameworks already exists?
One very low-level possibility would be to use some fancy regular expressions to match the text, but I think these will be a bit too limited for our use as you don't have enough context in regular expressions...
EDIT: Two comments:
Perhaps this is indicative that you need to be testing at a lower level ? i.e. testing the contributing components rather than the entire output en masse. I would hope that you can arrange your code/tests such that you can provide an immutable set of inputs (perhaps using mocking where necessary) and consequently the outputs won't change.
A few high-level tests would be useful (to confirm results integration) and you could perhaps do that by a simple string comparison (just to confirm stuff is being integrated properly) but I think the effort should perhaps be put in at a more granular level.
Otherwise I suspect you may want a diff-like tool, and this library looks like it may be useful.
I would use Groovy for writing the unit tests, because this is one of Groovy's strength, see
But Groovy is also superb for handling XML, see
A little example for summing up some XML attributes:
// multiline string, very complex XML content :-)
def input = '''\
<list>
<summand value='13' time='10:40' text='Compare me!'/>
<summand value='1' />
<summand value='4' />
<summand value='2' />
<summand value='7' />
</list>'''
// reading XML via XmlSlurper
def list = new XmlSlurper().parseText(input)
// Prints 13
println list.summand[0].@value
// collect all summand values, prints 27
println list.summand.collect { [email protected]() }.sum()
You can find a good tutorial about testing in the MEAP Making Java Groovy or look at this presentation.
Groovy has also template support. But with the XML support it is very easy to compare only certain attributes and not the whole tag content to skip some attributes like the timestamp you mentioned. Therefore you don't need to compare templates. For an example add this source to the skript above:
// compare the first summand tag, skipping the time attribute
assert [list.summand[0][email protected](), list.summand[0].@text] == [13, 'Compare me!']
To learn Groovy, I recommend the Groovy Koans. See also Adding Groovy Tests to a Maven Java Project.
Update:
I would not compare the XML against each other, instead I would unit test single values as desribed in my answer. But if you go the complete way I would use the following approach:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With