+ All Categories
Home > Technology > Test Driven Development

Test Driven Development

Date post: 10-May-2015
Category:
Upload: dhaval-dalal
View: 3,086 times
Download: 0 times
Share this document with a friend
Popular Tags:
36
Test Driven Development Dhaval Dalal software-artisan.com
Transcript
Page 1: Test Driven Development

Test Driven Development

Dhaval Dalalsoftware-artisan.com

Page 2: Test Driven Development

What TDD is not?TDD

is not about Testing!

TDDis not

Test Lastor

DDT (Design Driven Tests)

Page 3: Test Driven Development

What TDD is?TDDor

Test First is about

evolving the design of the system through Tests.

Page 4: Test Driven Development

2

4

3 2

4

5

TDD Episode

Page 5: Test Driven Development

[TestFixture]

public class OddNumberFilterTest {

[Test]

public void FiltersOutOddNumbers() {

OddNumberFilter filter = new OddNumberFilter();

int [] numbers = new int [] { 3, 4 };

int [] evenNumbers = filter.Filter(numbers);

Assert.That(evenNumbers, Has.Count(1));

Assert.That(evenNumbers, Has.Member(4));

Assert.That(evenNumbers, Has.No.Member(3));

}

} [email protected]

Specify What Software Should Do...

Then

When

Given

Page 6: Test Driven Development

public class OddNumberFilter {

public int [] Filter (params int [] numbers)

{

throw new NotImplementedException();

}

}

[email protected]

Write Just Enough Code To Compile

Page 8: Test Driven Development

public class OddNumberFilter {

public int [] Filter (params int [] numbers)

{

List<int> evenNumbers = new List<int>();

foreach (int number in numbers)

{

if (number % 2 == 0)

{

evenNumbers.Add(number);

}

}

return evenNumbers.ToArray();

}

} [email protected]

Write Enough Code To Pass The Specification...

Page 9: Test Driven Development

Green

[email protected]

Page 10: Test Driven Development

[email protected]

General Test Structure

Setup the Givens(Context in which the Test runs)

Then verify the Assertions(State or Behavior verifications)

Exercise the Whens(Perform the actual operation)

Arrange

Assert

Act

Page 11: Test Driven Development

[TestFixture]

public class NumberFilterTest {

[Test] public void FiltersOddNumbers() {

OddNumberFilter filter = new OddNumberFilter(); int [] numbers = new int [] { 3, 4 };

int [] evenNumbers = filter.Filter(numbers);

Assert.That(evenNumbers, Has.Count(1)); Assert.That(evenNumbers, Has.Member(4)); Assert.That(evenNumbers, Has.No.Member(3));

}

[email protected]

Add New Feature: Filter-out Non-Primes

Page 12: Test Driven Development

[TestFixture]

public class NumberFilterTest {

[Test] public void FiltersOddNumbers() {

OddNumberFilter filter = new OddNumberFilter(); int [] numbers = new int [] { 3, 4 };

int [] evenNumbers = filter.Filter(numbers);

Assert.That(evenNumbers, Has.Count(1)); Assert.That(evenNumbers, Has.Member(4)); Assert.That(evenNumbers, Has.No.Member(3));

}

[Test]

public void FiltersNonPrimes() {

NonPrimesFilter filter = new NonPrimesFilter();

int [] numbers = new int [] { 4, 5 };

int [] primeNumbers = filter.Filter(numbers);

Assert.That(primeNumbers, Has.Count(1));

Assert.That(primeNumbers, Has.Member(5));

Assert.That(primeNumbers, Has.No.Member(4));

}

} [email protected]

Add New Feature: Filter-out Non-Primes

Page 13: Test Driven Development

[TestFixture]

public class NumberFilterTest {

[Test] public void FiltersOddNumbers() {

OddNumberFilter filter = new OddNumberFilter(); int [] numbers = new int [] { 3, 4 };

int [] evenNumbers = filter.Filter(numbers);

Assert.That(evenNumbers, Has.Count(1)); Assert.That(evenNumbers, Has.Member(4)); Assert.That(evenNumbers, Has.No.Member(3));

}

[Test]

public void FiltersNonPrimes() {

NonPrimesFilter filter = new NonPrimesFilter();

int [] numbers = new int [] { 4, 5 };

int [] primeNumbers = filter.Filter(numbers);

Assert.That(primeNumbers, Has.Count(1));

Assert.That(primeNumbers, Has.Member(5));

Assert.That(primeNumbers, Has.No.Member(4));

}

} [email protected]

Add New Feature: Filter-out Non-Primes

Duplicationof Concept

Page 14: Test Driven Development

[TestFixture]

public class NumberFilterTest {

[Test] public void FiltersOddNumbers() {

OddNumberFilter filter = new OddNumberFilter(); int [] numbers = new int [] { 3, 4 };

int [] evenNumbers = filter.Filter(numbers);

Assert.That(evenNumbers, Has.Count(1)); Assert.That(evenNumbers, Has.Member(4)); Assert.That(evenNumbers, Has.No.Member(3));

}

[Test]

public void FiltersNonPrimes() {

NonPrimesFilter filter = new NonPrimesFilter();

int [] numbers = new int [] { 4, 5 };

int [] primeNumbers = filter.Filter(numbers);

Assert.That(primeNumbers, Has.Count(1));

Assert.That(primeNumbers, Has.Member(5));

Assert.That(primeNumbers, Has.No.Member(4));

}

} [email protected]

Add New Feature: Filter-out Non-Primes

Duplicationof Concept

Duplicationof Concept

Page 15: Test Driven Development

Refactor

[email protected]

Page 16: Test Driven Development

public interface IFilter {

int [] filter.Filter(param int [] numbers);

}

[email protected]

Introduce Abstraction

Page 17: Test Driven Development

[TestFixture]

public class NumberFilterTest {

[Test] public void FiltersOutOddNumbers() { IFilter filter = new OddNumberFilter(); int [] numbers = new int [] { 3, 4 };

int [] evenNumbers = filter.Filter(numbers);

Assert.That(evenNumbers, Has.Count(1)); Assert.That(evenNumbers, Has.Member(4)); Assert.That(evenNumbers, Has.No.Member(3));

}

[Test] public void FiltersOutNonPrimes() { IFilter filter = new NonPrimesFilter(); int [] numbers = new int [] { 4, 5 };

int [] primeNumbers = filter.Filter(numbers);

Assert.That(primeNumbers, Has.Count(1)); Assert.That(primeNumbers, Has.Member(5)); Assert.That(primeNumbers, Has.No.Member(4));

}

} [email protected]

Refactored Code

Page 18: Test Driven Development

Red Green

TDD Rhythm

Refactor

Page 19: Test Driven Development

[email protected]

TDD Rhythm Flowchart

Write just enough Code to compile

Refactor CodePass the Test

(GREEN)

Fail the Test(RED)

Write just enough Code to pass the test

Specify whatthe software should do

Pass the Test(GREEN)

Page 20: Test Driven Development

So, TDD is about…

analyzing what little you actually need to do and how cleanly you can do it!

Carving design of your code a unit test at a time.

Page 21: Test Driven Development

[email protected]

Write Tests Before Writing Code

Focuses the mind (and the development process) Deliver only what is absolutely necessary.

System so developed does exactly what it needs to do and no more.

Need not code for future YAGNI (You Ain’t Gonna Need It!)...no gold plating!

Page 22: Test Driven Development

[email protected]

TDD is a Design Technique Makes you think in terms of Object

behavior. How client is going to interact with the object.

Outside-In Object so created is “consumer aware”

What Object provides and needs from environment.

Traditional OOD focuses only on Object’s Implementation

Inside-Out

Page 23: Test Driven Development

[email protected]

TDD results in a Decoupled Design Favors Composition over Inheritance.

Relies on dependency injection for collaborators.

Avoids tight coupling to global objects Singletons mix static and state. Makes design untestable.

Many small, loosely coupled classes.

Makes you think of inter-object interactions in terms of interfaces. Promotes Programming to Super-Types and not

Concretes.

Page 24: Test Driven Development

[email protected]

Benefits of TDD Test-a-little and build-a-little gives

confidence Green bar gives you confidence Reduces fear of change

Documentation Provides starting point to understand code

functionality Safety Net

Checks Regression Supports Refactoring

Page 25: Test Driven Development

[email protected]

Benefits of TDD Effort

Reduces effort to final delivery Writing tests is more productive

Predictable Tells me when am I done Continuous Success Vs Illusive Success

Immediate Feedback Makes failures shine at you

Page 26: Test Driven Development

[email protected]

Costs of TDDClaim: It is too much work to write tests!Rebut: I’d say “are you looking to create a speculative

design?”, “do you want to sleep with a debugger?”

Claim: Tests themselves are code, we need to maintain them, that’s overhead!

Rebut: I’d say “do you prefer maintaining a big bug list?”

Claim: I have to spend time re-orient my thinking!Rebut: I’d say “Just as with any skill, you need to allow some

time to apply this effectively.”

Page 27: Test Driven Development

Writing Good Tests

Page 28: Test Driven Development

[email protected]

Better Test Practices Tests must be Small.

Easy to understand They do not break when other parts of the code are

changed. One behavioral-assert per test.

Tests must be Expressive. Test code should communicate its intent. It should not take more than 2 minutes for readers to

understand what is going on.

Tests must be Maintainable. When a test breaks, what it contains should be easiest

to fix.

Page 29: Test Driven Development

[email protected]

Better Test Practices Tests must execute Fast.

Slow running tests increase Build Viscosity.

Tests are Specifications, not Verifications. Do not verify whether the code does what its supposed

to do correctly. Specify what should the code do to function correctly.

Tests should talk the Domain Language. Communicate the behavior under test and not how the

system implements that behavior. Improves Communication with Non-Technical Members

on the team. Developers can understand domain faster.

Page 30: Test Driven Development

[email protected]

Better Test Practices Tests must run at will.

Able to write and execute tests without worrying about how to execute them.

Tests must be Isolated Very little set-up and minimum collaborators.

Tests must be Thorough Test all behavior, not methods.

Page 31: Test Driven Development

[email protected]

Better Test Practices Tests must be Automated.

Write them such that methods on objects are invoked by code rather than by hand.

Tests must be Self-Verifiable. Setup test expectations and compare outcome with

expectations for verdicts.

Tests must be Repeatable. Executing the same test several times under the same

conditions must yield same results.

Page 32: Test Driven Development

[email protected]

JUnit/NUnit Better Test Practices Test anything that could possibly break. Make testing exceptional scenarios easy to read. Always explain failure reason in Assert calls. Test should usually improve the design of the

code. For JUnit Tests

Make Test code reside in same packages, but different directories.

For NUnit Tests Make Test code reside in separate project from

source project, in same namespace.

Page 33: Test Driven Development

[email protected]

Flavors of Tests Object Tests (Unit or Programmer Tests)

Tests behavior of single object at a time.

Integration Tests Tests collaboration of a number of objects (how they talk

to each other) Complex fixtures More brittle

End-to-End Tests Thoroughly test the entire system from end-to-end.

Page 34: Test Driven Development

[email protected]

Unit Testing Frameworks xUnit framework for Unit Testing

JUnit/TestNG for Java NUnit/MbUnit for C# cppUnit for C++ pyUnit for Python …and tons of more Unit Testing frameworks.

Page 35: Test Driven Development

Thank you

[email protected]

Page 36: Test Driven Development

[email protected]

References JUnit Recipes

J. B. Rainsberger

JUnit In Action Vincent Massol

Agile Java Jeff Langr

Test-Driven Development Rhythm Gunjan Doshi

Agile Principles, Patterns, and Practices in C# Robert C. Martin, Micah Martin

xUnit Test Patterns Gerard Meszaros

On TDD (InfoQ): How Do We Know When We’re Done?

Steve Freeman

10-Ways-to-Better-Code (InfoQ) Neal Ford

Refactoring Away Duplicated Logic Creates a Domain Specific Embedded Language for Testing

Nat Pryce

Jay Field’s Blog Entry http://blog.jayfields.com/

2007/06/testing-inline-setup.html


Recommended