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

PPTX
Test-Driven Development
PDF
Tdd practices
PPTX
Test Driven Development
PPT
Test Driven Development
PPTX
Test driven development
PPTX
Test driven development
Test-Driven Development
Tdd practices
Test Driven Development
Test Driven Development
Test driven development
Test driven development

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

PPTX
Test driven development
PPTX
Test driven development
PPTX
Test driven development
PPTX
Test driven development
PPTX
Ian Cooper webinar for DDD Iran: Kent beck style tdd seven years after
PDF
Test Driven Development
KEY
Test Driven Development - For Girl Geeks Night Sydney
PDF
Test-Driven Development
ODP
Effective TDD - Less is more
PDF
Growing Object Oriented Software
PPTX
Software presentation
PPTX
TDD & Refactoring
PPTX
TDD - Seriously, try it - Codemotion (May '24)
PDF
iOS Test-Driven Development
PDF
Test Driven Development Methodology and Philosophy
PPTX
UXDX London 2018 Nik Crabtree - Enhancing the Processes of Test Driven Develo...
PDF
What CS Class Didn't Teach About Testing
PDF
Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...
PPTX
TeDevelopment Testing in Software Engineering
PDF
Test-Driven Development (TDD)
Test driven development
Test driven development
Test driven development
Test driven development
Ian Cooper webinar for DDD Iran: Kent beck style tdd seven years after
Test Driven Development
Test Driven Development - For Girl Geeks Night Sydney
Test-Driven Development
Effective TDD - Less is more
Growing Object Oriented Software
Software presentation
TDD & Refactoring
TDD - Seriously, try it - Codemotion (May '24)
iOS Test-Driven Development
Test Driven Development Methodology and Philosophy
UXDX London 2018 Nik Crabtree - Enhancing the Processes of Test Driven Develo...
What CS Class Didn't Teach About Testing
Test-Driven Developments are Inefficient; Behavior-Driven Developments are a ...
TeDevelopment Testing in Software Engineering
Test-Driven Development (TDD)

Recently uploaded (20)

PDF
PTS Company Brochure 2025 (1).pdf.......
PPTX
L1 - Introduction to python Backend.pptx
PPTX
Operating system designcfffgfgggggggvggggggggg
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PPTX
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
System and Network Administraation Chapter 3
PDF
medical staffing services at VALiNTRY
PDF
top salesforce developer skills in 2025.pdf
PDF
Softaken Excel to vCard Converter Software.pdf
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PPT
Introduction Database Management System for Course Database
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PPTX
ISO 45001 Occupational Health and Safety Management System
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PPTX
Transform Your Business with a Software ERP System
PPTX
ai tools demonstartion for schools and inter college
PDF
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
PTS Company Brochure 2025 (1).pdf.......
L1 - Introduction to python Backend.pptx
Operating system designcfffgfgggggggvggggggggg
Upgrade and Innovation Strategies for SAP ERP Customers
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
Agentic AI : A Practical Guide. Undersating, Implementing and Scaling Autono...
Navsoft: AI-Powered Business Solutions & Custom Software Development
System and Network Administraation Chapter 3
medical staffing services at VALiNTRY
top salesforce developer skills in 2025.pdf
Softaken Excel to vCard Converter Software.pdf
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Introduction Database Management System for Course Database
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
ISO 45001 Occupational Health and Safety Management System
Wondershare Filmora 15 Crack With Activation Key [2025
Internet Downloader Manager (IDM) Crack 6.42 Build 41
Transform Your Business with a Software ERP System
ai tools demonstartion for schools and inter college
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)

{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.