42
Learn To Test Like A Grumpy Programmer Chris Hartjes SushinePHP 2017

Learn To Test Like A Grumpy Programmer - 3 hour workshop

Embed Size (px)

Citation preview

Page 1: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Learn To Test Like A Grumpy Programmer

Chris Hartjes SushinePHP 2017

Page 2: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Who is this guy and why

should I listen?• Long-time tester • Beard conveys authority • Twitter account is verified • PHP dev since 1998 • Wants to help you get

better!

Page 3: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Building BlocksIt’s Like Using Lego

Page 4: Learn To Test Like A Grumpy Programmer - 3 hour workshop

It’s Like Lego!

• TDD encourages creating applications by combining units together like Legos

• Results in loosely-coupled modules

• Unit testing tools are no different

Page 5: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Assertions

• The backbone of unit testing

• Simple to understand

Page 6: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Assertions

• Unit tests (usually) usually have one or more assertions

• Proves that your expectation of an outcome is correct

Page 7: Learn To Test Like A Grumpy Programmer - 3 hour workshop

The Simplest Test That Runs

Page 8: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Assertions

• $this->assertTrue(<some expression>)

• $this->assertFalse(<some expression>)

• $this->assertEquals(<value 1>, <value 2)

Page 9: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Assertions

Those three assertions will cover

99% of your unit testing needs

Page 10: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Code Kata I

• Code katas are small coding exercises with known solutions

• Designed to turn certain programming practices into “muscle memory”

• Concept taken from Asian martial arts

Page 11: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Code Kata I

• FizzBuzz!

• great exercise for covering programming basics

• easily tested

Page 12: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Code Kata I

• make sure you create a directory to do your exercises in

• make sure you have Composer installed

• make sure you’ve installed PHPUnit using it

Page 13: Learn To Test Like A Grumpy Programmer - 3 hour workshop

FizzBuzz• Take a collection of integers only

• If the integer is divisible by 3, change it to ‘Fizz’

• If the integer is divisible by 5, change it to ‘Buzz’

• If the integer is divisible by 3 and 5, change it to ‘FizzBuzz’

• Otherwise do not change the value

Page 14: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Data Providers

• Reduce the number of tests you write

• Modify test data sets without modifying test

Page 15: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Data Providers

• Modify test method to accept parameters matching the data you will provide

• Create a method that returns an array of arrays containing data

Page 16: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Code Kata II

• Your turn to do some TDD!

• Create an object that turns Arabic numbers into Roman Numerals

Page 17: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Code Kata II

• Use TDD to design your class

• Use data providers

• Get into writing code in an iterative way

Page 18: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Code Kata II1 -> I 2 -> II 3 -> III 4 -> IV

5 -> V 6 -> VI 7 -> VII 8 -> VIII

9 -> IX 10 -> X 40 -> XL 50 -> L

Page 19: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Dependency Management In Unit Tests

• Figure out your dependencies

• Figure out which ones need to be doubles

• “Inject” them for your code-under-test to use

Page 20: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Dependency Injection Techniques

• Globally-available containers

• Constructor injection

• Setter injection

Page 21: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Globally-available Containers

• Best for legacy code where refactoring to injection is difficult

• Can use $GLOBALS super global in a pinch

• Container / service locator usage very common

Page 22: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Constructor Injection

• Pass in dependencies at object creation

• Gets messy if many dependencies are required

• Can lead to __construct() doing too much work

Page 23: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Setter Injection

• “Less messy” than using constructors

• Refactoring to add get/set methods not overly intrusive

• Allows overriding of internally-created dependencies

Page 24: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Test Doubles

• Understanding them was the most difficult thing I had to learn

• Makes you understand how critical putting dependencies in specific states is

Page 25: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Types Of Test Doubles

• Classical definition is that there are five types

• Dummy objects, test stubs, test spies, test mocks, test fakes

Page 26: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Types Of Test Doubles

• PHPUnit-compatible test double tools tend to only use three

• Dummy objects, test stubs, test mocks

Page 27: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Dummy Object

• Stand-in for the real dependency

• Does not any functionality

• Only needs to ‘look like’ the real dependency

Page 28: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Dummy Object

$mock = Mockery::mock(‘Grumpy\Foo’);

Page 29: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Stubs

• ‘Dummy object’ but with defined methods

• Methods don’t need to return anything

• Satisfies any calls to the dependency where the response doesn’t matter

Page 30: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Stubs

$mock = Mockery::mock(‘Grumpy\Foo’); $mock->shouldReceive(‘bar’);

Page 31: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Mocks

• ‘Stub’ where return value for methods are set

• Most common test double you will use

Page 32: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Mocks

$mock = Mockery::mock(‘Grumpy\Foo’); $mock->shouldReceive(‘bar’)

->andReturn(false);

Page 33: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Test Doubles Considered Harmful

• Be careful to not fall in love with test doubles

• Having to create too many of them exposes tightly-coupled code

Page 34: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Test Doubles Considered Harmful

• Use them when you have a dependency that is difficult to use under normal circumstances

• Database connections and 3rd party API calls come to mind

Page 35: Learn To Test Like A Grumpy Programmer - 3 hour workshop

A Simple Example

Page 36: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Code Kata III• Use TDD to add a method called getAllActive()

• Uses fetchAll() to get back a data set that includes id, email, and where is_active is set to 1 or 0

• Have at least 3 records, with 2 active

• You must manually filter out records in getAllActive()

• return results as array with just ‘id’ and ‘email’

Page 37: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Bonus Round!

Page 38: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Automation!(Help humans make fewer mistakes)

Page 39: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Deployments!(They should be trivial)

Page 40: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Opportunity Costs!(Make the cost of fixing bugs cheaper)

Page 41: Learn To Test Like A Grumpy Programmer - 3 hour workshop

TDD Works!(Studies exist showing effectiveness)

Page 42: Learn To Test Like A Grumpy Programmer - 3 hour workshop

Want To Learn More?

• https://grumpy-learning.com

• @grmpyprogrammer on Twitter

[email protected]