getting started-php unit

50
Getting Started with PHPUnit Matt Frost http://joind.in/13536 @shrtwhitebldguy

Upload: mfrost503

Post on 18-Jul-2015

193 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Getting started-php unit

Getting Started with PHPUnit

Matt Frost

http://joind.in/13536

@shrtwhitebldguy

Page 2: Getting started-php unit

Who am I?

• Director of Engineering at Budget Dumpster

• Marathoner (4 marathoner)

• Dad of 2 awesome little people

• Open Source Project Creator/Contributor

• Loosely Coupled Podcast Co-Host

• Testing advocate

• Agile skeptic

Page 3: Getting started-php unit

What Can I Expect?

• Coverage of essential PHPUnit concepts

• Practical examples/code along sessions

• Just enough theory

• Assertions, Mocking, Setup, Tear Down, Test suite

structure, Dependency Injection, Code Coverage;

to name a few things.

• https://github.com/mfrost503/phpunit-tutorial

Page 4: Getting started-php unit

Finally…

• My aim is give you something you can take back

to work with you,

• …provide assistance working through real world

examples,

• …and provide you a reference resource to help

you get started testing.

Page 5: Getting started-php unit

Let’s get going!

Take a few minutes to get your environment setup if you haven’t

already. Raise your hand if you need some help getting started!

Page 6: Getting started-php unit

Why write unit tests?

Page 7: Getting started-php unit

Predictability

• Helps you KNOW that things work

• Helps teammates know things work

• Makes deployment automation easier

• Allows you to go home on time

• Useful as a debugging tool

Page 8: Getting started-php unit

Mostly though…It’s because you care and caring is good!

Page 9: Getting started-php unit

A little history

• Created by Sebastian Bergmann

• Version 1.0.0 was released April 8th, 2001

• PHP gets a bad wrap, QA/QC have helped

make it a sustainable language.

• PHP runs almost 3/4 of all web apps

• People like to know their stuff is broken before

someone else points it out to them.

Page 10: Getting started-php unit

Why PHPUnit?

• Most PHP projects use it

• It’s actively maintained and adapted

• There’s really not a better option for Unit Tests

• It does more than Unit Tests (there are better

options)

• Most testing resources in PHP assume PHPUnit

as the testing framework

Page 11: Getting started-php unit

Show me the goods!ok…

Page 12: Getting started-php unit

Testable Code

• Dependency Injection

• Separation of Concerns

• Proper Use of Access Modifiers (public, private, protected,

final)

• Building with composition and useful inheritance

• All these things are going to make testing your code

easier, more reliable and more fun!

Page 13: Getting started-php unit

Dependency Injection

• Utilize existing functionality by passing it in!

• Eliminate the “new” keyword in method bodies

• Each component can be individually tested

• Creates flexibility for the different types of

functionality (interfaces, Liskov, etc)

Page 14: Getting started-php unit

Example Time!

Example from Snaggle

Page 15: Getting started-php unit

Assertions

• Define what we expect our code to do

• If they fail, the test fails

• Different types of assertions handle different

scenarios

• There’s more than true/false/equals!

Page 16: Getting started-php unit

Examples

assertTrue($condition,string $message);

$this->assertTrue(is_numeric(1));

assertFalse($condition, string $message);

$this->assertFalse(is_string(1234));

assertStringStartsWith($prefix, $string, $message);

$this->assertStringStartsWith(“pic”, “picture”);

assertSame($expected, $actual, $message);

$this->assertSame(‘1234’, ‘1234’);

assertObjectHasAttribute($attribute, $object, $message);

$this->assertObjectHasAttribute(‘name’, new User);

assertInstanceOf($expected, $actual, $message);

$this->assertInstanceOf(‘\PDO’, $pdo);

assertEquals($expected, $actual, $message);

$this->assertEquals(10, $sum);

Page 17: Getting started-php unit

Finally some code!

Take a look at the following files:

src/Math/Addition.php

tests/Math/AdditionTest.php

Page 18: Getting started-php unit

Write a test!

To start, we want to write a test that verifies that

our code is adding the numbers in the array

correctly.

Take a few minutes to do that, I’ll be walking

around if you have any questions

Page 19: Getting started-php unit

Exceptions

@expectedException annotation in the docblock

$this->setExpectedException($exception);

Page 20: Getting started-php unit

Data Providers

@dataProvider <methodName>

Here’s an example!

Page 21: Getting started-php unit

public function numberProvider()

{

return [

[1, 2, 3],

[2, 3, 4],

[4, 5, 6]

];

}

/**

* @dataProvider numberProvider

public function testNumbers($num1, $num2, $num3)

{

Page 22: Getting started-php unit

Add tests

Take a look at the code. Other than returning the

correct answer, what are some other things that

can happen?

Write some tests to verify the other behaviors

Page 23: Getting started-php unit

Serializers and Interfaces

Page 24: Getting started-php unit

Data Serialization

The transformation of data from a certain format to

another format

Page 25: Getting started-php unit

Common types

• JSON

• PHP Array

• PHP Object

• serialize()

• json_encode()

• json_decode()

Page 26: Getting started-php unit

A Word on Interfaces

Serializers are a good example for interfaces,

since the need to transform data to a from

different formats is a common need.

Page 27: Getting started-php unit

Contracts

By adhering to a contract, the serializer types can

be interchanged as needed and type hinted on the

interface

Page 28: Getting started-php unit

Serializer Tests

If you look at src/Tutorial/Serializers - you will see

a number of different types. Write some tests for

them

Page 29: Getting started-php unit

Cue the Jeopardy Theme

src/Tutorial/Serializers

tests/Tutorial/Serializers

Page 30: Getting started-php unit

Communicating with data stores

• Don’t connect to them

• Don’t talk to them

• Don’t expect them to be available

• Don’t expect data to be there

Page 31: Getting started-php unit

In the context of your tests, dependencies are

strangers and shouldn’t trust them.

Page 32: Getting started-php unit

You see…

• Using actual data sources means your tests

expect a certain state

• If source is down, tests fail…tells us nothing

about our code

• These are unit tests, we want them to run

quickly

• Ever seen an API with a 10 sec response time?

I have, they exist…

Page 33: Getting started-php unit

It’s not fanatical dogma

Page 34: Getting started-php unit

You will hate testingand that’s not what we want

Page 35: Getting started-php unit

Test Doubles

• The act of replicating dependencies

• We model them for scenarios

• We use them to avoid strangers

• We know them because we make them

Page 36: Getting started-php unit
Page 37: Getting started-php unit

What can we mock?

• API calls

• Database calls

• Internal functions*

* we can use runkit to change how internal

functions like mail interact in the test

Page 38: Getting started-php unit

What about the data?

Page 39: Getting started-php unit

How?

• Data Fixtures

• Predefined responses

• Data providers

• Data fixtures are realistic data that is read into a

test to simulate an actual response

Page 40: Getting started-php unit

It only works if it’s realistic

• Model realistic responses

• Save an API/DB/Cache call to a file

• Read it in, have the mock return it

• It’s that easy!

Page 41: Getting started-php unit

Sometimes…

There is no response and we just need to fill a

parameter requirement or we just want to make

sure a method in a dependency is called

Page 42: Getting started-php unit

Components

• Method - what method are we mocking

• Expectation - how often do we expect it to be called

• Parameters - what does it need to be called with?

• Return - Is it going to return data?

Page 43: Getting started-php unit

Example

$pdoMock = $this->getMock(‘PDO’);

$statement = $this->getMock(‘PDOStatement’);

$pdoMock->expects($this->once())

->method(‘prepare’)

->with(“SELECT * from table”)

->will($this->returnValue($statement));

Page 44: Getting started-php unit

That’s all there is too it

So when we run this code, we are mocking a

prepared statement in PDO

We can mock PDO Statement to handle the retrieval

of data

Page 45: Getting started-php unit

Let’s give it a go!

Have a look at:

src/Tutorial/Mocking/PDO

Try to write some tests for these classes

Page 46: Getting started-php unit

Did you notice?

We could very easily add a second parameter and

serialize the return data into our User value object.

In which case, we could choose to mock or not

mock the serializer.

Page 47: Getting started-php unit

API Mocking

• Guzzle

• Slack API

• Practice Mocking Guzzle

• GuzzleHttp\Client

• GuzzleHttp\Message\Response

Page 48: Getting started-php unit

Exceptions

There are some example tests, finish the tests -

looking for exceptions!

Page 49: Getting started-php unit

Code Coverage Report

• Different output formats

• Analyze how completely you’ve tested

• Can be used to find testing gaps

• 100% shouldn’t be your primary goal - write

tests that make sense, not just to up coverage

Page 50: Getting started-php unit

Generating Reports

• vendor/bin/phpunit —coverage-html <location>

• Must have xdebug installed to generate reports

• Make sure you generate them to a directory in your

gitignore.