Under Test TDD Techniques from the Trenches May

  • Slides: 51
Download presentation
Under Test TDD Techniques from the Trenches May 24, 2011 Matt Thurston

Under Test TDD Techniques from the Trenches May 24, 2011 Matt Thurston

Agenda TDD Legacy Code Pitfalls Benefits Techniques

Agenda TDD Legacy Code Pitfalls Benefits Techniques

TDD Legacy Code Pitfalls Benefits Techniques

TDD Legacy Code Pitfalls Benefits Techniques

Rediscovery

Rediscovery

Nutshell Failing Test Refactor Passing Test

Nutshell Failing Test Refactor Passing Test

Why get code ‘Under Test’?

Why get code ‘Under Test’?

Cost of Change

Cost of Change

Change Simple Code Change (“Hack”) versus Tough Design Change (“Right Thing”)

Change Simple Code Change (“Hack”) versus Tough Design Change (“Right Thing”)

Technical Debt

Technical Debt

Motivator

Motivator

TDD Legacy Code Pitfalls Benefits Techniques

TDD Legacy Code Pitfalls Benefits Techniques

What is Legacy Code? • • Inherited? Old version? Previous platform? ‘C’?

What is Legacy Code? • • Inherited? Old version? Previous platform? ‘C’?

Legacy Code = Code Without Tests

Legacy Code = Code Without Tests

Confident Change • Changing legacy code – What will break? – Will we find

Confident Change • Changing legacy code – What will break? – Will we find the break?

Under Test • TDD Greenfields vs Legacy Code Retrofits

Under Test • TDD Greenfields vs Legacy Code Retrofits

TDD Legacy Code Pitfalls Benefits Techniques

TDD Legacy Code Pitfalls Benefits Techniques

Defining ‘Unit Test’ • Our Unit is the C++ class • Unit Tests in

Defining ‘Unit Test’ • Our Unit is the C++ class • Unit Tests in C++

Issue #1 • TDD requires immediate feedback

Issue #1 • TDD requires immediate feedback

What should CTRL + B do? • Build and test as much as possible

What should CTRL + B do? • Build and test as much as possible within a few seconds.

Deployment Fidelity Development Test Deployment Production Deployment

Deployment Fidelity Development Test Deployment Production Deployment

Deployment Fidelity • Deployment Fidelity typically dictates Test Fidelity

Deployment Fidelity • Deployment Fidelity typically dictates Test Fidelity

Test Fidelity Unit Integration System

Test Fidelity Unit Integration System

Test Fidelity Unit Integration System (Seconds) (Minutes) (Hours)

Test Fidelity Unit Integration System (Seconds) (Minutes) (Hours)

Introduce New Fidelity? • TDD requires immediate feedback • If necessary, introduce a new

Introduce New Fidelity? • TDD requires immediate feedback • If necessary, introduce a new fidelity

Issue #2 • ‘Random’ test failures

Issue #2 • ‘Random’ test failures

Dependency Inversion • E. g. – Foo uses files to store configuration information –

Dependency Inversion • E. g. – Foo uses files to store configuration information – Instead, inject Foo. Configuration with • Virtual bool Foo. Configuration: : is. Enabled() = 0;

Dependency Inversion • Big Benefits: – Improves isolation – Simplifies reasoning about collaborations

Dependency Inversion • Big Benefits: – Improves isolation – Simplifies reasoning about collaborations

Issue #3 • Difficult component

Issue #3 • Difficult component

Difficult Components • • • Lack of modularity Lots of dependencies Lack of coherent

Difficult Components • • • Lack of modularity Lots of dependencies Lack of coherent design Full of bugs Etc.

Integration Test First • Works well for Difficult Components • Provides confidence when re-factoring

Integration Test First • Works well for Difficult Components • Provides confidence when re-factoring for unit testability

Issue #4 • Getting inherited legacy code under test

Issue #4 • Getting inherited legacy code under test

Characterization Tests Failing Test Passing Test Capture Output

Characterization Tests Failing Test Passing Test Capture Output

Characterization Tests • Capture reality not expected behavior • The first test is the

Characterization Tests • Capture reality not expected behavior • The first test is the hardest

Failing a Unit Test • If a unit test has never failed once, how

Failing a Unit Test • If a unit test has never failed once, how do you know it works?

Mutation Testing

Mutation Testing

Mutation Testing Passing Test Unmutate Mutate Failing Test

Mutation Testing Passing Test Unmutate Mutate Failing Test

TDD Legacy Code Pitfalls Benefits Techniques

TDD Legacy Code Pitfalls Benefits Techniques

Semantic Memory Input ‘A’ Output ‘B’

Semantic Memory Input ‘A’ Output ‘B’

Tests are never wrong • Tests encode semantics of the software – (even if

Tests are never wrong • Tests encode semantics of the software – (even if the sematic is wrong)

Comment on comments • “When the code and the comments disagree, both are probably

Comment on comments • “When the code and the comments disagree, both are probably wrong. ” – Norm Schryer

Under Test vs. Coding Speed

Under Test vs. Coding Speed

Dreaming of Code

Dreaming of Code

TDD Legacy Code Pitfalls Benefits Techniques

TDD Legacy Code Pitfalls Benefits Techniques

Continuous Testing • Share tests • Don’t let test code rot – Integrate with

Continuous Testing • Share tests • Don’t let test code rot – Integrate with build / CI tool

Mocks, Stubs, Fakes • Take care with terminology overloading

Mocks, Stubs, Fakes • Take care with terminology overloading

Mocks, Stubs, Fakes • Take care with terminology overloading • Mock: – Object used

Mocks, Stubs, Fakes • Take care with terminology overloading • Mock: – Object used to mock collaborator behavior in a unit test • Stub: – Satisfies linkage from a collaborator, provides no implementation (e. g. asserts) • Fake: – Implements a collaborator’s functionality in a synthetic fashion

Not Just the Tests • Code coverage • Static analysis (e. g. Lint, -Wall)

Not Just the Tests • Code coverage • Static analysis (e. g. Lint, -Wall) • Dynamic analysis (e. g. valgrind)

Quality? • TDD / Unit Testing does not imply Quality

Quality? • TDD / Unit Testing does not imply Quality

Questions? Comments? TDD Legacy Code Pitfalls Benefits Techniques

Questions? Comments? TDD Legacy Code Pitfalls Benefits Techniques