Wednesday, December 4, 2013

Writing Selenium tests with sausage (and phpunit).

This is thinking aloud as I write some tests...;

API things I'd like to fix:

in sausage:

spinAssert() doesn't show you what went wrong if you have assertions inside the callback function.  Although the assertions (appear to) get called, if one fails (not just because the page isn't ready, but because of an error) you don't know which/why.  You just get `failed asserting that false is true` (which is the return value of the callback).

in phpunit

$parentElement = $this->byCss('div');
$childElement = $this->byCssSelector('span');
// Really?  byCssSelector ?  Is there a reason not to be byCss()?

// and then:
$moreChildren = $this->elements($this->using('css selector')->value('.ugh'));

// so now there's using('css selector')->value('') ?
// how about

// or better, as convenience methods:
$oneElement = $this->one('div');
$anotherEl = $this->one('#eleid div.whatever span');
$lotsOfElements = $this->all('#eleid div');
// and always use css selector

Overall structure of tests

This is a question.  The advice is that there should be no dependencies between tests.  That definitely makes sense with unit testing where you're mocking things and don't (want to) touch the database.

But functional/user acceptance tests (what I'm writing) do touch the database, that's the point of them.  I want to test that things save and show up again.   So say I have one test that counts the number of records, and another that creates a new record.  Then there's a dependency between them: the order of the tests matters, unless I reset the database before every test.

But I don't want to do that.  It takes almost a minute.  I can't do that in-between every test.

So I'm thinking that dependencies between tests isn't a bad thing, although it's probably better that dependencies only exist within one class (ie no dependencies between test classes).

Second question.  It seems that a page load is inevitable before each test.  This isn't how our application is used - generally it's a one page load and then ajax everything.  Initial page load isn't optimised particularly after login, because it only happens once* a day.  So keeping things clean, with lots of small tests, each testing one thing, is 1. slow (because of page load) and 2. unreal - it's not how the application is actually used.  I want my tests to be fast and realistic.  So now each test is getting really big - 20+ assertions and several spinAsserts() (and nested spinAsserts!).

Perhaps I should refactor each test along the lines of

public function testEditARecord() {

These might have a small amount of value in terms of re-usability; but the point is making things a bit more readable.

No comments:

Post a Comment