Test Driven Development
Upcoming SlideShare
Loading in...5
×
 

Test Driven Development

on

  • 4,258 views

 

Statistics

Views

Total Views
4,258
Slideshare-icon Views on SlideShare
4,034
Embed Views
224

Actions

Likes
4
Downloads
158
Comments
0

9 Embeds 224

http://www.jroller.com 117
http://7feeds.com 47
http://www.linkedin.com 26
http://jroller.com 14
http://ww.jroller.com 10
https://www.linkedin.com 7
http://static.slideshare.net 1
http://www.slideshare.net 1
http://www.techgig.com 1
More...

Accessibility

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Test Driven Development Test Driven Development Presentation Transcript

    • Test Driven Development Dhaval Dalal software-artisan.com
    • What TDD is not? TDD TDD is not is not about Testing! Test Last or DDT (Design Driven Tests)
    • What TDD is? TDD or Test First is about evolving the design of the system through Tests.
    • TDD Episode 5 3 2 4 4 2
    • Specify What Software Should Do... [TestFixture] public class OddNumberFilterTest { [Test] Given public void FiltersOutOddNumbers() { OddNumberFilter filter = new OddNumberFilter(); int [] numbers = new int [] { 3, 4 }; When int [] evenNumbers = filter.Filter(numbers); Then Assert.That(evenNumbers, Has.Count(1)); Assert.That(evenNumbers, Has.Member(4)); Assert.That(evenNumbers, Has.No.Member(3)); } } dhaval.dalal@software-artisan.com
    • Write Just Enough Code To Compile public class OddNumberFilter { public int [] Filter (params int [] numbers) { throw new NotImplementedException(); } } dhaval.dalal@software-artisan.com
    • Red dhaval.dalal@software-artisan.com
    • Write Enough Code To Pass The Specification... 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(); } } dhaval.dalal@software-artisan.com
    • Green dhaval.dalal@software-artisan.com
    • General Test Structure Arrange Setup the Givens (Context in which the Test runs) Act Exercise the Whens (Perform the actual operation) Assert Then verify the Assertions (State or Behavior verifications) dhaval.dalal@software-artisan.com
    • Add New Feature: Filter-out Non-Primes [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)); } dhaval.dalal@software-artisan.com
    • Add New Feature: Filter-out Non-Primes [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)); } } dhaval.dalal@software-artisan.com
    • Add New Feature: Filter-out Non-Primes [TestFixture] public class NumberFilterTest { [Test] public void FiltersOddNumbers() { Duplication OddNumberFilter filter = new OddNumberFilter(); of Concept 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)); } } dhaval.dalal@software-artisan.com
    • Add New Feature: Filter-out Non-Primes [TestFixture] public class NumberFilterTest { [Test] public void FiltersOddNumbers() { Duplication OddNumberFilter filter = new OddNumberFilter(); of Concept 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(); Duplication int [] numbers = new int [] { 4, 5 }; of Concept int [] primeNumbers = filter.Filter(numbers); Assert.That(primeNumbers, Has.Count(1)); Assert.That(primeNumbers, Has.Member(5)); Assert.That(primeNumbers, Has.No.Member(4)); } } dhaval.dalal@software-artisan.com
    • Refactor dhaval.dalal@software-artisan.com
    • Introduce Abstraction public interface IFilter { int [] filter.Filter(param int [] numbers); } dhaval.dalal@software-artisan.com
    • Refactored Code [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)); } } dhaval.dalal@software-artisan.com
    • TDD Rhythm Red Green Refactor
    • TDD Rhythm Flowchart Specify what Write just enough Fail the Test the software Code to compile (RED) should do Pass the Test (GREEN) Pass the Test Write just enough Refactor Code (GREEN) Code to pass the test dhaval.dalal@software-artisan.com
    • 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.
    • 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! dhaval.dalal@software-artisan.com
    • 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 dhaval.dalal@software-artisan.com
    • 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. dhaval.dalal@software-artisan.com
    • 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 dhaval.dalal@software-artisan.com
    • 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 dhaval.dalal@software-artisan.com
    • Costs of TDD Claim: 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.” dhaval.dalal@software-artisan.com
    • Writing Good Tests
    • 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. dhaval.dalal@software-artisan.com
    • 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. dhaval.dalal@software-artisan.com
    • 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. dhaval.dalal@software-artisan.com
    • 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. dhaval.dalal@software-artisan.com
    • 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. dhaval.dalal@software-artisan.com
    • 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. dhaval.dalal@software-artisan.com
    • 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. dhaval.dalal@software-artisan.com
    • Thank you dhaval.dalal@software-artisan.com software-artisan.com
    • References  JUnit Recipes  On TDD (InfoQ): How Do We  J. B. Rainsberger Know When We’re Done?  Steve Freeman  JUnit In Action  Vincent Massol  10-Ways-to-Better-Code (InfoQ)  Neal Ford  Agile Java  Jeff Langr  Refactoring Away Duplicated Logic Creates a Domain Specific Embedded Language for Testing  Test-Driven Development Rhythm  Nat Pryce  Gunjan Doshi  Jay Field’s Blog Entry  Agile Principles, Patterns, and  http://blog.jayfields.com/ Practices in C# 2007/06/testing-inline-setup.html  Robert C. Martin, Micah Martin  xUnit Test Patterns  Gerard Meszaros dhaval.dalal@software-artisan.com