Search code examples
concordion

Concordion - how can i set a value into a table?


At some stage in a concordion test I have, I set a value to some random number.

This value is passed along, and later on , I have some output. The output is "checked" using the concordion "table" setup, where i compare an output value to what I expect it to be.

The problem I have is that I would like to check against the random number mentioned above. When I get the random number, I can set it to something Concordion can store -

<span c:set="#prefixValue">Bob</span>

Well, you get the idea - I replace "Bob" with a getter for my value.

But when I try to use it:

<table c:execute="#actual = getValue(#report, #xpath)">
    <tr>
        <th>Field name</th>
        <th c:assertEquals="#actual">Value</th>
        <th c:set="#xpath">Xpath</th>
    </tr>
    <tr>
        <td>UnrelatedValue</td>
        <td>SomeDeterminateValue</td>
        <td>theXpathForThisToCompareTo</td>
    </tr>
    <tr>
        <td>prefix</td>
        <td><span c:echo="#prefixValue" /></td>
        <td>differentXpathForThisToCompareTo</td>
    </tr>

The whole shebang grinds to a halt, complaining that

" Commands must be placed on elements when using 'execute' or 'verifyRows' commands on a <table>. "

How can I use a pre-determined value in a table in Concordion?


Solution

  • Oh Lord! I didn't realise Concordion was going to get all rigid on me.

    To fix, I had to alter the Concordion method I was using to be less stupidly rigid.

    Following the general ideas here: http://automatingsoftwaretesting.wordpress.com/2011/05/27/write-your-own-concordion-command-an-example-for-asserting/

    I wrote this:

    @Override
    public void verify(CommandCall commandCall, Evaluator evaluator, ResultRecorder resultRecorder) {
        Object expected = evaluator.evaluate(commandCall.getChildren().get(0).getExpression());
        Object actual = evaluator.evaluate(commandCall.getExpression());
    
        Element element = setupTheGoshDarnElement(commandCall, expected);
    
        if (actual.equals(expected)) {
            resultRecorder.record(Result.SUCCESS);
            announceSuccess(element);
        } else {
            resultRecorder.record(Result.FAILURE);
            announceFailure(element, expected.toString(), actual);
        }
    }
    
    private Element setupTheGoshDarnElement(CommandCall commandCall, Object expected) {
        Element e = commandCall.getElement();
        e.appendText(expected.toString());
        return e;
    }
    
    private void announceFailure(Element element, String expected, Object actual) {
        listeners.announce().failureReported(new AssertFailureEvent(element, expected, actual));
    }
    
    private void announceSuccess(Element element) {
        listeners.announce().successReported(new AssertSuccessEvent(element));
    }
    

    And so made a new "evaluator" ~ the rest of the evaluator is identical to the AssertEqualsCommand, if you're wondering.

    This neatly checks the element and evaluates. Why concordion didn't do this ~ it isn't rocket science at all ~ is beyond me!

    NOTE that I still need to use the "expanded table" in my question to get this to work, the short-form table has it's own issues with evaluating inner expressions.