dev@javaserverfaces.java.net

Re: Unit tests failing

From: Adam Winer <adam.winer_at_oracle.com>
Date: Mon, 29 Jan 2007 09:33:27 -0800

FWIW, when writing rendering unit tests for Trinidad,
I decided I didn't want to get screwed with by changes
to the ordering of attributes - we should be free
to change the order of attributes in code without
breaking unit tests, since the order has zero
semantic meaning.

So, I use an alternative ResponseWriter:

http://svn.apache.org/repos/asf/incubator/adffaces/trunk/trinidad/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/TestResponseWriter.java

... that sorts the attributes. This response writer
also tests that there aren't attributes written out
twice, and optionally verifies that IDs are valid
for HTML and that block-level elements aren't added
inside of inline elements. It also puts each attribute
onto its own line, which makes diffs *much* clearer.

I also swap in a custom ExternalContext that takes
some common no-op operations like encodeResourceUrl()
and encodeActionUrl() and makes them predictable
non-no-ops, so the tests verify that calls to
these APIs are happening consistently.

Just a thought.

-- Adam




Jason Lee said the following on 1/29/07 7:30 AM PT:
> I have an odd problem that Ryan assures me is unique to my computer (two
> of them actually), but neither he nor I have been successful in figuring
> why. When I run the full the suite of tests, everything runs fine until
> I hit the jsf-ri systests, particularly
> com.sun.faces.jsptest.PrependIdTestCase.testMissingView(PrependIdTestCase.java:126).
> The line referenced there is this one:
>
> assertTrue(-1 != pageText.indexOf("input value=\"prependIdFalse\"
> type=\"text\" name=\"j_id_id54\""));
>
> That tests the output of this block in the jsp:
>
> <h:form prependId="false">
> <h:inputText value="prependIdFalse" />
> </h:form>
>
> <h:form prependId="true">
> <h:inputText value="prependIdTrue" />
> </h:form>
>
> <h:form>
> <h:inputText value="prependIdUnspecified" />
> </h:form>
> When I request that page from the server via my browser, I can see that
> the first inputText is rendered as:
>
> <input type="text" name="j_id_id54" value="prependIdFalse" />
>
> Note that the only thing wrong with that rendered output is the order of
> the attributes. The code is expecting value/type/name, but the server
> is returning type/name/value. The question that haunts me, and causes
> my tests to fail is this: Why is that different? A related question is
> why is it rendering like that for me, but not for Ryan (or Ed, I hear,
> and I guess untold others).
>
> From the hip, I see a couple of fixes. The most obvious would be to
> determine why the attribute order is different and fix it. Sadly, that
> has not been easy to date. The second option is to change the test
> itself. Currently, the test submits the request to the server via
> HtmlUnit:
>
> HtmlPage page = getPage("/faces/jsp/prependId.jsp");
>
> It then gets the String representation of the reponse and begins to
> perform a number of String.indexOf() operations. Could the test be
> altered to use the HtmlUnit API more extensively, making use of calls
> such as HtmlPage.getHtmlElemenetById(), getFormByName(), getChildren(),
> etc? That would mean, I think, we'd have to iterate through the DOM
> tree for certain tests (i.e., get the forms, which are rendered in a
> known order, then iterate through its children to get those elements
> that have no IDs, such as in this case).
>
> Am I missing something with regard to the current form of the test? Is
> there an easier solution? I honestly don't care how the test works, as
> long as it's effective and actually runs. :) I would certainly
> appreciate any help, tips, pointers, fixes, etc. :) Thanks!
>
> -----
> Jason Lee, SCJP
> JSF RI Dev Team
> Programmer/Analyst
> http://www.iec-okc.com <http://www.iec-okc.com/>
>