Do & Don't of TDD

The Problem

Subjectivity 

Why the hate

Teams start in Experimental mode / Discovery mode

it's fun / fast / agile and test would slow things down

Write test to make sure we don't break something when we add new feature / refactor

The refacor breaks the tests, we loosing some speed

Spend more time maintaining the tests than the app  

The developers loved phase 1, 2, but they hate phase 3 and the loss of fun / fast / agile and discovery mode is killing the moral

This pattern is so frequent 

Prevention

VS

Cure

Loss of Speed

Large Test Suite = Longer execution time = Longer interation Cycle = Loss of productivity

Writing more Test Code than

Application Code ratio (1Ac / 3Tc)

Result:

Frustration (Client/Dev)

For the client

Our job number one

 

is Shipping

(new feature / application)

 

it's not maintaining our test suite

Maintenance Nightmare

because refactoring breaks the tests

Loss of Agility

Afraid to change things

because refactoring breaks the tests

Result:

Less Refactoring

The fastest way to hell is

No Refactoring 

Smaller but smarter Tests Suites

No / Minimal impact on Refactoring

We are in Heaven

The Right and Wrong

I have a new method in my class I need a test

Wrong

A new method is not a trigger for a new test

 is the trigger for a new test

A new behaviour

Unit Test

What is a Unit in TDD

A single method or a single Class

Wrong

A Unit in TDD is a single application behaviour that can be run in isolation

The Test is isolated not the thing under test

Wisdom

Avoid testing implementation details

Write test against application behaviour

Test the surface,

the public Api, not the implemention 

Don't test the internals

When you test the internals you are coupling 

your test to your implementation and

not the application behaviour

Tight coupling is bad for refactoring

The surface area that you are testing should be smaller than what people are usually testing

The Surface, the Perimeter, the Contract rarely change and is independant from the implementation

The interaction between the public Api(s) is the behaviour that you should be testing

Don't test HOW it works

Test IF it works

Coupling is the biggest problem in Software Development

Coupling will kill you !

May the force be with you

Typical Mistakes

Selinium / webdriver

Connection to DB / Services

The Pyramid is upside-down

There is a lot of Manual Testing

Every change on the UI breaks the Automated Tests

The most important Tests are taking

the smallest area

A Better Testing Model

 

Misconception

The unit test is written by the programmers for the programmers and it's not testing the running application 

Test the behaviour of your Application in the Unit Test

The majority of your Test efforts should be in

Unit Test testing the good behaviour of the Application

Unit Tests frontiers between App Domain & Port 

This is where the usecases, the stories, the senarios are express

This is where the behaviours of the app are express it's

the contract with the world

The communication is bi-directional 

Don't test the Application Domain as it's mutable

Integration Tests frontiers between Ports & Addapters 

They figure out if we are expressing our self correctly to the outside world

If you don't own the adapter or if it's a

3rd party don't test it

System Tests the frontiers between Ports & Outside 

A small number of test checking that everything works together nicely

They confirm that the rest is working

Don't test the implementation it is

Mutable

 To certify that the implementation is correct

Test the Api,

the Perimiters

Methodology 

You can't do 2 things at once

You can't solve the problem

&

Engineer the solution at the same time

Write a failing test

&

make the test pass in the :

fastest / dirtiest 

least engineered way !

Then refactor the solution but...

Don't write test on the new code written

The test is covering the refactoring test

Mocks

don't mock internals or implementation as it would couple your test to your 

implementation through your mocks

Mock your Ports

Mock Public API 

Conclusion

Test the behaviour of your Application in the Unit Tests

Remiders

  • Test new behaviours not new methods on a class
  • Write dirty code to go green and then refactor
  • No new test written for refactored internals
  • Write Unit Test against Ports
  • Write Integration Test against Ports to Adapters
  • Write System Test for E2E confidence
  • Don't mock internals, private or adapters

Do & Don't of TDD

By bretto

Do & Don't of TDD

  • 360