SlideShare a Scribd company logo
Test Driven Development
INFO-6067
Test Driven Development
• “Only ever write code to fix a failing test.” That’s test-driven
development, or TDD, in one sentence.
• First - write a test,
• Then write code to make the test pass.
• Then design relying on the existing tests to keep from breaking things
while coding.
The Challenge
• Even after decades of advancements in the software industry, the
quality of software remains a problem
• There are two sides to quality problems:
• high defect rates
• lack of maintainability.
• Defects create unwanted costs by making the system unstable,
unpredictable, or potentially completely unusable.
• They reduce the value of software —sometimes to the point of creating
more damage than value.
Test Driven Development
The Challenge
• Well-written code exhibits good design and a balanced division of
responsibilities without duplication.
• Poorly written code doesn’t, and working with it is a nightmare in
many aspects:
• the code can be difficult to understand
• difficult to change.
• changing problematic code tends to break functionality elsewhere in the
system,
• duplication causes issues in the form of bugs that were supposed to be fixed
already.
The Challenge
• Testing has been established as a critical ingredient in software
development, but the way testing is traditionally performed— a
lengthy testing phase after the code is “frozen”—leaves much room
for improvement.
• The cost of fixing defects that get caught during testing is typically a
magnitude or two higher than if caught as they were introduced into
the code base.
Test Driven Development
TDD
• Test-code-refactor is the mantra test-driven developers like to chant.
• It describes succinctly what takes place
Solution
• Build the thing right.
• Build the right thing.
• Using Test Driven development and Acceptance TDD.
• On a lower level, we test-drive code using the technique called TDD.
• On a higher level—that of features and functionality— test-drive the system
using a similar technique called acceptance TDD
Test Driven
TDD is a technique for improving the software’s internal quality, whereas
acceptance TDD helps keep the product’s external quality on track by
giving it the correct features and functionality.
In Practice
• Traditionally we’ve always designed first, then implemented the
design, and then tested the implementation
• TDD turns this thinking around and says we should write the test first
and only then write code to reach that clear goal.
• Design is what we do last. We look at the code we have and find the
simplest design possible.
• The last step in the cycle is called refactoring.
Quality
• People tend to associate the word quality with the number of defects
found after using the software.
• Some consider quality to be other things such as the degree to which
the software fulfills its users’ needs and expectations.
• Some consider not just the externally visible quality but also the internal
qualities of the software in question (which translate to external
qualities like the cost of development, maintenance, and so forth).
• TDD contributes to improved quality in all of these aspects with its
design-guiding and quality-oriented nature.
Quality TDD
• TDD makes sure that there’s practically no code in the system that is
not required—and therefore executed—by the tests.
• Through extensive test coverage and having all of these tests
automated, TDD guarantees that whatever you have written a test for
works, and the quality (in terms of defects) becomes more of a
function of how well we succeed in coming up with the right test
cases.
• to build the thing right —with TDD
Quality ATDD
• With acceptance TDD, we’re just talking about tests for the behavior
of a system rather than tests for the behavior of objects. This means
that we need to speak a language that both the programmer and the
customer understand.
• Development on a higher level to help us meet our customers’
needs—to build the right thing—with acceptance TDD
Test Driven Development
Test Driven Development
Test Driven Development
Test Driven Development
Test Driven Development
Writing Tests
Test Driven Development
Refactoring
Refactoring
• Refactoring is a disciplined way of transforming code from one state
or structure to another, removing duplication, and gradually moving
the code toward the best design we can imagine.
• By constantly refactoring, we can grow our code base and evolve our
design incrementally.
TDD
Writing Tests
Programming by Intention
• When writing tests before the production code they’re
supposed to test, we face a dilemma: how to test something
that doesn’t exist without breaking our test-first rule. The
answer is as simple —imagine the code you’re testing exists!
• What are we supposed to imagine? We imagine the ideal shape
and form of the production code from this particular test’s
point of view.
• By writing our tests with the assumption that the production
code is as easy to use as we can imagine, we’re making it easy
to write the tests and we’re making sure that our production
code will become as easy to use as we are able to imagine.
• It has to, because our tests won’t pass otherwise.
• This is programming by intention.
Program by Intention
• The concept of writing code as if another piece of code exists—even
if it doesn’t—is a technique that makes us focus on what we could
have instead of working around what we have.
• Programming by intention tends to lead to code that flows better,
code that’s easier to understand and use—code that expresses what
it does and why, instead of how it does it.
Write the Code
• Write just enough code to make the test pass.
• Why just enough code? The test we’ve written is a test that’s failing.
It’s pointing out a gap between what the code does and what we
expect it to do. It’s a small gap, which we should be able to close in a
few minutes which, in turn, means that the code is never broken for
long.
Write the Code
• One of the fundamental ideas behind the concept of test-first
development is to let the tests show you what to implement in order
to make progress on developing the software.
• You code to satisfy an explicit, unambiguous requirement expressed
by a test.
• You’re making progress, and you’ve got a passing test to show for it.
Refactor
• Our main goal is to make the test pass as quickly as possible. That
often means an implementation that’s not optimal.
• We’ll take care of a sub-optimal design after we have the desired
behavior in place—and tests to prove it.
• With the tests as our safety net, we can then proceed to improving
the design in the last step of the TDD cycle: refactoring.
Refactor
• We take a step back, look at our design, and figure out ways of
making it better. The refactoring step is what makes TDD sustainable.
• Sustainable:
• able to be maintained at a certain rate or level.
Requirements to Tests
• How would tests drive the development of the system?
• Decompose the requirements
• slicing the requirements into a set of tests that, when passing, lead to the
requirements being satisfied.
• Translating requirements into tests is far superior to merely
decomposing requirements into tasks because tasks make it easy to
lose sight of the ultimate goal—the satisfied requirement.
• Tasks only give us an idea of what we should do.
A good Test
• A good test is atomic
• tests a small, focused, atomic slice of the desired behavior
• A good test is isolated
• test should be isolated from other tests so that, the test assumes nothing
about any previously executed tests.
• Remember F.I.R.S.T. ?
• Fast
• Isolated/independent
• Repeatable
• Self-validating
• Thorough/Timely
Run the failing test
• When we run our freshly written test, it fails—not surprisingly,
because none of the methods we added are doing anything.
• A failing test is progress.
• What we have now is a test that tells us when we’re done with that
particular task. Not a moment too soon, not a moment too late. It
won’t try to tell us something like “you’re 90% done” or “just five
more minutes.” We’ll know when the test passes; that is, when the
code does what we expect it to do.
Failing test
• Running the test, we get the output complaining about getting a null
when it expected the string “Hello, Reader”.
• We’re in the red phase of the TDD cycle, which means that we have
written and executed a test that is failing
• We’ve now written a test, programming by intention, and we have a
skeleton of the production code that our test is testing.
• At this point, all that’s left is to implement the Template class so that
our test passes and we can rest our eyes on a green progress bar.
Red Phase
Make our test pass.
• We don’t have much code yet, but we’ve already made a number of
significant design decisions. We’ve decided that there should be a
class Template that loads a template text given as an argument to the
constructor
• We can set a value for a named placeholder, and it can evaluate itself,
producing the wanted output.
• What’s next?
• We had already written the skeleton for the Template class so that
our test compiles.
Make it pass
• All the constructors and methods are in place to make the compiler
happy, but none of those constructors and methods is doing anything
so far.
• We want to make the test pass in the easiest, quickest way possible.
To put it another way, we’re now facing a red bar, meaning the code
in our workspace is currently in an unstable state.
• We want to get out of that state and into stable ground as quickly as
possible.
How to make it pass simply?
• How do we make the test pass as quickly and easily as possible?
• Evaluating a template that simple, “Hello, ${name}”, with a string-
replace operation would be a matter of a few minutes of work,
probably.
• There’s another implementation, however, of the functionality
implied by our failing test that fits our goal of “as quickly as possible”
a bit better.
First try
public class Template
{
public Template(String templateText) {
}
public void set(String variable, String value) {
}
public String evaluate()
{
return "Hello, Reader";
}
}
Not optimum
• Hard-coding the evaluate method to return “Hello, Reader” is most
certainly the quickest and easiest way to make the test pass.
Although it may not make much sense at first.
• We want to squeeze out the wanted behavior with our tests. In this
case, we’re making use of neither the actual variable nor the
template.
• And that means we know at least two dimensions on which to push
our code toward a proper implementation.
• Let’s extend our test to squeeze out the implementation we’re
looking for.
Second try
public class TestTemplate
{
@Test
public void oneVariable() throws Exception {
Template template = new Template("Hello, ${name}");
template.set("name", "Reader");
assertEquals("Hello, Reader", template.evaluate());
}
@Test
public void differentValue() throws Exception {
Template template = new Template("Hello, ${name}");
template.set("name", "someone else");
assertEquals("Hello, someone else", template.evaluate());
}
}
Triangulate
• We’ve added a second call to set—with different input—and a second
assertion to verify that the Template object will re-evaluate the template
with the latest value for the “name” variable.
• Our hard-coded evaluate method in the Template class will surely no
longer pass this test, which was our goal.
• This technique is named triangulation, referring to how we’re using
multiple bearings to pinpoint the design toward the proper
implementation.
• Now, how could we make this enhanced test pass?
Another pass
public class Template
{
private String variableValue;
public Template(String templateText) {
}
public void set(String variable, String value) {
this.variableValue = value;
}
public String evaluate() {
return "Hello, " + variableValue;
}
}
Are we refactoring?
• Our test passes again with minimal effort.
• Obviously our test isn’t good enough yet, because we’ve got that
hard-coded part in there, so let’s continue triangulating to push out
the last bits of literal strings from our code.
• The next shows how we alter our test to drive out not just the hard-
coding of the variable value but also the template text around the
variable.
Closer?
public class TestTemplate {
@Test
public void oneVariable() throws Exception {
Template template = new Template("Hello, ${name}");
template.set("name", "Reader");
assertEquals("Hello, Reader", template.evaluate());
}
@Test
public void differentTemplate() throws Exception {
Template template = new Template("Hi, ${name}");
template.set("name", "someone else");
assertEquals("Hi, someone else", template.evaluate());
}}
Red result
• Red bar. Obviously the hard-coded return statement doesn’t cut it
anymore. At this point, we’re facing the task of parsing the template
text somehow.
• Perhaps we should first implement the parsing logic and then come
back to this test.
• Time to discuss breadth and depth.

More Related Content

Similar to {10.0} Test Driven Development.pptx

Tdd
TddTdd
Tdd and bdd
Tdd and bddTdd and bdd
Tdd and bdd
MohamedSubhiBouchi
 
TDD in Agile
TDD in AgileTDD in Agile
TDD in Agile
Atish Narlawar
 
Introduction to Automated Testing
Introduction to Automated TestingIntroduction to Automated Testing
Introduction to Automated Testing
Lars Thorup
 
Introduction to-automated-testing
Introduction to-automated-testingIntroduction to-automated-testing
Introduction to-automated-testingBestBrains
 
Test driven developement
Test driven developementTest driven developement
Test driven developementBhavik Panchal
 
Quality metrics and angular js applications
Quality metrics and angular js applicationsQuality metrics and angular js applications
Quality metrics and angular js applicationsnadeembtech
 
Software Testing Basic Concepts
Software Testing Basic ConceptsSoftware Testing Basic Concepts
Software Testing Basic Concepts
wesovi
 
Becoming a better programmer - unit testing
Becoming a better programmer - unit testingBecoming a better programmer - unit testing
Becoming a better programmer - unit testingDuy Tan Geek
 
Test driven development
Test driven developmentTest driven development
Test driven development
Harry Potter
 
Test driven development
Test driven developmentTest driven development
Test driven development
Luis Goldster
 
Test driven development
Test driven developmentTest driven development
Test driven development
Tony Nguyen
 
Test driven development
Test driven developmentTest driven development
Test driven development
Young Alista
 
Test driven development
Test driven developmentTest driven development
Test driven development
James Wong
 
Test driven development
Test driven developmentTest driven development
Test driven development
Fraboni Ec
 
Tdd
TddTdd
Driving application development through behavior driven development
Driving application development through behavior driven developmentDriving application development through behavior driven development
Driving application development through behavior driven developmentEinar Ingebrigtsen
 
Tdd
TddTdd

Similar to {10.0} Test Driven Development.pptx (20)

Tdd
TddTdd
Tdd
 
Tdd and bdd
Tdd and bddTdd and bdd
Tdd and bdd
 
TDD in Agile
TDD in AgileTDD in Agile
TDD in Agile
 
Introduction to Automated Testing
Introduction to Automated TestingIntroduction to Automated Testing
Introduction to Automated Testing
 
Introduction to-automated-testing
Introduction to-automated-testingIntroduction to-automated-testing
Introduction to-automated-testing
 
Test driven developement
Test driven developementTest driven developement
Test driven developement
 
Quality metrics and angular js applications
Quality metrics and angular js applicationsQuality metrics and angular js applications
Quality metrics and angular js applications
 
Software Testing Basic Concepts
Software Testing Basic ConceptsSoftware Testing Basic Concepts
Software Testing Basic Concepts
 
Becoming a better programmer - unit testing
Becoming a better programmer - unit testingBecoming a better programmer - unit testing
Becoming a better programmer - unit testing
 
Test driven development
Test driven developmentTest driven development
Test driven development
 
Test driven development
Test driven developmentTest driven development
Test driven development
 
Test driven development
Test driven developmentTest driven development
Test driven development
 
Test driven development
Test driven developmentTest driven development
Test driven development
 
Test driven development
Test driven developmentTest driven development
Test driven development
 
Test driven development
Test driven developmentTest driven development
Test driven development
 
Tdd
TddTdd
Tdd
 
Driving application development through behavior driven development
Driving application development through behavior driven developmentDriving application development through behavior driven development
Driving application development through behavior driven development
 
Tdd
TddTdd
Tdd
 
TDD and PhoneGap
TDD and PhoneGapTDD and PhoneGap
TDD and PhoneGap
 
Test first!
Test first!Test first!
Test first!
 

Recently uploaded

Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
WSO2
 
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisProviding Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Globus
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FME
Jelle | Nordend
 
Designing for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesDesigning for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web Services
KrzysztofKkol1
 
Advanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should KnowAdvanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should Know
Peter Caitens
 
Why React Native as a Strategic Advantage for Startup Innovation.pdf
Why React Native as a Strategic Advantage for Startup Innovation.pdfWhy React Native as a Strategic Advantage for Startup Innovation.pdf
Why React Native as a Strategic Advantage for Startup Innovation.pdf
ayushiqss
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
Cyanic lab
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
Ortus Solutions, Corp
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
Georgi Kodinov
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New Zealand
IES VE
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Globus
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
AMB-Review
 
Strategies for Successful Data Migration Tools.pptx
Strategies for Successful Data Migration Tools.pptxStrategies for Successful Data Migration Tools.pptx
Strategies for Successful Data Migration Tools.pptx
varshanayak241
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
takuyayamamoto1800
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
Juraj Vysvader
 
Software Testing Exam imp Ques Notes.pdf
Software Testing Exam imp Ques Notes.pdfSoftware Testing Exam imp Ques Notes.pdf
Software Testing Exam imp Ques Notes.pdf
MayankTawar1
 
Understanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSageUnderstanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSage
Globus
 

Recently uploaded (20)

Accelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with PlatformlessAccelerate Enterprise Software Engineering with Platformless
Accelerate Enterprise Software Engineering with Platformless
 
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data AnalysisProviding Globus Services to Users of JASMIN for Environmental Data Analysis
Providing Globus Services to Users of JASMIN for Environmental Data Analysis
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
 
De mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FMEDe mooiste recreatieve routes ontdekken met RouteYou en FME
De mooiste recreatieve routes ontdekken met RouteYou en FME
 
Designing for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web ServicesDesigning for Privacy in Amazon Web Services
Designing for Privacy in Amazon Web Services
 
Advanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should KnowAdvanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should Know
 
Why React Native as a Strategic Advantage for Startup Innovation.pdf
Why React Native as a Strategic Advantage for Startup Innovation.pdfWhy React Native as a Strategic Advantage for Startup Innovation.pdf
Why React Native as a Strategic Advantage for Startup Innovation.pdf
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New Zealand
 
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
Exploring Innovations in Data Repository Solutions - Insights from the U.S. G...
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
 
Strategies for Successful Data Migration Tools.pptx
Strategies for Successful Data Migration Tools.pptxStrategies for Successful Data Migration Tools.pptx
Strategies for Successful Data Migration Tools.pptx
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
 
Software Testing Exam imp Ques Notes.pdf
Software Testing Exam imp Ques Notes.pdfSoftware Testing Exam imp Ques Notes.pdf
Software Testing Exam imp Ques Notes.pdf
 
Understanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSageUnderstanding Globus Data Transfers with NetSage
Understanding Globus Data Transfers with NetSage
 

{10.0} Test Driven Development.pptx

  • 2. Test Driven Development • “Only ever write code to fix a failing test.” That’s test-driven development, or TDD, in one sentence. • First - write a test, • Then write code to make the test pass. • Then design relying on the existing tests to keep from breaking things while coding.
  • 3. The Challenge • Even after decades of advancements in the software industry, the quality of software remains a problem • There are two sides to quality problems: • high defect rates • lack of maintainability. • Defects create unwanted costs by making the system unstable, unpredictable, or potentially completely unusable. • They reduce the value of software —sometimes to the point of creating more damage than value.
  • 5. The Challenge • Well-written code exhibits good design and a balanced division of responsibilities without duplication. • Poorly written code doesn’t, and working with it is a nightmare in many aspects: • the code can be difficult to understand • difficult to change. • changing problematic code tends to break functionality elsewhere in the system, • duplication causes issues in the form of bugs that were supposed to be fixed already.
  • 6. The Challenge • Testing has been established as a critical ingredient in software development, but the way testing is traditionally performed— a lengthy testing phase after the code is “frozen”—leaves much room for improvement. • The cost of fixing defects that get caught during testing is typically a magnitude or two higher than if caught as they were introduced into the code base.
  • 8. TDD • Test-code-refactor is the mantra test-driven developers like to chant. • It describes succinctly what takes place
  • 9. Solution • Build the thing right. • Build the right thing. • Using Test Driven development and Acceptance TDD. • On a lower level, we test-drive code using the technique called TDD. • On a higher level—that of features and functionality— test-drive the system using a similar technique called acceptance TDD
  • 10. Test Driven TDD is a technique for improving the software’s internal quality, whereas acceptance TDD helps keep the product’s external quality on track by giving it the correct features and functionality.
  • 11. In Practice • Traditionally we’ve always designed first, then implemented the design, and then tested the implementation • TDD turns this thinking around and says we should write the test first and only then write code to reach that clear goal. • Design is what we do last. We look at the code we have and find the simplest design possible. • The last step in the cycle is called refactoring.
  • 12. Quality • People tend to associate the word quality with the number of defects found after using the software. • Some consider quality to be other things such as the degree to which the software fulfills its users’ needs and expectations. • Some consider not just the externally visible quality but also the internal qualities of the software in question (which translate to external qualities like the cost of development, maintenance, and so forth). • TDD contributes to improved quality in all of these aspects with its design-guiding and quality-oriented nature.
  • 13. Quality TDD • TDD makes sure that there’s practically no code in the system that is not required—and therefore executed—by the tests. • Through extensive test coverage and having all of these tests automated, TDD guarantees that whatever you have written a test for works, and the quality (in terms of defects) becomes more of a function of how well we succeed in coming up with the right test cases. • to build the thing right —with TDD
  • 14. Quality ATDD • With acceptance TDD, we’re just talking about tests for the behavior of a system rather than tests for the behavior of objects. This means that we need to speak a language that both the programmer and the customer understand. • Development on a higher level to help us meet our customers’ needs—to build the right thing—with acceptance TDD
  • 23. Refactoring • Refactoring is a disciplined way of transforming code from one state or structure to another, removing duplication, and gradually moving the code toward the best design we can imagine. • By constantly refactoring, we can grow our code base and evolve our design incrementally.
  • 25. Programming by Intention • When writing tests before the production code they’re supposed to test, we face a dilemma: how to test something that doesn’t exist without breaking our test-first rule. The answer is as simple —imagine the code you’re testing exists! • What are we supposed to imagine? We imagine the ideal shape and form of the production code from this particular test’s point of view. • By writing our tests with the assumption that the production code is as easy to use as we can imagine, we’re making it easy to write the tests and we’re making sure that our production code will become as easy to use as we are able to imagine. • It has to, because our tests won’t pass otherwise. • This is programming by intention.
  • 26. Program by Intention • The concept of writing code as if another piece of code exists—even if it doesn’t—is a technique that makes us focus on what we could have instead of working around what we have. • Programming by intention tends to lead to code that flows better, code that’s easier to understand and use—code that expresses what it does and why, instead of how it does it.
  • 27. Write the Code • Write just enough code to make the test pass. • Why just enough code? The test we’ve written is a test that’s failing. It’s pointing out a gap between what the code does and what we expect it to do. It’s a small gap, which we should be able to close in a few minutes which, in turn, means that the code is never broken for long.
  • 28. Write the Code • One of the fundamental ideas behind the concept of test-first development is to let the tests show you what to implement in order to make progress on developing the software. • You code to satisfy an explicit, unambiguous requirement expressed by a test. • You’re making progress, and you’ve got a passing test to show for it.
  • 29. Refactor • Our main goal is to make the test pass as quickly as possible. That often means an implementation that’s not optimal. • We’ll take care of a sub-optimal design after we have the desired behavior in place—and tests to prove it. • With the tests as our safety net, we can then proceed to improving the design in the last step of the TDD cycle: refactoring.
  • 30. Refactor • We take a step back, look at our design, and figure out ways of making it better. The refactoring step is what makes TDD sustainable. • Sustainable: • able to be maintained at a certain rate or level.
  • 31. Requirements to Tests • How would tests drive the development of the system? • Decompose the requirements • slicing the requirements into a set of tests that, when passing, lead to the requirements being satisfied. • Translating requirements into tests is far superior to merely decomposing requirements into tasks because tasks make it easy to lose sight of the ultimate goal—the satisfied requirement. • Tasks only give us an idea of what we should do.
  • 32. A good Test • A good test is atomic • tests a small, focused, atomic slice of the desired behavior • A good test is isolated • test should be isolated from other tests so that, the test assumes nothing about any previously executed tests. • Remember F.I.R.S.T. ? • Fast • Isolated/independent • Repeatable • Self-validating • Thorough/Timely
  • 33. Run the failing test • When we run our freshly written test, it fails—not surprisingly, because none of the methods we added are doing anything. • A failing test is progress. • What we have now is a test that tells us when we’re done with that particular task. Not a moment too soon, not a moment too late. It won’t try to tell us something like “you’re 90% done” or “just five more minutes.” We’ll know when the test passes; that is, when the code does what we expect it to do.
  • 34. Failing test • Running the test, we get the output complaining about getting a null when it expected the string “Hello, Reader”. • We’re in the red phase of the TDD cycle, which means that we have written and executed a test that is failing • We’ve now written a test, programming by intention, and we have a skeleton of the production code that our test is testing. • At this point, all that’s left is to implement the Template class so that our test passes and we can rest our eyes on a green progress bar.
  • 36. Make our test pass. • We don’t have much code yet, but we’ve already made a number of significant design decisions. We’ve decided that there should be a class Template that loads a template text given as an argument to the constructor • We can set a value for a named placeholder, and it can evaluate itself, producing the wanted output. • What’s next? • We had already written the skeleton for the Template class so that our test compiles.
  • 37. Make it pass • All the constructors and methods are in place to make the compiler happy, but none of those constructors and methods is doing anything so far. • We want to make the test pass in the easiest, quickest way possible. To put it another way, we’re now facing a red bar, meaning the code in our workspace is currently in an unstable state. • We want to get out of that state and into stable ground as quickly as possible.
  • 38. How to make it pass simply? • How do we make the test pass as quickly and easily as possible? • Evaluating a template that simple, “Hello, ${name}”, with a string- replace operation would be a matter of a few minutes of work, probably. • There’s another implementation, however, of the functionality implied by our failing test that fits our goal of “as quickly as possible” a bit better.
  • 39. First try public class Template { public Template(String templateText) { } public void set(String variable, String value) { } public String evaluate() { return "Hello, Reader"; } }
  • 40. Not optimum • Hard-coding the evaluate method to return “Hello, Reader” is most certainly the quickest and easiest way to make the test pass. Although it may not make much sense at first. • We want to squeeze out the wanted behavior with our tests. In this case, we’re making use of neither the actual variable nor the template. • And that means we know at least two dimensions on which to push our code toward a proper implementation. • Let’s extend our test to squeeze out the implementation we’re looking for.
  • 41. Second try public class TestTemplate { @Test public void oneVariable() throws Exception { Template template = new Template("Hello, ${name}"); template.set("name", "Reader"); assertEquals("Hello, Reader", template.evaluate()); } @Test public void differentValue() throws Exception { Template template = new Template("Hello, ${name}"); template.set("name", "someone else"); assertEquals("Hello, someone else", template.evaluate()); } }
  • 42. Triangulate • We’ve added a second call to set—with different input—and a second assertion to verify that the Template object will re-evaluate the template with the latest value for the “name” variable. • Our hard-coded evaluate method in the Template class will surely no longer pass this test, which was our goal. • This technique is named triangulation, referring to how we’re using multiple bearings to pinpoint the design toward the proper implementation. • Now, how could we make this enhanced test pass?
  • 43. Another pass public class Template { private String variableValue; public Template(String templateText) { } public void set(String variable, String value) { this.variableValue = value; } public String evaluate() { return "Hello, " + variableValue; } }
  • 44. Are we refactoring? • Our test passes again with minimal effort. • Obviously our test isn’t good enough yet, because we’ve got that hard-coded part in there, so let’s continue triangulating to push out the last bits of literal strings from our code. • The next shows how we alter our test to drive out not just the hard- coding of the variable value but also the template text around the variable.
  • 45. Closer? public class TestTemplate { @Test public void oneVariable() throws Exception { Template template = new Template("Hello, ${name}"); template.set("name", "Reader"); assertEquals("Hello, Reader", template.evaluate()); } @Test public void differentTemplate() throws Exception { Template template = new Template("Hi, ${name}"); template.set("name", "someone else"); assertEquals("Hi, someone else", template.evaluate()); }}
  • 46. Red result • Red bar. Obviously the hard-coded return statement doesn’t cut it anymore. At this point, we’re facing the task of parsing the template text somehow. • Perhaps we should first implement the parsing logic and then come back to this test. • Time to discuss breadth and depth.