We have no ideas about the following: … does newly created code really work? … does newly created code break old code (“Regression Error”) … how does adequate test data look like? … do we have all adequate test data in our database for manually testing? … do/can we really test all cases manually or do we miss (the most important) ones?
Unit Testing “In computer programming, unit testing is a method by which individual units of source code, sets of one or more computer program modules together with associated control data, usage procedures, and operating procedures are tested to determine if they are fit for use. Intuitively, one can view a unit as the smallest testable part of an application.” http://en.wikipedia.org/wiki/Unit_testing
How to test? You write stupid code. Very stupid. Very very stupid. And it’ s very repetitive. so, you test your app code with simple assertions: $result = $this->Team->isAbleTo(‘test’); $expected = array(‘read’, ‘create’, ‘edit’, ‘delete’); $this->assertsEqual($expected, $result);
Assertions: (http://book.cakephp.org/2.0/en/development/testing.html) ● assertEquals: === ● assertContains: does $result contain a specific string? ● assertTrue ● assertFalse ● and more!
How do tests look like in real life? Helper Test: https://gist.github.com/johannesnagl/7785824 Component Test: https://gist.github.com/johannesnagl/7785842 Model Test: …
No, … Fixtures! We don’t want to test our app with real life data. So we need something else. Test datasets are called “fixtures”. And they get “magically” imported when running our test cases. class GroupFixture extends CakeTestFixture { public $import = 'Group'; public $records = array( array('id' => 1, 'name' => 'Group with users'), array('id' => 2, 'name' => 'Group with one user'), array('id' => 3, 'name' => 'Group without any user') ); }
Mocking methods/objects Example: We don’t want any mails to be sent in the testing environment. So we “mock” the Email-Object and replace the method “send” with a “result true;”. public function testSendingEmails() { $model = $this->getMockForModel('EmailVerification', array('send')); $model->expects($this->once()) ->method('send') ->will($this->returnValue(true)); $model->verifyEmail('[email protected]'); }
Lessons learned so far ● Thinking about useful test cases let you think better about methods ● Decouple all the things! ● Always return values in your methods! ○ $this->setUser(1); $this->user = $this->setUser(1); ● Fix the Fixtures! (Instead of trying to do voodoo-magic with your fixtures, write own “namespaced”-fixtures for every test case) ○ Testcase 1: Use User-Fixture 100, 101, 102 ○ Testcase 2: Use User-Fixture 200, 201, 202