Making friends with TDD

Post on 10-May-2015

153 views 4 download

Tags:

Transcript of Making friends with TDD

Making Friends with TDD

John ClearyLead Web Developer, DocNet

@TheRealBifter

So, What is TDD?

10 Write one test20 Run tests (they fail)30 Write code to make test pass40 Run tests again (they pass)50 Refactor (code AND tests)60 Run test (they still pass)70 Goto 10

Red

GreenRefactor

Red

GreenRefactor

Write����������� ������������������  a����������� ������������������  failing����������� ������������������  test

Red

GreenRefactor

Write����������� ������������������  a����������� ������������������  failing����������� ������������������  test

Fix����������� ������������������  the����������� ������������������  test

Red

GreenRefactor

Write����������� ������������������  a����������� ������������������  failing����������� ������������������  test

Fix����������� ������������������  the����������� ������������������  test

Make����������� ������������������  it����������� ������������������  pretty

Why do it?

1. Improved Code Design

Classes that are easy to test are by definition decoupled.

1. Improved Code Design

Classes that are easy to test are by definition decoupled.

Encourages refactoring

1. Improved Code Design

2. Verification

Fewer bugs

2. Verification

Fewer bugs

Easier to maintain

2. Verification

Awesome - let’s do it, right?

Awesome - let’s do it, right?

Wait!

Does it take longer?

Does it take longer?

Maybe, maybe not.

Is it harder?

Is it harder?

For sure!

But it wrecks my creativity, dude?

But it wrecks my creativity, dude?

Really? Do some prototypes man!

Could we get these benefits without TDD?

Could we get these benefits without TDD?

No, but yeah, but no...

Awesome, let's do it!(for real this time)

Recently Used List Class

Recently Used List ClassDevelop a recently-used-list class to hold strings uniquely in Last-In-First-Out order.

Recently Used List Class

A recently-used-list is initially empty.

Develop a recently-used-list class to hold strings uniquely in Last-In-First-Out order.

Recently Used List Class

A recently-used-list is initially empty.The most recently added item is first, the least recently added item is last.

Develop a recently-used-list class to hold strings uniquely in Last-In-First-Out order.

Recently Used List Class

A recently-used-list is initially empty.The most recently added item is first, the least recently added item is last.Items can be looked up by index, which counts from zero.

Develop a recently-used-list class to hold strings uniquely in Last-In-First-Out order.

Recently Used List Class

A recently-used-list is initially empty.The most recently added item is first, the least recently added item is last.Items can be looked up by index, which counts from zero.Items in the list are unique, so duplicate insertions are moved rather than added.

Develop a recently-used-list class to hold strings uniquely in Last-In-First-Out order.

Recently Used List Class

A recently-used-list is initially empty.The most recently added item is first, the least recently added item is last.Items can be looked up by index, which counts from zero.Items in the list are unique, so duplicate insertions are moved rather than added.

Develop a recently-used-list class to hold strings uniquely in Last-In-First-Out order.

Recently Used List Class

A recently-used-list is initially empty.The most recently added item is first, the least recently added item is last.Items can be looked up by index, which counts from zero.Items in the list are unique, so duplicate insertions are moved rather than added.

Develop a recently-used-list class to hold strings uniquely in Last-In-First-Out order.

Recently Used List Class

A recently-used-list is initially empty.The most recently added item is first, the least recently added item is last.Items can be looked up by index, which counts from zero.Items in the list are unique, so duplicate insertions are moved rather than added.

Develop a recently-used-list class to hold strings uniquely in Last-In-First-Out order.

Recently Used List Class

A recently-used-list is initially empty.The most recently added item is first, the least recently added item is last.Items can be looked up by index, which counts from zero.Items in the list are unique, so duplicate insertions are moved rather than added.

Develop a recently-used-list class to hold strings uniquely in Last-In-First-Out order.

Refactor����������� ������������������  to����������� ������������������  this

That wasn’t so hard...

That wasn’t so hard...

...but what about testing the persistence layer?

You’ve got options

Mock the database layer

DBUnit

Codeception

You’ve got options

Mock the database layer

DBUnit

Codeception

You’ve got options

The����������� ������������������  purist����������� ������������������  way

Mock the database layer

DBUnit

Codeception

You’ve got options

The����������� ������������������  purist����������� ������������������  way

The����������� ������������������  easy����������� ������������������  way

Mock the database layer

DBUnit

Codeception

You’ve got options

The����������� ������������������  purist����������� ������������������  way

The����������� ������������������  easy����������� ������������������  way

The����������� ������������������  even����������� ������������������  easier����������� ������������������  way

Mock Examplefunction testInsertDatabase(){ $insertArray = array( 'name' => 'Miles', );

// create a mock database $mock = $this->getMockBuilder('Zend_Db_Adapter_Pdo_Mysql', array('insert')) ->disableOriginalConstructor() ->getMock();

// mock out the insert method $mock ->expects($this->once()) ->method('insert') ->with($insertArray);

// pass the database to the container $container = new DIContainer(): $container->set('database', $mock);

// run the test $user = new User(); $user->setName('Miles'); $user->save();}

Not great because• Requires Dependency Injection• Can be fragile• Complicated

But good because• Super fast• Not tied to database structure

DBUnit Examplepublic function testCanCreateNewUser(){ $user = new User(); $user->setName('Miles'); $user->save();

$queryTable = $this->getConnection()->createTableQuery( 'users', 'SELECT * from users' );

$expectedTable = $this->createFlatXmlDataSet("users-expected.xml") ->getTable('users');

$this->assertTableEquals($expectedTable, $queryTable);}

Not great because• Slow• Can be fragile• Tied to database structure• Requires xml setup of expected results

But good because• Tests are easy to write and read• It’s obvious whats being tested

Codeception Example<?phpfunction testSavingUser(){ $user = new User(); $user->setName('Miles'); $user->save(); $this->codeGuy->seeInDatabase('users',array('name' => 'Miles'));}?> Not great because

• Slow• Tied to database structure

But good because• Less fragile than DBUnit (no xml to maintain)• Tests are easy to write and read• It’s obvious whats being tested

When testing the DB...

When testing the DB...

Give each developer their own test database (preferably on their own VM)

When testing the DB...

Give each developer their own test database (preferably on their own VM)

DB tests are slow - move them outside the main suite or use memory tables

When testing the DB...

Give each developer their own test database (preferably on their own VM)

DB tests are slow - move them outside the main suite or use memory tables

Use a tool like “Migrations” to keep databases in sync

UI Testing

UI Testing

PHPUnit with Selenium

UI Testing

PHPUnit with Selenium

Codeception

So, where do we go from here?

1. Have a go

www.cyber-dojo.com

2. Build up slowly

2. Build up slowly

Start with one afternoon per week

2. Build up slowly

Start with one afternoon per week

Try pair programming

3. Motivate your team

3. Motivate your team

Start a Coding Club / Kata

3. Motivate your team

Start a Coding Club / Kata

[Get your boss to] buy some books

3. Motivate your team

Start a Coding Club / Kata

[Get your boss to] buy some books

See����������� ������������������  me����������� ������������������  after����������� ������������������  this����������� ������������������  talk

4. Get a CI server

Jenkins

Travis

CruiseControl

5. Share

5. Share

Attend public Katas

5. Share

Attend public Katas

Forums & IRC

Questions ?

Thank YouJohn Cleary

Lead Web Developer, DocNet@TheRealBifter