The key difference is that SeasideTesting runs on the Seaside server
and gives you access to your Seaside components (not just their HTML
representations). So, in SeasideTesting not only can I test if a
component is displaying what I expect, I can test that a component or
domain object is in the state I expect. The disadvantages of this
technique are that only Seaside applications can be tested and the
tests must run on the server (either through the normall SUnit
TestRunner or through a WebTestRunner included with SeasideTesting).
Actually with a little refactoring one could write remote
SeasideTesting test cases but, of course, they wouldn't have access to
the component objects themselves, just the generated HTML.
While I haven't used it, my impression is that the CS
SmallHttpUnitTest project runs remotely (ie it accesses the server
through a TCP socket) and can test Seaside and non-Seaside
applications. They seem to have paid more attention to design than I
did since they have a very clean API for
accessing/querying/manipulating the HTML components. SeasideTesting
can do all this but it just doesn't seem quite as clean as their work
does on the surface at least.
SmallHttpUnitTest is obviously the way to go if you aren't using
Seaside. If you are using Seaside then the choice comes down to
knowing what you plan to test. I personally don't find tests which
ask lots of questions about the contents of the display to be very
robust. First, presence of an HTML element and its appearance on the
screen are two different things (how do you make sure the page "looks"
right?). Second, small changes in your component layout usually force
changes in your test cases. I don't like this. I prefer to press
buttons, follow links etc and then make sure my domain objects (or
even the Seaside components themselves) have "done the right thing".
Here's an example...
Using SmallHttpUnitTest one could test the Seaside counter like this
(borrowed from the same code provided with the announcement of
SmallHttpUnitTest):
testNavigation
| browser |
browser := HttpBrowser on:
'http://localhost:8008/seaside/go/counter'.
self assert: (browser h1 allSatisfy: [:each | each text = '0']).
self assert: (browser a text includesAllOf: #('++' '--')).
browser click: [:a | a text = '++'].
self assert: (browser h1 text includesExactly: #('1')).
browser click: '++'.
self assert: (browser h1 text includesExactly: #('2')).
browser click: '--'.
self assert: (browser h1 text includesExactly: #('1')).
In SeasideTesting we'd something more like:
testBack
self newApplicationWithRootClass: WACounter.
self establishSession.
self followAnchor: (self lastResponse anchorWithLabel: '++').
self followAnchor: (self lastResponse anchorWithLabel: '++').
self assert: self component count = 2.
self back.
self followAnchor: (self lastResponse anchorWithLabel: '++').
self assert: self component count = 2
Notice that I'm testing that the domain (the "count") has the correct
value, rather than testing the contents of the page. Now, this isn't
to say I can't write tests which look for strings in SeasideTesting
but right now it isn't very clean. I expect this to improve as
SeasideTesting evolves. At the moment I simply don't write that many
test cases that test page contents.
I like the way one "clicks" on buttons and links in SmallHttpUnitTest.
In general, iterating over a type of component in SmallHttpUnitTest
is cleaner than in SeasideTesting but I hope to change that.
Hope this helps!
David