Developer testing 101: Become a Testing Fanatic

3,218 views
3,141 views

Published on

In this workshop we will cover the methodologies and three basic levels of testing, then we will deep dive into how to use PHPUnit to achieve developer testing. The tests may not be the prettiest, most robust, or efficient, but you should leave the course with the ability and confidence to write tests for your code.

Topics include: xUnit framework basics and workflows, test classification, asserts, data driven testing, and an introduction to mocking.

This is a beginner course, but seasoned veterans may discover features they never knew.

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

No Downloads
Views
Total views
3,218
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
0
Comments
0
Likes
5
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
  • Developer testing 101: Become a Testing Fanatic

    1. 1. Developer Testing 101
    2. 2. Goals• Learn what is Developer Testing• Gain confidence in writing tests with an xUnit Testing Framework
    3. 3. Non-Goals• When to test with external dependencies, ie. databases• Not to necessarily learn how to write the best (code) tests
    4. 4. ResourcesCode Samples https://github.etsycorp.com/llincoln/ DeveloperTesting101PHPUnit Manual http://www.phpunit.de/manual/current/en/PHPUnit GitHub https://github.com/sebastianbergmann/phpunitEtsy PHPUnit Extensions https://github.com/etsy/phpunit-extensions/wiki
    5. 5. Topics• Methodology, Terminology, Kool-Aid• xUnit Basics and Theory• Assertions• Data Driven Tests• Test Classification• Stubs, Fakes, and Mocks
    6. 6. • Methodology, Terminology, Kool-Aid • Agile • Test-Driven Development (TDD) • Pyramid of Testing
    7. 7. Agile
    8. 8. a·gil·i·ty [uh-jil-i-tee]  noun1. the power of moving quickly and easily;nimbleness: exercises demanding agility.2. the ability to think and draw conclusionsquickly; intellectual acuity.
    9. 9. Agile Manifesto• Individuals and interactions • over processes and tools• Working software • over comprehensive documentation• Customer collaboration • over contract negotiation• Responding to change • over following a plan
    10. 10. TDD
    11. 11. TDDTest Driven Development
    12. 12. WaterfallThe Assembly Line
    13. 13. TDD Waterfall
    14. 14. Developer Testing TDD is a design process
    15. 15. Why Developer Testing? • Verify Correctness • Communication • Gain Confidence
    16. 16. Inside Out v. Outside In
    17. 17. Inside Out v. Outside In • Implement first • Test first • Easy to code • Easy to test • Difficult to test • Easy to code
    18. 18. Tests should always be treated like everyother consumer of the subject under test.
    19. 19. Pyramid of Testing
    20. 20. Test TypesVocabulary Break!
    21. 21. Functional TestsDoes the overallproduct satisfy thethe requirements?
    22. 22. Integration TestsDo the pieces fittogether?
    23. 23. Unit TestsIs the logic correct inthat function?
    24. 24. FunctionalUnderstand the product.
    25. 25. The Tools
    26. 26. The Tools• BeHat (Cucumber)
    27. 27. The Tools• BeHat (Cucumber)• PHPSpec
    28. 28. The Tools• BeHat (Cucumber)• PHPSpec• Keyboard, Mouse, and You
    29. 29. When Do They Work?• During prototyping• Focused on the product requirements• Refactoring• Regression of key features• Better for smaller teams
    30. 30. ...Stop Helping?• Focused on the implementation• Rapidly changing functionality• Large organizations
    31. 31. AfterGreenfieldInverted Test Pyramid
    32. 32. Test PyramidFood Pyramid of the 90s
    33. 33. Unit TestsSimple and to the point.
    34. 34. Verify Correctness• Line coverage• Branch coverage• Icky Bits-o-Logic
    35. 35. Gain Confidence• Individual functions• Variety of parameters• Works for expected interactions with collaborators
    36. 36. Communication• Show how to use the function• Show expected interactions with other collaborators• Increase discoverability of possible reuse
    37. 37. IntegrationFor everything in-between.
    38. 38. You’re Paranoid• Experimenting with third-party code or service• You do not trust that your collaborators work as specified
    39. 39. Sorry! Piece of Testing Functional Integration Unit
    40. 40. • Methodology, Terminology, Kool-Aid • Agile for realz! Developer Testing • Test-Driven Development (TDD) Sorry! piece • Pyramid of Testing
    41. 41. xUnit Basics and Theory
    42. 42. TestCaseclass My_Class { ... }class My_ClassTestextends PHPUnit_Framework_TestCase{ ... }
    43. 43. testFunctionclass My_Class { function foo(){ ... }}class My_ClassTestextends PHPUnit_Framework_TestCase { function testFoo() { ... }}
    44. 44. @testclass My_ClassTestextends PHPUnit_Framework_TestCase { /** * @test */ function foo() { ... }}
    45. 45. Several Tests Per Function class My_Class { function foo(/*bool*/ $param){ ... } } class My_ClassTest extends PHPUnit_Framework_TestCase { function testFoo_true() { ... } function testFoo_false() { ... } }
    46. 46. xUnit Basics• HappySet• 01-xUnitBasics • FlowTest.php • ChildTest.php -> ParentTest.php • UniqueInstanceTest.php • StaticTest.php • GlobalStateTest.php • TestListener.php and listener-
    47. 47. Honorable Mentions• public static function setUpBeforeClass()• public static function tearDownAfterClass()• /** @depends */
    48. 48. Equivalence Class Partitioning A Little Math Lesson
    49. 49. Equivalence Relation• Let S be any set and let ~ be a relation on S. Then ~ is called an equivalence relation provided it satisfies the following laws: • Reflexive a ~ a • Symmetrical a ~ b implies b ~ a • Transitive a ~ b and b ~ c implies a ~ c
    50. 50. Partition• A partition of a nonempty set S is a collection of nonempty subsets that are disjoint and whose union is S.
    51. 51. Equivalence ClassConsider again an equivalence relation ~ on aset S. For each s in S we define [s] = {t ∈ S : s ~ t}The set [s] is called the equivalence classcontaining s.
    52. 52. InputPartitioning Write just the right number of tests
    53. 53. ECP• 02-ECP • Boolean.php • String.php • Integer.php • ControlStructures.php • Object.php
    54. 54. Assertions
    55. 55. Assertions• 03-Assertions • StatusTest.php • AssertTest.php • ExceptionTest.php
    56. 56. Built-In Assertions• assertArrayHasKey • assertLessThanOrEqual• assertContains • assertNull• assertContainsOnly • assertRegExp• assertCount • assertStringMatchesFormat• assertEmpty • assertSame• assertEquals • assertStringStartsWith• assertFalse • assertStringEndsWith• assertGreaterThan • assertTag• assertGreaterThanOrEqual • assertThat• assertInstanceOf • assertTrue• assertInternalType• assertLessThan • more...
    57. 57. Custom Asserts• Work-around for multiple asserts• No appropriate assert or constraint exists• One of the few times statics aren’t so bad• Consider writing a new PHPUnit_Framework_Constraint• Use assertThat( mixed $value, PHPUnit_Framework_Constraint $constraint [, $message = ‘’] )
    58. 58. Data Driven Tests
    59. 59. Data Driven Testing• 04-DataDrivenTesting • Calculator.php • CalculatorTest.php • DataDrivenTest.php
    60. 60. @dataProvider /** * @dataProvider <methodName> */• Provider method must be public• Return must be a double array• Cannot depend on instance variables• Always use literal values
    61. 61. Test Classification
    62. 62. External Dependencies• Memcache• MySQL• Postgres• Services via Network
    63. 63. More Sources of Flake• Sleep• Date/Time• Random Number Generators
    64. 64. @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
    65. 65. Unit Tests are DEFAULT There is NO @group for unit tests.
    66. 66. 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
    67. 67. Stubs, Fakes, and Mocks
    68. 68. The Difference• Stub returns fixed values• Fake returns modifiable values• Mock mimics the behavior of the original
    69. 69. Creating a Mock /** * Returns a mock object for the specified class. * * @param string $originalClassName * @param array $methods * @param array $arguments * @param string $mockClassName * @param boolean $callOriginalConstructor * @param boolean $callOriginalClone * @param boolean $callAutoload * @return PHPUnit_Framework_MockObject_MockObject * @throws InvalidArgumentException * @since Method available since Release 3.0.0 */    public function getMock($originalClassName, $methods = array(), array$arguments = array(), $mockClassName = , $callOriginalConstructor = TRUE,$callOriginalClone = TRUE, $callAutoload = TRUE) { ... }    
    70. 70. Mock Builder$stub = $this->getMock( ‘SomeClass’, null, null, ‘’, false); or$stub = $this->getMockBuilder(‘SomeClass’) ->disableOriginalConstructor() ->getMock();
    71. 71. Mock Builder Options• setMethods(array|null $methods)• setConstructorArgs(array|null $args)• setMockClassName($name)• disableOriginalConstructor()• disableOriginalClone()• disableAutoload()
    72. 72. expects()• Takes a PHPUnit_Framework_MockObject_Matcher • $this->any() • $this->never() • $this->once() • $this->exactly(int $count) • $this->at(int $index)
    73. 73. method()• Simply takes the name of the method to stub/mock as a String
    74. 74. with()• Takes a variable number of Strings or PHPUnit_Framework_Constraints
    75. 75. 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...
    76. 76. will()• Takes a PHPUnit_Framework_MockObject_Stub • $this->returnValue() • $this->returnArgument() • $this->returnSelf() • $this->returnValueMap() • $this->returnCallback() • $this->onConsecutiveCalls() • $this->throwsException()
    77. 77. Return Stub• See an example of a PHPUnit_Framework_MockObject_Stub • etsy/phpunit-extensions
    78. 78. Stub (or Fake) in PHPUnit$stub = $this->getMock(‘SomeClass’);$stub ->expects($this->any()) ->method(‘someMethod’) ->will($this->returnValue(2));
    79. 79. Mocks in PHPUnit$mock = $this->getMock(‘SomeClass’);$mock ->expects($this->any()) ->method(‘someMethod’) ->with($this->greaterThan(2)) ->will($this->returnValue(true));
    80. 80. Preview: Mockery• Requires PHP 5.3• More fluent PHPUnit Mocks • expects->method->with->will• Example use Mockery as m; class SimpleTest extends PHPUnit_Framework_TestCase { public function testSimpleMock() { $mock = m::mock(simple mock); $mock->shouldReceive(foo)->with(5, m::any())->once()->andReturn(10); $this->assertEquals(10, $mock->foo(5)); } public function teardown() { m::close(); } }

    ×