Testing in PHP has always been hard - PHP Devs generally just don’t “get it”. There have been some recent developments from Symfony camp, but again they are not easily integratable with Kohana - the framework I’m most interested in. And the saddest thing is there are great testing frameworks out there in other languages and the fact that nobody has tried to accomplish something similar in PHP is just heartbreaking. I mean - the best answer to “how to do functional testing in PHP” is “selenium with PHPUnit”, even if what you want to test is just some form input without any javascript - that can get tough on you.
Anyway I rolled up my sleeves and started on the long and perilous journey of writing my own testing framework. Well not exactly - I mostly got the DSL idea from Capybara, and wrote it on top of Kohana Unittest (PHPUnit) but the result is I think quite significant in itself.
FuncTest
The core principles of FuncTest are to be as easy to write the test as possible, and to execute it as fast as possible. Great! But what does that mean in practice? Here’s an example test, straight from the docs:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Looks easy right? Well it will do exactly what you think it would:
- Go to URL /my/url
- Fill in the input tag labeled with ‘John’ (yes labeled - like a label tag with a for=’id’ that matches the id of the input tag)
- Fill in the input tag labeled Username with ‘john-user’
- Select 2004 from the dropdown labeled ‘Select Year’
- Check the checkbox labeled ‘Recieve Newsletter’
- Click the button ‘Create User’
Why use titles / labels instead of ‘name’ attributes or even css selectors, well - if you wanted to you can, and that too is pretty easy, but in my experience the texts change much less frequently than the internal stuff.
And the best part is - this will work with the Kohana classes themselves internally (actually using HMVC patterns for special internal requests) - so there are no network, apache or Kohana framework overhead whatsoever.
And … just one more thing - if you want to run this in selenium (for ajax testing for example): just add public $driver_name = 'selenium'
to your class - and you’re good to go - the same test will run by actually opening up your browser and filling in these fields.