My first SimpleTest

Events happening in the community are now at Drupal community events on www.drupal.org.

Having not written a single test yet I figured it'd be a good idea to document the process, and I happen to have an issue in the queue which is perfect for doing so.

Background:
* Access rules were removed from core
* Statistics module had a direct call to the {access} table which I knew nothing bout, so is now broken
* Dries said "We should probably write a test for it too so we don't reintroduce this problem."

Everything I know about unit testing has been from the past year or so as it's been discussed in relation to Drupal. I've read odd bits of the docs, read through some core tests, but not written any tests yet or played around with simpletest.module much. I imagine this is the same for a lot of people.

These are any issues I managed to come up with before trying to write the patch, note I'm being deliberately dumb about some of this to try to find what the roadblocks are, and if I appear to be talking to myself, then I probably am.

IP blocking doesn't have any tests existing tests for it within system.module (because that patch (by me) got accepted without tests) - so nothing to build on there.
Statistics.module doesn't have any existing tests either (issue here: http://drupal.org/node/253121)

(These are both temporary conditions hopefully, but important at this stage of trying to get people involved. If I didn't already know what was going on with this, Dries' statement would have stumped me completely.)

There's a whole bunch of steps - like enabling statistics module, then enabling access logging and having some data in two different tables before you can test the page in question. I know you can set variables and create nodes and users cleanly but do I insert arbitrary data into the accesslog and blocked_ips table or just test if the page displays ok or what?

- I couldn't find the answer to this in the docs, so asked chx, who confirmed I need to use db_query() to insert/delete the data manually for these cases (in the absence of mocking). We probably need to come up with some documentation for that - I can think of {accesslog}, {watchdog}, maybe {history} where such information might need to be faked.

The patch to fix the issue changes 10 lines of code, the SimpleTest is going to be a lot more than this.

- if there'd been a SimpleTest for this already I wouldn't be writing a 10 line patch to fix something I broke writing a much bigger one that's already committed. This is why testing is good.

Do I put this test in system.test or statistics.test?

- I think this particular issue needs an integration test and we don't have any of those yet. So I'll put it in statistics, or split it between the two for now.

---
This is a very rough log of the process of actually writing a test for the first time:

Stuff I looked at in order of frequency:
1. core tests
2. simpletest handbook page.

Since there was no statistics.test to work with I copied user.test into a new file to get the basic structure to fill in.

Not entirely clear whether I should be using setUp('module') or drupalModuleEnable. The handbook says drupalModuleEnable but the tests say setUp() - so I went for setUp().

drupalCreateUser() is entirely self explanatory, which is nice. Handbook says I should've used drupalCreateUserRolePerm though - which appears to be deprecated as well.

I have to insert some dummy accesslog information - only way to do this is via db_query(), meh.

Handbook says use $this->drupalVariableSet($name, $value) but I picked up from somewhere that this is deprecated, and the tests say the same thing, so I just use variable_set.

Using the internal browser is the easy bit - do stuff, see what happens, do more stuff, see what happens.

Since there's not existing tests for this bit of core it's hard to know how much or how little to test. I figure I'll test as much as possible and cut it down later if told, for practice if nothing else.

Can't see an obvious way to test whether the #default_value in my form is getting set or not, will skip that for now.

So now I have my first test ready to try out. I wasn't on my development machine when writing this so as yet I've just got something completely untested which vaguely resembles some other tests.

1st run: 19 passes, 14 fails and 0 exceptions.

Not so bad for running blind. Turned out I'd missed a capital letter in an assertText. s/block/Block.

Nice to see what the error is, which line etc., make things much easier to fix.

Fix that, next run:

23 passes, 11 fails and 2 exceptions.

Ok so now it looks like I've got the drupalPost messed up somehow. Ah - no I haven't, I'm rolling this test along with a patch, and I'd done something stupid with my menu definition - so my test is actually failing due to my sloppy code!!

Fix that and check manually that my menu item is appearing this time, one more pass on running the test.

24 passes, 8 fails and 2 exceptions.

However I've got two exceptions - looks like I'm using assertRaw/assertText incorrectly or some other issue - fiddling about with it didn't do me any good, so time to ask for help on IRC.

More fiddling, I was using 12.34.56.789 as my IP address for testing. This, of course, isn't a valid IP address, so it's not getting saved, because the validation works. That was stupid. Note to self - follow the exact steps you're trying to test manually too.

31 passes, 3 fails and 4 exceptions.

Got it to all passes, no fails but still 4 exceptions. Turns out clickLink() isn't handling query strings quite right: http://drupal.org/node/255613

Final test is on this issue: http://drupal.org/node/248436

Testing and Quality Assurance

Group organizers

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds:

Hot content this week