PHP Tests tipsHow not to shoot yourself in the foot?            Damian Sromek            damiansromek.pl               201...
Agenda● Whats about those tests?● What are the tests about?● What to do and not to do?
Test types1. Acceptance (end-to-end)   Test as if end user would use the whole   system/feature.2. Integration   Test how ...
Tests will save you time & troubles1. Prove youve done your work2. Help you check much faster if youre work is   done3. Pr...
How to be happy about tests?1. If youre new to testing try with writing tests   after writing the code2. Once youre confid...
You will regret youve got a lot oftests if you:1. make them complex and hard to read2. duplicate the test code3. do not us...
Behavioral testsDraft - BehatFeature: Log in and use the application  In order to use the application  As a user  I need t...
Whats good test like?1. Finds as much bugs as possible2. Tells you what the software can do and how   to use it3. Is easy ...
How to start testing?1. Write acceptance test for functionality youre   implementing - it should cover main story   flow2....
How to start even better?1.   "Wait" for a bug2.   Write a test confirming/reproducing that bug3.   Fix the code using the...
TDD flowRepeat this process1. Write test2. Make test failure message descriptive and   easy to understand3. Make the test ...
Do not - test something irrelevant<?php// SHOULD TEST PLUGIN BUT IS TESTING DATABASE MODEL AND NOTHING MOREclass Plugin_Sm...
Do not - test too much at once<?php// TRY NOT TO MAKE MORE THAN 2-3 ASSERTIONS IN ONE TESTclass ResponseSetTest extends PH...
Do - use meaningful test nameTest name should be descriptive even if it hasvery long name.Try to avoid test names like "te...
Do - use data providers<?phpnamespace XsTestUnit;class StringTest extends TestCase{    /**     * @param string $heystack  ...
Do - test one unit in unit testUnit test should NOT:1. Test more than one unit/class2. Touch database, filesystem,   API/W...
Do - make tests easy to read andunderstandclass Acceptance_Product_ProductListTest extends Test_TestCase{    public functi...
Do - make tests easy to read andunderstand (2)Draftclass SortingTest extends XsCanalDigitalTestStbAdbTestCase{    /**     ...
Summary1. Use TDD2. Unit tests should test what youve written /   proper unit and nothing more3. Do not test too much in o...
Thank you@see Test Driven Development@see PHPUnit@see Behavioral Driven Development@see Behat@see Growing Object-Oriented ...
Upcoming SlideShare
Loading in …5
×

Php tests tips

4,329 views
4,173 views

Published on

Newer presentation about tests: http://www.slideshare.net/damiansromek/automated-tests-60944715

Published in: Technology, Education
1 Comment
2 Likes
Statistics
Notes
  • thanks
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
4,329
On SlideShare
0
From Embeds
0
Number of Embeds
722
Actions
Shares
0
Downloads
9
Comments
1
Likes
2
Embeds 0
No embeds

No notes for slide

Php tests tips

  1. 1. PHP Tests tipsHow not to shoot yourself in the foot? Damian Sromek damiansromek.pl 2012-06
  2. 2. Agenda● Whats about those tests?● What are the tests about?● What to do and not to do?
  3. 3. Test types1. Acceptance (end-to-end) Test as if end user would use the whole system/feature.2. Integration Test how different parts of system work together - eg. couple of classes or your class using some web service3. Unit Test single unit (eg. class). Mock all dependencies, eg. web service, file system.
  4. 4. Tests will save you time & troubles1. Prove youve done your work2. Help you check much faster if youre work is done3. Protect you from breaking things - regresion4. Help you make better code design - easier to maintain5. Let you apply changes with less worries - refactoring will improve things without breaking anything
  5. 5. How to be happy about tests?1. If youre new to testing try with writing tests after writing the code2. Once youre confident about testing try to write tests before the code - TDD3. Start with acceptance tests, than integration and unit tests when your functionality is implemented4. Run tests often - after every change and before any commit5. Use continuous integration server
  6. 6. You will regret youve got a lot oftests if you:1. make them complex and hard to read2. duplicate the test code3. do not use descriptive fail messages4. do not run them often - eg. you dont have continuous integration server5. do not make them run fast
  7. 7. Behavioral testsDraft - BehatFeature: Log in and use the application In order to use the application As a user I need to log in using my smart card@javascriptScenario: Log in with inactive smart card Given I am inactive smart card user Given I am on "http://localhost/somethign.cool.php" When I log in Then I should see log in error message
  8. 8. Whats good test like?1. Finds as much bugs as possible2. Tells you what the software can do and how to use it3. Is easy to maintain4. Independent from other tests and repeatable
  9. 9. How to start testing?1. Write acceptance test for functionality youre implementing - it should cover main story flow2. Make the test show meaningful fail message3. Implement functionality so the test is passing4. Add tests covering more story flows5. Improve functionality code so all tests are passing again6. Refactor (also tests)7. Enjoy!
  10. 10. How to start even better?1. "Wait" for a bug2. Write a test confirming/reproducing that bug3. Fix the code using the test youve got4. Enjoy!
  11. 11. TDD flowRepeat this process1. Write test2. Make test failure message descriptive and easy to understand3. Make the test pass - implement feature youve write the test for4. Refactor
  12. 12. Do not - test something irrelevant<?php// SHOULD TEST PLUGIN BUT IS TESTING DATABASE MODEL AND NOTHING MOREclass Plugin_Smooth_Streaming_BoundariesTest extends TestCase_Plugin{ ... public function testLowerBoundary() { $settings = Xstream_Loader::getModelHelper("SettingHelper"); $lowerLimit = $settings->setSetting(plugin_boundaries, lower_limit,1.0); $this->assertEquals(1.0, $settings->getSetting(plugin_boundaries, lower_limit)->value); } ...}
  13. 13. Do not - test too much at once<?php// TRY NOT TO MAKE MORE THAN 2-3 ASSERTIONS IN ONE TESTclass ResponseSetTest extends PHPUnit_Framework_TestCase{ ... public function testAddItems() { $responseSet = new Xs_Monitor_Response_Set(test); $this->assertEquals(Xs_Monitor_Interface::STATE_WARNING, $responseSet->getStateAsInteger()); $responseSet->addResponse(new Xs_Monitor_Response(service 1, Xs_Monitor_Interface::STATE_OK, detail of service 1)); $this->assertEquals(Xs_Monitor_Interface::STATE_OK, $responseSet->getStateAsInteger()); $this->assertNotEquals(detail of service 1, $responseSet->getDetails()); $responseSet->addResponse(new Xs_Monitor_Response(service 2, 3, detail of service 2)); $this->assertEquals(3, $responseSet->getStateAsInteger()); $this->assertEquals(UNKNOWN, $responseSet->getState()); $this->assertEquals(detail of service 2, $responseSet->getDetails()); $responseSet ->addResponse(new Xs_Monitor_Response(service 3, Xs_Monitor_Interface::STATE_WARNING, detail of service 3)); $this->assertEquals(Xs_Monitor_Interface::STATE_WARNING, $responseSet->getStateAsInteger()); $this->assertEquals(detail of service 3, $responseSet->getDetails()); $responseSet ->addResponse(new Xs_Monitor_Response(service 4, Xs_Monitor_Interface::STATE_CRITICAL, detail of service 4)); $this->assertEquals(Xs_Monitor_Interface::STATE_CRITICAL, $responseSet->getStateAsInteger()); $this->assertEquals(detail of service 4, $responseSet->getDetails()); $responseSet ->addResponse(new Xs_Monitor_Response(service 5, Xs_Monitor_Interface::STATE_CRITICAL, detail of service 5)); $this->assertEquals(Xs_Monitor_Interface::STATE_CRITICAL, $responseSet->getStateAsInteger()); $this->assertEquals(detail of service 4, $responseSet->getDetails());
  14. 14. Do - use meaningful test nameTest name should be descriptive even if it hasvery long name.Try to avoid test names like "testAdd" etc.Better would be something like"testAddWillPutNewItemIntoContainer" or"testAddWillThrowExceptionIfContainerIsFull" /** * @test */ public function add() { ...
  15. 15. Do - use data providers<?phpnamespace XsTestUnit;class StringTest extends TestCase{ /** * @param string $heystack * @param string $needle * @param boolean $expected * * @dataProvider endsWithDataProvider */ public function testEndsWith($heystack, $needle, $expected) { $this->assertEquals($expected, XsString::endsWith($heystack, $needle)); } public function endsWithDataProvider() { return array( array(asdf, f, true), array(asdf, df, true), array(asdf, asdf, true), array(asdf, d, false), array(asdf, xf, false), array(asdf, asd, false), ); }}
  16. 16. Do - test one unit in unit testUnit test should NOT:1. Test more than one unit/class2. Touch database, filesystem, API/WebService etc. - you should mock all "externals"3. Execute very fast - matter of 10th of second
  17. 17. Do - make tests easy to read andunderstandclass Acceptance_Product_ProductListTest extends Test_TestCase{ public function testReturnsErrorAboutNoProductsUserCanBuyWhenHeHasNoProductsRelatedToMedia() { $this->user() ->logIn() ->withoutProducts(array( $this->svodProductId, $this->premiumSvodProductId )) ->withoutOrderedMedia($this->mediaId); $this->shop()->respondsJsonAboutNoProductsAvailable($this->mediaId); }
  18. 18. Do - make tests easy to read andunderstand (2)Draftclass SortingTest extends XsCanalDigitalTestStbAdbTestCase{ /** * @test */ public function mediaListWithoutFixedSortingCanBeSortedByPressingRedButton() { $this->user() ->onPage($this->stbApp()->page(sort_fixed)); $initialAppState = $this->stbApp()->getState(maincovers); $this->user()->pressedButton(Key::BUTTON_RED); $appStateAfterPressingRedButton = $this->stbApp()->getState(maincovers); // TODO: better way of comparing items sorting $this->assertNotEquals( $initialAppState, $appStateAfterPressingRedButton, Pressing red button should change page sorting ); }
  19. 19. Summary1. Use TDD2. Unit tests should test what youve written / proper unit and nothing more3. Do not test too much in one test4. Make your tests easy to maintain - proper naming etc.5. Try to use data provider to test a lot of different cases without code duplication
  20. 20. Thank you@see Test Driven Development@see PHPUnit@see Behavioral Driven Development@see Behat@see Growing Object-Oriented Software,Guided by Tests@see www.jenkins-ci.org

×