Tired of slow test suites? Not enough RAM to satisfy both tests and your browser? Have you ever committed without seeing tests results because “It 18.30!”?
Good, this one is totally for you.
The problem
You all know how symfony1 test suites become a problem as you have lots of tests: when I say lots, I mean 30, 40 tests, which should not be that huge amount of tests.
A possible solution for this problem is not to test forms with functional tests, when you have tons of:
How could this be possible? Well, thanks to the form framework, all forms, widgets and validators are, obviously, objects, so they are easy to test as a unit.
Let’s imagine this scenario: I want to test that a form has one and one widget only, in which the user can type multiple email addresses, separated by comma.
Testing the form
Create the empty form under lib/form directory:
12345
<?phpclassMultipleMailFormextendsBaseForm{}
Let’s write the test, which checks that the form has 1 widget and 1 validator:
If you re-launch the test, a green bar will appear :)
As you might notice, now the test isn’t meaningful: we know how many widgets/validators we have but we didn’t tested in which conditions the form is valid, which kind of data it accepts and so on.
To do so, you have 2 things to do: first, bind the form in the test with an array of values and then check the isValid() method; second, test your custom validator.
<?phpinclude(dirname(__FILE__).'/../../bootstrap/unit.php');$t=newlime_test();$v=newMultipleInlineEmailAddressesValidator();try{$t->is($v->clean('[email protected]'),true);}catch(Exception$e){$t->fail('The validator accepts a single email address');}try{$t->is($v->clean('[email protected], [email protected]'),true);}catch(Exception$e){$t->fail('The validator accepts multiple email addresses');}try{$t->is($v->clean('[email protected],[email protected]'),true);}catch(Exception$e){$t->fail('The validator accepts multiple email addresses, without spaces');}try{$t->is($v->clean(' [email protected] , [email protected] '),true);}catch(Exception$e){$t->fail('The validator accepts multiple email addresses, without caring about spaces');}try{$t->is($v->clean('alessandro.nadalinmymail.com'),true);$t->fail('Exception should be raised');}catch(Exception$e){$t->pass('The validator fails if an address is wrong');}try{$t->is($v->clean('[email protected], [email protected]'),true);$t->fail('Exception should be raised');}catch(Exception$e){$t->pass('The validator fails if a multiple address is wrong');}
which checks the validator under lots of circumstances ( single email, multiple emails, multiple emails some good some wrong, etcetera ): launching it, you should get a red bar.
Now you can implement the validator, overriding the doClean() method: