Developer testing 201: When to Mock and When to Integrate

2,051 views

Published on

This workshop is for those who know how to write developer tests in PHPUnit. This workshop will expand upon that knowledge and further emphasize the difference between unit testing and integration testing. We will cover better tools and techniques for integration testing with databases and external services, and we will cover advanced mocking techniques to maintain a more fast and robust test suite.

Topics include: DBUnit, PHPUnit Mocks, Mockery, vfsStream

This course requires prior experience with PHPUnit or the 'Developer Testing 101: Become a Testing Fanatic' course.

Published in: Technology
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,051
On SlideShare
0
From Embeds
0
Number of Embeds
3
Actions
Shares
0
Downloads
0
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Developer testing 201: When to Mock and When to Integrate

    1. 1. Developer Testing 201
    2. 2. Goals• Learn advanced unit testing techniques• Build a toolbox for integration testing• Begin to be able to assess appropriate testing needs and usages
    3. 3. Non-Goals• Not an introduction to testing• Not to necessarily learn how to write the best (code) tests, but getting closer
    4. 4. ResourcesCode Samples https://github.com/elblinkin/DeveloperTesting201PHPUnit Manual http://www.phpunit.de/manual/current/en/PHPUnit GitHub https://github.com/sebastianbergmann/phpunitEtsy PHPUnit Extensions https://github.com/etsy/phpunit-extensions/wikiMockery https://github.com/padraic/mockery
    5. 5. Topics• Review Test Sizes• Database Testing• Custom Assertions• Mock Objects• Filesystem Testing• Network Testing
    6. 6. Test PyramidFood Pyramid of the 90s
    7. 7. Test TypesVocabulary Break!
    8. 8. Functional TestsDoes the overallproduct satisfy thethe requirements?
    9. 9. Integration TestsDo the pieces fittogether?
    10. 10. Unit TestsIs the logic correct inthat function?
    11. 11. FunctionalUnderstand the product.
    12. 12. The Tools
    13. 13. The Tools• BeHat (Cucumber)
    14. 14. The Tools• BeHat (Cucumber)• PHPSpec
    15. 15. The Tools• BeHat (Cucumber)• PHPSpec• Keyboard, Mouse, and You
    16. 16. When Do They Work?• During prototyping• Focused on the product requirements• Refactoring• Regression of key features• Better for smaller teams
    17. 17. AfterGreenfieldInverted Test Pyramid
    18. 18. ...Stop Helping?• Focused on the implementation• Rapidly changing functionality• Large organizations
    19. 19. Test PyramidFood Pyramid of the 90s
    20. 20. Unit TestsSimple and to the point.
    21. 21. Verify Correctness• Line coverage• Branch coverage• Icky Bits-o-Logic
    22. 22. Gain Confidence• Individual functions• Variety of parameters• Works for expected interactions with collaborators
    23. 23. Communication• Show how to use the function• Show expected interactions with other collaborators• Increase discoverability of possible reuse
    24. 24. Tests should always be treated like everyother consumer of the subject under test.
    25. 25. IntegrationFor everything in-between.
    26. 26. You’re Paranoid• Experimenting with third-party code or service• You do not trust that your collaborators work as specified
    27. 27. Sorry! Piece of Testing Functional Integration Unit
    28. 28. Test Classification
    29. 29. External Dependencies• Caches, ie. Memcache• Databases, ie. MySQL, Postgres, etc.• 3rd Party Services• Filesystem
    30. 30. More Sources of Flake• Sleep• Date/Time• Random Number Generators• Multiple-Processes
    31. 31. @group• @group cache • for test that use memcache• @group dbunit • for test that use DBUnit and databases• @group network • for tests that talk to external services• @group flaky • for tests that fail without a code change
    32. 32. Unit Tests are DEFAULT There is NO @group for unit tests.
    33. 33. Test Sizes• New in PHPUnit 3.6• @small run in less than one second• @medium run in less than 10 seconds• @large run in less than 60 seconds• Note: All times are configurable
    34. 34. Database Testing
    35. 35. DBUnit: Basic Steps1. Set Up Fixture • getDataSet() • getConnection()2. Exercise System Under Test3. Verify Outcome4. Tear Down
    36. 36. Supported Databases• MySQL• PostgreSQL• Oracle• SQLite• IBM DB2 or Microsoft SQL Server • via Zend Framework or Doctrine 2
    37. 37. DataSet Options• XML • Replacement• Flat XML • Filter• MySQL XML • Composite• YAML• CSV• Query (SQL)• Database (DB)• Array* * from Etsy Extensions
    38. 38. Example Deep Dive• 01 - Database • 01 - Simple (Read-Only DBUnit Test) • 02 - TestCase (Extract Custom) • 03 - Modify (Modifying Existing) • 04 - Create (Adding Data) • 05 - DRYing (Reducing Integration Points)
    39. 39. Custom Assertions
    40. 40. Custom Assert
    41. 41. Custom Assert: Lv. 1
    42. 42. Custom Assert: Lv. 1 Multiple Asserts!!1234
    43. 43. Custom Assert: Lv. 1 No Message!!
    44. 44. Custom Assert: Lv. 1 N ot N ot N ot N ot N ot
    45. 45. Custom Assert: Lv. 2
    46. 46. Custom Assert: Lv. 2 Not An Assertion
    47. 47. Custom Assert: Lv. 2 assertTrue(true);
    48. 48. Custom Assert: Lv. 2 Messaging is Awkward * Look at PHPUnit assertEquals() output.
    49. 49. Custom Assert: Lv. 2 N ot !() ‘Expected %s to not be equal to %s.’
    50. 50. Custom Assert: Lv. 3
    51. 51. Custom Assert: Lv. 3 Single Assert!
    52. 52. Custom Assert: Lv. 3 Message!
    53. 53. Custom Assert: Lv. 3 Easy Inverse!
    54. 54. Custom Assert: Lv. 3 Message! Single Assert! Easy Inverse!
    55. 55. Custom Assert: Lv. 3 What’s this?!?
    56. 56. Constraints
    57. 57. Constraints• Based on Hamcrest matchers• Can be used in assertThat() for Custom Asserts• Can also be used in with()for Mock Objects
    58. 58. Constraints
    59. 59. Custom Assert: Lv. 2 ( This is It! )
    60. 60. Constraints
    61. 61. Constraints with() Mocks
    62. 62. Constraints with() Mocks
    63. 63. with()• equalTo() • identicalTo()• anything() • isInstanceOf()• isTrue() • isType()• isFalse() • matchesRegularExpression• isNull() • matches()• contains() • stringStartWith()• containsOnly() • stringEndWith()• arrayHasKey() • stringContains()• isEmpty() • logicalAnd()• greaterThan() • logicalOr()• greaterThanOrEqual() • logicalNot()• lessThan() • logicalXor()• lessThanOrEqual() • more...
    64. 64. Custom Assert: Lv. 3 Composed Constraint
    65. 65. Composed Constraint * See: Etsy PHPUnit-Extensions
    66. 66. Composed Constraint * See: Etsy PHPUnit-Extensions
    67. 67. Constraints v. Matcher(?) • PHPUnit Constraint • evaluate() • Hamcrest Matcher • matches() • Mockery Matcher • match()
    68. 68. Constraints
    69. 69. Mockery Matcher
    70. 70. Hamcrest Matcher
    71. 71. Mock Objects
    72. 72. Mock Object
    73. 73. Mock Object Have To Specify Occurrences Every Time Can Have Only ONE Expectation Per Method
    74. 74. Workarounds• There are hacks to allow multiple expectations per method• See: https://github.com/etsy/phpunit- extensions/wiki/Mock-object
    75. 75. Mockery
    76. 76. MockeryYou Can Use Hamcrest Matchers Instead! anyOf() This is Need for Verification
    77. 77. Bootstrap for Mockery bootstrap.php phpunit --boostrap=bootstrap.php or set in your phpunit.xml
    78. 78. Mockery PHPUnit Listener
    79. 79. Mockery PHPUnit Listener No tearDown() Boilerplate Omit Mockery from Coverage
    80. 80. Incompatible with --strict N ot h i Nu m b ng Co e r of E u nt s t xp e ct he atio n s !!
    81. 81. Mockery
    82. 82. Mockery TestCase PHPUnit_Extensions_Mockery_TestCase $this->getMockery(‘s imple mock’); anyOf()
    83. 83. Mockery TestCase
    84. 84. Mockery TestCaseExtra Namespace-ing, Gone! Expectations Count! No bootstrap.php or TestListener necessary!!
    85. 85. @mockery Creates a Mockery Instance
    86. 86. Mix and Match Create with Annotation Make a Partial Mock Use PHPUnit Mock Objects too!
    87. 87. Filesystem Testing
    88. 88. vfsStream• Virtual FileSystem• In-Memory• Utilizes stream_wrapper_register • vfs://path/to/my/file.txt
    89. 89. Works With...• file_exists• copy• mkdir• unlink• is_file• is_dir• ...
    90. 90. Pure Filenames Only• realpath()• symlink()• SplFileInfo::getRealPath()
    91. 91. Not Supported in 5.3• touch()• chmod()• chown()• chgrp()
    92. 92. Other Limitations• ext/zip • does not support user-land stream wrappers• is_executable() • always returns false
    93. 93. Not Implemented• stream_set_blocking()• stream_set_timeout()• stream_set_write_buffer()
    94. 94. Examples• 05 - Filesystem • vfsStream/examples • Taggle
    95. 95. Network Tests
    96. 96. Web Services• SOAP/WSDL • $this->getMockFromWsdl();• Thin Wrap Your Web Service Client
    97. 97. Closing Thoughts• Minimize Integration Points• Minimize Integration Tests• Wrap External (Hostile) Dependencies• Try to Avoid Test Fixture Files• Test Your Custom Test Tools• Consider Alert Systems, not CI
    98. 98. ResourcesCode Samples https://github.com/elblinkin/DeveloperTesting201PHPUnit Manual http://www.phpunit.de/manual/current/en/PHPUnit GitHub https://github.com/sebastianbergmann/phpunitEtsy PHPUnit Extensions https://github.com/etsy/phpunit-extensions/wikiMockery https://github.com/padraic/mockery

    ×