SlideShare ist ein Scribd-Unternehmen logo
1 von 76
TDD FOR THE WIN
Basics to Test Driven Development
May 2014 Minh Ngoc Dang
Senior Developer at ThoughtWorks
ThoughtWorks University Trainer
Minh Ngoc Dang
TESTING
WHY TESTING?
Lots of reasons! Here are a select few
Verify functionality of
application
Catch bugs and prevent them from
coming back
Serve as documentation for
maintainability purposes
BUT WHAT ABOUT…?
? How do we make sure we have full test coverage?
? How can we be confident all cases are covered?
? How can we prevent bugs from happening?
TDD!
TEST DRIVEN DEVELOPMENT!
BUT WAIT…WHAT IS IT?
BUT WAIT…WHAT IS IT?
TEST DRIVING MEANS
Writing tests before writing code
Write the minimum amount of code
necessary to make tests pass
Rinse and repeat
TESTS FIRST?! BUT
WHY?
WHY TDD?
Back to previously posed questions
Test
Coverage?
Cases Covered? Bug Prevention?
TEST COVERAGE
Tests written before code
TEST COVERAGE
Tests written before code
Ensure all code covered by tests
TEST COVERAGE
Tests written before code
Ensure all code covered by tests
High test coverage
WHY TDD?
Back to previously posed questions
Test
Coverage?
Cases Covered? Bug Prevention?
TEST CASES
Test cases reflect exactly what code
does
TEST CASES
Test cases reflect exactly what code
does
Visible list of functionality
TEST CASES
Test cases reflect exactly what code
does
Visible list of functionality
Easy to see which
cases are missing
WHY TDD?
Back to previously posed questions
Test
Coverage?
Cases Covered? Bug Prevention?
BUG PREVENTION
Mental shift in thinking up test case
before code
BUG PREVENTION
Mental shift in thinking up test case
before code
Encourage edge case testing
BUG PREVENTION
Mental shift in thinking up test case
before code
Encourage edge case testing
Help prevent bugs in
edge cases
WHY TDD?
Back to previously posed questions
Test
Coverage?
Cases Covered? Bug Prevention?
AND THAT’S NOT ALL!
TIME SAVER
Ease in debugging
Confidence in refactoring
DRIVING DESIGN
Help define usage – How should the
code be used?
Only write necessary code – YAGNI!
SO HOW CAN I TDD?
RED – GREEN - REFACTOR
New Test New Test New Test
Red
GreenRefactor
Red
GreenRefactor
Red
GreenRefactor
EXAMPLE
You are given strings of different lengths. If
the number of vowels are more than 30%
of the string length then insert ‘mommy’ for
each continuous set of vowels.
 his → hmommys
 hear → hmommyr
✗ hear → hmommymommyr
TEST CASES
“” → “” // empty string
“str” → “str” // no vowels
“a” → “mommy” // single vowel
“blah” → “blah” // < 30% length
“bla” → “blmommy” // > 30% length
“blaa” → “blmommy” // continuous vowels
“blaaha” → “blmommyhmommy”
// multi sets of vowels
“blA” → “blmommy” // capital letters
Null → raise exception // null checks
TEST
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class MommifierTest {
@Test
public void shouldNotMommifyEmptyString() {
String word = "";
Mommifier mommifier = new Mommifier();
String mommifiedWord = mommifier.mommify(word);
assertEquals("", mommifiedWord);
}
}
SOURCE
public class Mommifier {
public String mommify(String word) {
return null;
}
}
TEST
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class MommifierTest {
@Test
public void shouldNotMommifyEmptyString() {
String word = "";
Mommifier mommifier = new Mommifier();
String mommifiedWord = mommifier.mommify(word);
assertEquals("", mommifiedWord);
}
}
SOURCE
public class Mommifier {
public String mommify(String word) {
return "";
}
}
TEST
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class MommifierTest {
@Test
public void shouldNotMommifyEmptyString() {
String word = "";
Mommifier mommifier = new Mommifier();
String mommifiedWord = mommifier.mommify(word);
assertEquals("", mommifiedWord);
}
}
TEST
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class MommifierTest {
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {
String word = "str";
Mommifier mommifier = new Mommifier();
String mommifiedWord = mommifier.mommify(word);
assertEquals("str", mommifiedWord);
}
}
TEST
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class MommifierTest {
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {
String word = "str";
Mommifier mommifier = new Mommifier();
String mommifiedWord = mommifier.mommify(word);
assertEquals("str", mommifiedWord);
}
}
SOURCE
public class Mommifier {
public String mommify(String word) {
return word;
}
}
TEST
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class MommifierTest {
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {
String word = "str";
Mommifier mommifier = new Mommifier();
String mommifiedWord = mommifier.mommify(word);
assertEquals("str", mommifiedWord);
}
}
TEST
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class MommifierTest {
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {...}
@Test
public void shouldMommifyVowel() {
String word = "a";
Mommifier mommifier = new Mommifier();
String mommifiedWord = mommifier.mommify(word);
assertEquals("mommy", mommifiedWord);
}
}
TEST
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class MommifierTest {
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {...}
@Test
public void shouldMommifyVowel() {
String word = "a";
Mommifier mommifier = new Mommifier();
String mommifiedWord = mommifier.mommify(word);
assertEquals("mommy", mommifiedWord);
}
}
SOURCE
public class Mommifier {
public String mommify(String word) {
for (char character : word.toCharArray()) {
if (character == 'a'
|| character == 'e'
|| character == 'i'
|| character == 'o'
|| character == 'u'){
return "mommy";
}
}
return word;
}
}
TEST
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class MommifierTest {
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {...}
@Test
public void shouldMommifyVowel() {
String word = "a";
Mommifier mommifier = new Mommifier();
String mommifiedWord = mommifier.mommify(word);
assertEquals("mommy", mommifiedWord);
}
}
SOURCE
public class Mommifier {
public String mommify(String word) {
for (char character : word.toCharArray()) {
if (character == 'a'
|| character == 'e'
|| character == 'i'
|| character == 'o'
|| character == 'u'){
return "mommy";
}
}
return word;
}
}
SOURCE
public class Mommifier {
private static final String VOWELS = "aeiou";
private static final String REPLACEMENT_WORD = "mommy";
public String mommify(String word) {
for (Character character : word.toCharArray()) {
if (isAVowel(character)) {
return REPLACEMENT_WORD;
}
}
return word;
}
private boolean isAVowel(Character character) {
return VOWELS.contains(character.toString());
}
}
TEST
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class MommifierTest {
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {...}
@Test
public void shouldMommifyVowel() {
String word = "a";
Mommifier mommifier = new Mommifier();
String mommifiedWord = mommifier.mommify(word);
assertEquals("mommy", mommifiedWord);
}
}
TEST
private Mommifier mommifier;
@Before
public void setUp() {
mommifier = new Mommifier();
}
@Test
public void shouldNotMommifyEmptyString() {
assertEquals("", mommifier.mommify(""));
}
@Test
public void shouldNotMommifyWordsWithNoVowels() {
assertEquals("str", mommifier.mommify("str"));
}
@Test
public void shouldMommifyVowel() {
assertEquals("mommy", mommifier.mommify("a"));
}
TEST
private Mommifier mommifier;
@Before
public void setUp() {
mommifier = new Mommifier();
}
@Test
public void shouldNotMommifyEmptyString() {
assertEquals("", mommifier.mommify(""));
}
@Test
public void shouldNotMommifyWordsWithNoVowels() {
assertEquals("str", mommifier.mommify("str"));
}
@Test
public void shouldMommifyVowel() {
assertEquals("mommy", mommifier.mommify("a"));
}
TEST
import ...;
public class MommifierTest {
private Mommifier mommifier;
@Before
public void setUp() {...}
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {...}
@Test
public void shouldMommifyVowel() {...}
@Test
public void shouldMommifyConsonantsAndSingleVowel() {
assertEquals("blmommy", mommifier.mommify("bla"));
}
}
TEST
import ...;
public class MommifierTest {
private Mommifier mommifier;
@Before
public void setUp() {...}
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {...}
@Test
public void shouldMommifyVowel() {...}
@Test
public void shouldMommifyConsonantsAndSingleVowel() {
assertEquals("blmommy", mommifier.mommify("bla"));
}
}
SOURCE
public class Mommifier {
private static final String VOWELS = "aeiou";
private static final String REPLACEMENT_WORD = "mommy";
public String mommify(String word) {
String mommifiedWord = "";
for (Character character : word.toCharArray()) {
if (isAVowel(character)) {
mommifiedWord += REPLACEMENT_WORD;
} else {
mommifiedWord += character;
}
}
return mommifiedWord;
}
private boolean isAVowel(Character character) {
return VOWELS.contains(character.toString());
}
}
TEST
import ...;
public class MommifierTest {
private Mommifier mommifier;
@Before
public void setUp() {...}
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {...}
@Test
public void shouldMommifyVowel() {...}
@Test
public void shouldMommifyConsonantsAndSingleVowel() {
assertEquals("blmommy", mommifier.mommify("bla"));
}
}
TEST
private Mommifier mommifier;
@Before
public void setUp() {...}
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {...}
@Test
public void shouldMommifyVowel() {...}
@Test
public void shouldMommifyConsonantsAndSingleVowel() {...}
@Test
public void shouldNotMommifyLessThan30PercentVowels() {
assertEquals("blah", mommifier.mommify("blah"));
}
TEST
private Mommifier mommifier;
@Before
public void setUp() {...}
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {...}
@Test
public void shouldMommifyVowel() {...}
@Test
public void shouldMommifyConsonantsAndSingleVowel() {...}
@Test
public void shouldNotMommifyLessThan30PercentVowels() {
assertEquals("blah", mommifier.mommify("blah"));
}
SOURCE
...
private static final double THRESHOLD = 0.3;
public String mommify(String word) {
int vowelCount = 0;
String mommifiedWord = "";
for (Character character : word.toCharArray()) {
if (isAVowel(character)) {
mommifiedWord += REPLACEMENT_WORD;
vowelCount++;
} else {
mommifiedWord += character;
}
}
if((double)vowelCount/word.toCharArray().length
< THRESHOLD){
return word;
}
return mommifiedWord;
}
...
TEST
private Mommifier mommifier;
@Before
public void setUp() {...}
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {...}
@Test
public void shouldMommifyVowel() {...}
@Test
public void shouldMommifyConsonantsAndSingleVowel() {...}
@Test
public void shouldNotMommifyLessThan30PercentVowels() {
assertEquals("blah", mommifier.mommify("blah"));
}
SOURCE
public String mommify(String word) {
if(vowelCountLessThanThreshold(word)){
return word;
}
return replaceVowels(word);
}
private boolean vowelCountLessThanThreshold(String word){...}
private String replaceVowels(String word) {...}
private boolean isAVowel(Character character) {...}
TEST
private Mommifier mommifier;
@Before
public void setUp() {...}
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {...}
@Test
public void shouldMommifyVowel() {...}
@Test
public void shouldMommifyConsonantsAndSingleVowel() {...}
@Test
public void shouldNotMommifyLessThan30PercentVowels() {
assertEquals("blah", mommifier.mommify("blah"));
}
TEST
private Mommifier mommifier;
@Before
public void setUp() {...}
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {...}
@Test
public void shouldMommifyVowel() {...}
@Test
public void shouldMommifyConsonantsAndSingleVowel() {...}
@Test
public void shouldNotMommifyLessThan30PercentVowels() {...}
@Test
public void shouldMommifyContinuousVowelsOnlyOnce() {
assertEquals("blmommyh”, mommifier.mommify("blaah"));
}
TEST
private Mommifier mommifier;
@Before
public void setUp() {...}
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {...}
@Test
public void shouldMommifyVowel() {...}
@Test
public void shouldMommifyConsonantsAndSingleVowel() {...}
@Test
public void shouldNotMommifyLessThan30PercentVowels() {...}
@Test
public void shouldMommifyContinuousVowelsOnlyOnce() {
assertEquals("blmommyh”, mommifier.mommify("blaah"));
}
SOURCE
...
public String mommify(String word) {...}
private String replaceVowels(String word) {
String mommifiedWord = "";
for (Character character : word.toCharArray()) {
if (!isVowel(character)) {
mommifiedWord += character;
} else if(!mommifiedWord.endsWith(REPLACEMENT_WORD)){
mommifiedWord += REPLACEMENT_WORD;
}
}
return mommifiedWord;
}
private boolean vowelCountLessThanThreshold(String word){...}
private boolean isVowel(Character character) {...}
...
TEST
private Mommifier mommifier;
@Before
public void setUp() {...}
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {...}
@Test
public void shouldMommifyVowel() {...}
@Test
public void shouldMommifyConsonantsAndSingleVowel() {...}
@Test
public void shouldNotMommifyLessThan30PercentVowels() {...}
@Test
public void shouldMommifyContinuousVowelsOnlyOnce() {
assertEquals("blmommyh”, mommifier.mommify("blaah"));
}
TEST
private Mommifier mommifier;
@Before
public void setUp() {...}
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {...}
@Test
public void shouldMommifyVowel() {...}
@Test
public void shouldMommifyConsonantsAndSingleVowel() {...}
@Test
public void shouldNotMommifyLessThan30PercentVowels() {...}
@Test
public void shouldMommifyContinuousVowelsOnlyOnce() {...}
@Test
public void shouldMommifyMultipleSetsOfVowels() {
assertEquals("blmommyhmommy”, mommifier.mommify("blaha"));
}
TEST
private Mommifier mommifier;
@Before
public void setUp() {...}
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {...}
@Test
public void shouldMommifyVowel() {...}
@Test
public void shouldMommifyConsonantsAndSingleVowel() {...}
@Test
public void shouldNotMommifyLessThan30PercentVowels() {...}
@Test
public void shouldMommifyContinuousVowelsOnlyOnce() {...}
@Test
public void shouldMommifyMultipleSetsOfVowels() {
assertEquals("blmommyhmommy”, mommifier.mommify("blaha"));
}
TEST
@Before
public void setUp() {...}
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {...}
@Test
public void shouldMommifyVowel() {...}
@Test
public void shouldMommifyConsonantsAndSingleVowel() {...}
@Test
public void shouldNotMommifyLessThan30PercentVowels() {...}
@Test
public void shouldMommifyContinuousVowelsOnlyOnce() {...}
@Test
public void shouldMommifyMultipleSetsOfVowels() {...}
@Test
public void shouldMommifyCapitalVowels() {
assertEquals("BLmommy", mommifier.mommify("BLA"));
}
TEST
@Before
public void setUp() {...}
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {...}
@Test
public void shouldMommifyVowel() {...}
@Test
public void shouldMommifyConsonantsAndSingleVowel() {...}
@Test
public void shouldNotMommifyLessThan30PercentVowels() {...}
@Test
public void shouldMommifyContinuousVowelsOnlyOnce() {...}
@Test
public void shouldMommifyMultipleSetsOfVowels() {...}
@Test
public void shouldMommifyCapitalVowels() {
assertEquals("BLmommy", mommifier.mommify("BLA"));
}
SOURCE
public class Mommifier {
private static final String VOWELS = "aeiou";
private static final String REPLACEMENT_WORD = "mommy";
private static final double THRESHOLD = 0.3;
public String mommify(String word) {...}
private String replaceVowels(String word) {...}
private boolean vowelCountLessThanThreshold(String word){...}
private boolean isVowel(Character character) {
Character lowerCase = Character.toLowerCase(character);
return VOWELS.contains(lowerCase.toString());
}
}
TEST
@Before
public void setUp() {...}
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {...}
@Test
public void shouldMommifyVowel() {...}
@Test
public void shouldMommifyConsonantsAndSingleVowel() {...}
@Test
public void shouldNotMommifyLessThan30PercentVowels() {...}
@Test
public void shouldMommifyContinuousVowelsOnlyOnce() {...}
@Test
public void shouldMommifyMultipleSetsOfVowels() {...}
@Test
public void shouldMommifyCapitalVowels() {
assertEquals("BLmommy", mommifier.mommify("BLA"));
}
TEST
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {...}
@Test
public void shouldMommifyVowel() {...}
@Test
public void shouldMommifyConsonantsAndSingleVowel() {...}
@Test
public void shouldNotMommifyLessThan30PercentVowels() {...}
@Test
public void shouldMommifyContinuousVowelsOnlyOnce() {...}
@Test
public void shouldMommifyMultipleSetsOfVowels() {...}
@Test
public void shouldMommifyCapitalVowels() {...}
@Test(expected = NullPointerException.class)
public void shouldErrorOnNull() {
mommifier.mommify(null);
}
TEST
@Test
public void shouldNotMommifyEmptyString() {...}
@Test
public void shouldNotMommifyWordsWithNoVowels() {...}
@Test
public void shouldMommifyVowel() {...}
@Test
public void shouldMommifyConsonantsAndSingleVowel() {...}
@Test
public void shouldNotMommifyLessThan30PercentVowels() {...}
@Test
public void shouldMommifyContinuousVowelsOnlyOnce() {...}
@Test
public void shouldMommifyMultipleSetsOfVowels() {...}
@Test
public void shouldMommifyCapitalVowels() {...}
@Test(expected = NullPointerException.class)
public void shouldErrorOnNull() {
mommifier.mommify(null);
}
TEST CASES
“” → “”
“str” → “str”
“a” → “mommy”
“blah” → “blah”
“bla” → “blmommy”
“blaa” → “blmommy”
“blaaha” → “blmommyhmommy”
“blA” → “blmommy”
Null → raise exception
TEST CASES
public void shouldNotMommifyEmptyString
public void shouldNotMommifyWordsWithNoVowels
public void shouldMommifyVowel
public void shouldMommifyConsonantsAndSingleVowel
public void shouldNotMommifyLessThan30PercentVowels
public void shouldMommifyContinuousVowelsOnlyOnce
public void shouldMommifyMultipleSetsOfVowels
public void shouldMommifyCapitalVowels
public void shouldErrorOnNull
TOP DOWN TESTING
SOME USEFUL BOOKS
THANK YOU
Gabriel Gavasso
Anand Iyengar
Thao Dang
Hung Dang
Mommifier Dojo by TWU team

Weitere ähnliche Inhalte

Was ist angesagt?

Mvcc in postgreSQL 권건우
Mvcc in postgreSQL 권건우Mvcc in postgreSQL 권건우
Mvcc in postgreSQL 권건우PgDay.Seoul
 
DockerCon SF 2015: Getting Started w/ Docker
DockerCon SF 2015: Getting Started w/ DockerDockerCon SF 2015: Getting Started w/ Docker
DockerCon SF 2015: Getting Started w/ DockerDocker, Inc.
 
Cloud foundry: The Platform for Forging Cloud Native Applications
Cloud foundry: The Platform for Forging Cloud Native ApplicationsCloud foundry: The Platform for Forging Cloud Native Applications
Cloud foundry: The Platform for Forging Cloud Native ApplicationsChip Childers
 
Networking in Java with NIO and Netty
Networking in Java with NIO and NettyNetworking in Java with NIO and Netty
Networking in Java with NIO and NettyConstantine Slisenka
 
The Secrets of Hexagonal Architecture
The Secrets of Hexagonal ArchitectureThe Secrets of Hexagonal Architecture
The Secrets of Hexagonal ArchitectureNicolas Carlo
 
Database migrations with Flyway and Liquibase
Database migrations with Flyway and LiquibaseDatabase migrations with Flyway and Liquibase
Database migrations with Flyway and LiquibaseLars Östling
 
Microservices in Practice
Microservices in PracticeMicroservices in Practice
Microservices in PracticeKasun Indrasiri
 
Spring Cloud: Why? How? What?
Spring Cloud: Why? How? What?Spring Cloud: Why? How? What?
Spring Cloud: Why? How? What?Orkhan Gasimov
 
Monoliths, Migrations, and Microservices
Monoliths, Migrations, and MicroservicesMonoliths, Migrations, and Microservices
Monoliths, Migrations, and MicroservicesRandy Shoup
 
How to write a Dockerfile
How to write a DockerfileHow to write a Dockerfile
How to write a DockerfileKnoldus Inc.
 
Resilient Architecture
Resilient ArchitectureResilient Architecture
Resilient ArchitectureMatt Stine
 
Hexagonal architecture for java applications
Hexagonal architecture for java applicationsHexagonal architecture for java applications
Hexagonal architecture for java applicationsFabricio Epaminondas
 
Docker for .NET Developers
Docker for .NET DevelopersDocker for .NET Developers
Docker for .NET DevelopersTaswar Bhatti
 
Yow Conference Dec 2013 Netflix Workshop Slides with Notes
Yow Conference Dec 2013 Netflix Workshop Slides with NotesYow Conference Dec 2013 Netflix Workshop Slides with Notes
Yow Conference Dec 2013 Netflix Workshop Slides with NotesAdrian Cockcroft
 

Was ist angesagt? (20)

Mvcc in postgreSQL 권건우
Mvcc in postgreSQL 권건우Mvcc in postgreSQL 권건우
Mvcc in postgreSQL 권건우
 
Domain driven design
Domain driven designDomain driven design
Domain driven design
 
Second Level Cache in JPA Explained
Second Level Cache in JPA ExplainedSecond Level Cache in JPA Explained
Second Level Cache in JPA Explained
 
DockerCon SF 2015: Getting Started w/ Docker
DockerCon SF 2015: Getting Started w/ DockerDockerCon SF 2015: Getting Started w/ Docker
DockerCon SF 2015: Getting Started w/ Docker
 
Event storming recipes
Event storming recipesEvent storming recipes
Event storming recipes
 
Cloud foundry: The Platform for Forging Cloud Native Applications
Cloud foundry: The Platform for Forging Cloud Native ApplicationsCloud foundry: The Platform for Forging Cloud Native Applications
Cloud foundry: The Platform for Forging Cloud Native Applications
 
Networking in Java with NIO and Netty
Networking in Java with NIO and NettyNetworking in Java with NIO and Netty
Networking in Java with NIO and Netty
 
The Secrets of Hexagonal Architecture
The Secrets of Hexagonal ArchitectureThe Secrets of Hexagonal Architecture
The Secrets of Hexagonal Architecture
 
Database migrations with Flyway and Liquibase
Database migrations with Flyway and LiquibaseDatabase migrations with Flyway and Liquibase
Database migrations with Flyway and Liquibase
 
Event storming
Event storming Event storming
Event storming
 
Microservices in Practice
Microservices in PracticeMicroservices in Practice
Microservices in Practice
 
Spring Cloud: Why? How? What?
Spring Cloud: Why? How? What?Spring Cloud: Why? How? What?
Spring Cloud: Why? How? What?
 
Monoliths, Migrations, and Microservices
Monoliths, Migrations, and MicroservicesMonoliths, Migrations, and Microservices
Monoliths, Migrations, and Microservices
 
How to write a Dockerfile
How to write a DockerfileHow to write a Dockerfile
How to write a Dockerfile
 
Resilient Architecture
Resilient ArchitectureResilient Architecture
Resilient Architecture
 
Introduction to Microservices
Introduction to MicroservicesIntroduction to Microservices
Introduction to Microservices
 
Hexagonal architecture for java applications
Hexagonal architecture for java applicationsHexagonal architecture for java applications
Hexagonal architecture for java applications
 
Event Storming and Saga
Event Storming and SagaEvent Storming and Saga
Event Storming and Saga
 
Docker for .NET Developers
Docker for .NET DevelopersDocker for .NET Developers
Docker for .NET Developers
 
Yow Conference Dec 2013 Netflix Workshop Slides with Notes
Yow Conference Dec 2013 Netflix Workshop Slides with NotesYow Conference Dec 2013 Netflix Workshop Slides with Notes
Yow Conference Dec 2013 Netflix Workshop Slides with Notes
 

Andere mochten auch

Tdd in android (mvp)
Tdd in android (mvp)Tdd in android (mvp)
Tdd in android (mvp)Prateek Jain
 
Overview on TDD (Test Driven Development) & ATDD (Acceptance Test Driven Deve...
Overview on TDD (Test Driven Development) & ATDD (Acceptance Test Driven Deve...Overview on TDD (Test Driven Development) & ATDD (Acceptance Test Driven Deve...
Overview on TDD (Test Driven Development) & ATDD (Acceptance Test Driven Deve...Zohirul Alam Tiemoon
 
Test-Driven Development (TDD)
Test-Driven Development (TDD)Test-Driven Development (TDD)
Test-Driven Development (TDD)Brian Rasmussen
 
Test Driven Development (TDD)
Test Driven Development (TDD)Test Driven Development (TDD)
Test Driven Development (TDD)David Ehringer
 
Mobile Performance Testing
Mobile Performance TestingMobile Performance Testing
Mobile Performance TestingThoughtworks
 
DevOps - Agile on Steroids by Tom Clement Oketch and Augustine Kisitu
DevOps - Agile on Steroids by Tom Clement Oketch and Augustine KisituDevOps - Agile on Steroids by Tom Clement Oketch and Augustine Kisitu
DevOps - Agile on Steroids by Tom Clement Oketch and Augustine KisituThoughtworks
 
7 Dimensions of Agile Analytics by Ken Collier
7 Dimensions of Agile Analytics by Ken Collier 7 Dimensions of Agile Analytics by Ken Collier
7 Dimensions of Agile Analytics by Ken Collier Thoughtworks
 

Andere mochten auch (10)

Tdd in android (mvp)
Tdd in android (mvp)Tdd in android (mvp)
Tdd in android (mvp)
 
Android TDD
Android TDDAndroid TDD
Android TDD
 
TDD - Agile
TDD - Agile TDD - Agile
TDD - Agile
 
Overview on TDD (Test Driven Development) & ATDD (Acceptance Test Driven Deve...
Overview on TDD (Test Driven Development) & ATDD (Acceptance Test Driven Deve...Overview on TDD (Test Driven Development) & ATDD (Acceptance Test Driven Deve...
Overview on TDD (Test Driven Development) & ATDD (Acceptance Test Driven Deve...
 
Test-Driven Development (TDD)
Test-Driven Development (TDD)Test-Driven Development (TDD)
Test-Driven Development (TDD)
 
Test Driven Development (TDD)
Test Driven Development (TDD)Test Driven Development (TDD)
Test Driven Development (TDD)
 
TDD - Ketan Soni
TDD - Ketan SoniTDD - Ketan Soni
TDD - Ketan Soni
 
Mobile Performance Testing
Mobile Performance TestingMobile Performance Testing
Mobile Performance Testing
 
DevOps - Agile on Steroids by Tom Clement Oketch and Augustine Kisitu
DevOps - Agile on Steroids by Tom Clement Oketch and Augustine KisituDevOps - Agile on Steroids by Tom Clement Oketch and Augustine Kisitu
DevOps - Agile on Steroids by Tom Clement Oketch and Augustine Kisitu
 
7 Dimensions of Agile Analytics by Ken Collier
7 Dimensions of Agile Analytics by Ken Collier 7 Dimensions of Agile Analytics by Ken Collier
7 Dimensions of Agile Analytics by Ken Collier
 

Ähnlich wie TDD for the Win

Automated Testing in Django
Automated Testing in DjangoAutomated Testing in Django
Automated Testing in DjangoLoek van Gent
 
DOES NOT NEED TO BE ANSWERED UNTIL NOV 13thWords AssignmentRober.pdf
DOES NOT NEED TO BE ANSWERED UNTIL NOV 13thWords AssignmentRober.pdfDOES NOT NEED TO BE ANSWERED UNTIL NOV 13thWords AssignmentRober.pdf
DOES NOT NEED TO BE ANSWERED UNTIL NOV 13thWords AssignmentRober.pdfarchanaemporium
 
C++ Unit Test with Google Testing Framework
C++ Unit Test with Google Testing FrameworkC++ Unit Test with Google Testing Framework
C++ Unit Test with Google Testing FrameworkHumberto Marchezi
 
Can You Trust Your Tests? (Agile Tour 2015 Kaunas)
Can You Trust Your Tests? (Agile Tour 2015 Kaunas)Can You Trust Your Tests? (Agile Tour 2015 Kaunas)
Can You Trust Your Tests? (Agile Tour 2015 Kaunas)Vaidas Pilkauskas
 
Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516SOAT
 
Boosting Your Testing Productivity with Groovy
Boosting Your Testing Productivity with GroovyBoosting Your Testing Productivity with Groovy
Boosting Your Testing Productivity with GroovyJames Williams
 
Javaone2008 Bof 5101 Groovytesting
Javaone2008 Bof 5101 GroovytestingJavaone2008 Bof 5101 Groovytesting
Javaone2008 Bof 5101 GroovytestingAndres Almiray
 
Test-Driven Development for TYPO3 @ T3CON12DE
Test-Driven Development for TYPO3 @ T3CON12DETest-Driven Development for TYPO3 @ T3CON12DE
Test-Driven Development for TYPO3 @ T3CON12DEOliver Klee
 
Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDUnit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDPaweł Michalik
 
GTAC Boosting your Testing Productivity with Groovy
GTAC Boosting your Testing Productivity with GroovyGTAC Boosting your Testing Productivity with Groovy
GTAC Boosting your Testing Productivity with GroovyAndres Almiray
 
Not your father's tests
Not your father's testsNot your father's tests
Not your father's testsSean P. Floyd
 
Assignment 7
Assignment 7Assignment 7
Assignment 7IIUM
 
Vaidas Pilkauskas and Tadas Ščerbinskas - Can you trust your tests?
Vaidas Pilkauskas and Tadas Ščerbinskas - Can you trust your tests?Vaidas Pilkauskas and Tadas Ščerbinskas - Can you trust your tests?
Vaidas Pilkauskas and Tadas Ščerbinskas - Can you trust your tests?Agile Lietuva
 
Test-driven development for TYPO3 (T3DD11)
Test-driven development for TYPO3 (T3DD11)Test-driven development for TYPO3 (T3DD11)
Test-driven development for TYPO3 (T3DD11)Oliver Klee
 
Test-driven Development for TYPO3
Test-driven Development for TYPO3Test-driven Development for TYPO3
Test-driven Development for TYPO3Oliver Klee
 
Test your tests with PIT framework
Test your tests with PIT frameworkTest your tests with PIT framework
Test your tests with PIT frameworkDarko Špoljarić
 

Ähnlich wie TDD for the Win (20)

Automated Testing in Django
Automated Testing in DjangoAutomated Testing in Django
Automated Testing in Django
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
 
DOES NOT NEED TO BE ANSWERED UNTIL NOV 13thWords AssignmentRober.pdf
DOES NOT NEED TO BE ANSWERED UNTIL NOV 13thWords AssignmentRober.pdfDOES NOT NEED TO BE ANSWERED UNTIL NOV 13thWords AssignmentRober.pdf
DOES NOT NEED TO BE ANSWERED UNTIL NOV 13thWords AssignmentRober.pdf
 
C++ Unit Test with Google Testing Framework
C++ Unit Test with Google Testing FrameworkC++ Unit Test with Google Testing Framework
C++ Unit Test with Google Testing Framework
 
Can You Trust Your Tests? (Agile Tour 2015 Kaunas)
Can You Trust Your Tests? (Agile Tour 2015 Kaunas)Can You Trust Your Tests? (Agile Tour 2015 Kaunas)
Can You Trust Your Tests? (Agile Tour 2015 Kaunas)
 
Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516
 
Boosting Your Testing Productivity with Groovy
Boosting Your Testing Productivity with GroovyBoosting Your Testing Productivity with Groovy
Boosting Your Testing Productivity with Groovy
 
Javaone2008 Bof 5101 Groovytesting
Javaone2008 Bof 5101 GroovytestingJavaone2008 Bof 5101 Groovytesting
Javaone2008 Bof 5101 Groovytesting
 
Test-Driven Development for TYPO3 @ T3CON12DE
Test-Driven Development for TYPO3 @ T3CON12DETest-Driven Development for TYPO3 @ T3CON12DE
Test-Driven Development for TYPO3 @ T3CON12DE
 
Unit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDDUnit testing with PHPUnit - there's life outside of TDD
Unit testing with PHPUnit - there's life outside of TDD
 
GTAC Boosting your Testing Productivity with Groovy
GTAC Boosting your Testing Productivity with GroovyGTAC Boosting your Testing Productivity with Groovy
GTAC Boosting your Testing Productivity with Groovy
 
Google guava
Google guavaGoogle guava
Google guava
 
Not your father's tests
Not your father's testsNot your father's tests
Not your father's tests
 
Assignment 7
Assignment 7Assignment 7
Assignment 7
 
Vaidas Pilkauskas and Tadas Ščerbinskas - Can you trust your tests?
Vaidas Pilkauskas and Tadas Ščerbinskas - Can you trust your tests?Vaidas Pilkauskas and Tadas Ščerbinskas - Can you trust your tests?
Vaidas Pilkauskas and Tadas Ščerbinskas - Can you trust your tests?
 
Rc2010 tdd
Rc2010 tddRc2010 tdd
Rc2010 tdd
 
Test-driven development for TYPO3 (T3DD11)
Test-driven development for TYPO3 (T3DD11)Test-driven development for TYPO3 (T3DD11)
Test-driven development for TYPO3 (T3DD11)
 
jUnit
jUnitjUnit
jUnit
 
Test-driven Development for TYPO3
Test-driven Development for TYPO3Test-driven Development for TYPO3
Test-driven Development for TYPO3
 
Test your tests with PIT framework
Test your tests with PIT frameworkTest your tests with PIT framework
Test your tests with PIT framework
 

Mehr von Thoughtworks

Design System as a Product
Design System as a ProductDesign System as a Product
Design System as a ProductThoughtworks
 
Designers, Developers & Dogs
Designers, Developers & DogsDesigners, Developers & Dogs
Designers, Developers & DogsThoughtworks
 
Cloud-first for fast innovation
Cloud-first for fast innovationCloud-first for fast innovation
Cloud-first for fast innovationThoughtworks
 
More impact with flexible teams
More impact with flexible teamsMore impact with flexible teams
More impact with flexible teamsThoughtworks
 
Culture of Innovation
Culture of InnovationCulture of Innovation
Culture of InnovationThoughtworks
 
Developer Experience
Developer ExperienceDeveloper Experience
Developer ExperienceThoughtworks
 
When we design together
When we design togetherWhen we design together
When we design togetherThoughtworks
 
Hardware is hard(er)
Hardware is hard(er)Hardware is hard(er)
Hardware is hard(er)Thoughtworks
 
Customer-centric innovation enabled by cloud
 Customer-centric innovation enabled by cloud Customer-centric innovation enabled by cloud
Customer-centric innovation enabled by cloudThoughtworks
 
Amazon's Culture of Innovation
Amazon's Culture of InnovationAmazon's Culture of Innovation
Amazon's Culture of InnovationThoughtworks
 
When in doubt, go live
When in doubt, go liveWhen in doubt, go live
When in doubt, go liveThoughtworks
 
Don't cross the Rubicon
Don't cross the RubiconDon't cross the Rubicon
Don't cross the RubiconThoughtworks
 
Your test coverage is a lie!
Your test coverage is a lie!Your test coverage is a lie!
Your test coverage is a lie!Thoughtworks
 
Docker container security
Docker container securityDocker container security
Docker container securityThoughtworks
 
Redefining the unit
Redefining the unitRedefining the unit
Redefining the unitThoughtworks
 
Technology Radar Webinar UK - Vol. 22
Technology Radar Webinar UK - Vol. 22Technology Radar Webinar UK - Vol. 22
Technology Radar Webinar UK - Vol. 22Thoughtworks
 
A Tribute to Turing
A Tribute to TuringA Tribute to Turing
A Tribute to TuringThoughtworks
 
Rsa maths worked out
Rsa maths worked outRsa maths worked out
Rsa maths worked outThoughtworks
 

Mehr von Thoughtworks (20)

Design System as a Product
Design System as a ProductDesign System as a Product
Design System as a Product
 
Designers, Developers & Dogs
Designers, Developers & DogsDesigners, Developers & Dogs
Designers, Developers & Dogs
 
Cloud-first for fast innovation
Cloud-first for fast innovationCloud-first for fast innovation
Cloud-first for fast innovation
 
More impact with flexible teams
More impact with flexible teamsMore impact with flexible teams
More impact with flexible teams
 
Culture of Innovation
Culture of InnovationCulture of Innovation
Culture of Innovation
 
Dual-Track Agile
Dual-Track AgileDual-Track Agile
Dual-Track Agile
 
Developer Experience
Developer ExperienceDeveloper Experience
Developer Experience
 
When we design together
When we design togetherWhen we design together
When we design together
 
Hardware is hard(er)
Hardware is hard(er)Hardware is hard(er)
Hardware is hard(er)
 
Customer-centric innovation enabled by cloud
 Customer-centric innovation enabled by cloud Customer-centric innovation enabled by cloud
Customer-centric innovation enabled by cloud
 
Amazon's Culture of Innovation
Amazon's Culture of InnovationAmazon's Culture of Innovation
Amazon's Culture of Innovation
 
When in doubt, go live
When in doubt, go liveWhen in doubt, go live
When in doubt, go live
 
Don't cross the Rubicon
Don't cross the RubiconDon't cross the Rubicon
Don't cross the Rubicon
 
Error handling
Error handlingError handling
Error handling
 
Your test coverage is a lie!
Your test coverage is a lie!Your test coverage is a lie!
Your test coverage is a lie!
 
Docker container security
Docker container securityDocker container security
Docker container security
 
Redefining the unit
Redefining the unitRedefining the unit
Redefining the unit
 
Technology Radar Webinar UK - Vol. 22
Technology Radar Webinar UK - Vol. 22Technology Radar Webinar UK - Vol. 22
Technology Radar Webinar UK - Vol. 22
 
A Tribute to Turing
A Tribute to TuringA Tribute to Turing
A Tribute to Turing
 
Rsa maths worked out
Rsa maths worked outRsa maths worked out
Rsa maths worked out
 

Kürzlich hochgeladen

How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 

Kürzlich hochgeladen (20)

How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 

TDD for the Win

  • 1. TDD FOR THE WIN Basics to Test Driven Development May 2014 Minh Ngoc Dang
  • 2. Senior Developer at ThoughtWorks ThoughtWorks University Trainer Minh Ngoc Dang
  • 4. WHY TESTING? Lots of reasons! Here are a select few Verify functionality of application Catch bugs and prevent them from coming back Serve as documentation for maintainability purposes
  • 5. BUT WHAT ABOUT…? ? How do we make sure we have full test coverage? ? How can we be confident all cases are covered? ? How can we prevent bugs from happening?
  • 10. TEST DRIVING MEANS Writing tests before writing code Write the minimum amount of code necessary to make tests pass Rinse and repeat
  • 12. WHY TDD? Back to previously posed questions Test Coverage? Cases Covered? Bug Prevention?
  • 14. TEST COVERAGE Tests written before code Ensure all code covered by tests
  • 15. TEST COVERAGE Tests written before code Ensure all code covered by tests High test coverage
  • 16. WHY TDD? Back to previously posed questions Test Coverage? Cases Covered? Bug Prevention?
  • 17. TEST CASES Test cases reflect exactly what code does
  • 18. TEST CASES Test cases reflect exactly what code does Visible list of functionality
  • 19. TEST CASES Test cases reflect exactly what code does Visible list of functionality Easy to see which cases are missing
  • 20. WHY TDD? Back to previously posed questions Test Coverage? Cases Covered? Bug Prevention?
  • 21. BUG PREVENTION Mental shift in thinking up test case before code
  • 22. BUG PREVENTION Mental shift in thinking up test case before code Encourage edge case testing
  • 23. BUG PREVENTION Mental shift in thinking up test case before code Encourage edge case testing Help prevent bugs in edge cases
  • 24. WHY TDD? Back to previously posed questions Test Coverage? Cases Covered? Bug Prevention?
  • 26. TIME SAVER Ease in debugging Confidence in refactoring
  • 27. DRIVING DESIGN Help define usage – How should the code be used? Only write necessary code – YAGNI!
  • 28. SO HOW CAN I TDD?
  • 29. RED – GREEN - REFACTOR New Test New Test New Test Red GreenRefactor Red GreenRefactor Red GreenRefactor
  • 30. EXAMPLE You are given strings of different lengths. If the number of vowels are more than 30% of the string length then insert ‘mommy’ for each continuous set of vowels.  his → hmommys  hear → hmommyr ✗ hear → hmommymommyr
  • 31. TEST CASES “” → “” // empty string “str” → “str” // no vowels “a” → “mommy” // single vowel “blah” → “blah” // < 30% length “bla” → “blmommy” // > 30% length “blaa” → “blmommy” // continuous vowels “blaaha” → “blmommyhmommy” // multi sets of vowels “blA” → “blmommy” // capital letters Null → raise exception // null checks
  • 32. TEST import org.junit.Test; import static org.junit.Assert.assertEquals; public class MommifierTest { @Test public void shouldNotMommifyEmptyString() { String word = ""; Mommifier mommifier = new Mommifier(); String mommifiedWord = mommifier.mommify(word); assertEquals("", mommifiedWord); } }
  • 33. SOURCE public class Mommifier { public String mommify(String word) { return null; } }
  • 34. TEST import org.junit.Test; import static org.junit.Assert.assertEquals; public class MommifierTest { @Test public void shouldNotMommifyEmptyString() { String word = ""; Mommifier mommifier = new Mommifier(); String mommifiedWord = mommifier.mommify(word); assertEquals("", mommifiedWord); } }
  • 35. SOURCE public class Mommifier { public String mommify(String word) { return ""; } }
  • 36. TEST import org.junit.Test; import static org.junit.Assert.assertEquals; public class MommifierTest { @Test public void shouldNotMommifyEmptyString() { String word = ""; Mommifier mommifier = new Mommifier(); String mommifiedWord = mommifier.mommify(word); assertEquals("", mommifiedWord); } }
  • 37. TEST import org.junit.Test; import static org.junit.Assert.assertEquals; public class MommifierTest { @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() { String word = "str"; Mommifier mommifier = new Mommifier(); String mommifiedWord = mommifier.mommify(word); assertEquals("str", mommifiedWord); } }
  • 38. TEST import org.junit.Test; import static org.junit.Assert.assertEquals; public class MommifierTest { @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() { String word = "str"; Mommifier mommifier = new Mommifier(); String mommifiedWord = mommifier.mommify(word); assertEquals("str", mommifiedWord); } }
  • 39. SOURCE public class Mommifier { public String mommify(String word) { return word; } }
  • 40. TEST import org.junit.Test; import static org.junit.Assert.assertEquals; public class MommifierTest { @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() { String word = "str"; Mommifier mommifier = new Mommifier(); String mommifiedWord = mommifier.mommify(word); assertEquals("str", mommifiedWord); } }
  • 41. TEST import org.junit.Test; import static org.junit.Assert.assertEquals; public class MommifierTest { @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() {...} @Test public void shouldMommifyVowel() { String word = "a"; Mommifier mommifier = new Mommifier(); String mommifiedWord = mommifier.mommify(word); assertEquals("mommy", mommifiedWord); } }
  • 42. TEST import org.junit.Test; import static org.junit.Assert.assertEquals; public class MommifierTest { @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() {...} @Test public void shouldMommifyVowel() { String word = "a"; Mommifier mommifier = new Mommifier(); String mommifiedWord = mommifier.mommify(word); assertEquals("mommy", mommifiedWord); } }
  • 43. SOURCE public class Mommifier { public String mommify(String word) { for (char character : word.toCharArray()) { if (character == 'a' || character == 'e' || character == 'i' || character == 'o' || character == 'u'){ return "mommy"; } } return word; } }
  • 44. TEST import org.junit.Test; import static org.junit.Assert.assertEquals; public class MommifierTest { @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() {...} @Test public void shouldMommifyVowel() { String word = "a"; Mommifier mommifier = new Mommifier(); String mommifiedWord = mommifier.mommify(word); assertEquals("mommy", mommifiedWord); } }
  • 45. SOURCE public class Mommifier { public String mommify(String word) { for (char character : word.toCharArray()) { if (character == 'a' || character == 'e' || character == 'i' || character == 'o' || character == 'u'){ return "mommy"; } } return word; } }
  • 46. SOURCE public class Mommifier { private static final String VOWELS = "aeiou"; private static final String REPLACEMENT_WORD = "mommy"; public String mommify(String word) { for (Character character : word.toCharArray()) { if (isAVowel(character)) { return REPLACEMENT_WORD; } } return word; } private boolean isAVowel(Character character) { return VOWELS.contains(character.toString()); } }
  • 47. TEST import org.junit.Test; import static org.junit.Assert.assertEquals; public class MommifierTest { @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() {...} @Test public void shouldMommifyVowel() { String word = "a"; Mommifier mommifier = new Mommifier(); String mommifiedWord = mommifier.mommify(word); assertEquals("mommy", mommifiedWord); } }
  • 48. TEST private Mommifier mommifier; @Before public void setUp() { mommifier = new Mommifier(); } @Test public void shouldNotMommifyEmptyString() { assertEquals("", mommifier.mommify("")); } @Test public void shouldNotMommifyWordsWithNoVowels() { assertEquals("str", mommifier.mommify("str")); } @Test public void shouldMommifyVowel() { assertEquals("mommy", mommifier.mommify("a")); }
  • 49. TEST private Mommifier mommifier; @Before public void setUp() { mommifier = new Mommifier(); } @Test public void shouldNotMommifyEmptyString() { assertEquals("", mommifier.mommify("")); } @Test public void shouldNotMommifyWordsWithNoVowels() { assertEquals("str", mommifier.mommify("str")); } @Test public void shouldMommifyVowel() { assertEquals("mommy", mommifier.mommify("a")); }
  • 50. TEST import ...; public class MommifierTest { private Mommifier mommifier; @Before public void setUp() {...} @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() {...} @Test public void shouldMommifyVowel() {...} @Test public void shouldMommifyConsonantsAndSingleVowel() { assertEquals("blmommy", mommifier.mommify("bla")); } }
  • 51. TEST import ...; public class MommifierTest { private Mommifier mommifier; @Before public void setUp() {...} @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() {...} @Test public void shouldMommifyVowel() {...} @Test public void shouldMommifyConsonantsAndSingleVowel() { assertEquals("blmommy", mommifier.mommify("bla")); } }
  • 52. SOURCE public class Mommifier { private static final String VOWELS = "aeiou"; private static final String REPLACEMENT_WORD = "mommy"; public String mommify(String word) { String mommifiedWord = ""; for (Character character : word.toCharArray()) { if (isAVowel(character)) { mommifiedWord += REPLACEMENT_WORD; } else { mommifiedWord += character; } } return mommifiedWord; } private boolean isAVowel(Character character) { return VOWELS.contains(character.toString()); } }
  • 53. TEST import ...; public class MommifierTest { private Mommifier mommifier; @Before public void setUp() {...} @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() {...} @Test public void shouldMommifyVowel() {...} @Test public void shouldMommifyConsonantsAndSingleVowel() { assertEquals("blmommy", mommifier.mommify("bla")); } }
  • 54. TEST private Mommifier mommifier; @Before public void setUp() {...} @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() {...} @Test public void shouldMommifyVowel() {...} @Test public void shouldMommifyConsonantsAndSingleVowel() {...} @Test public void shouldNotMommifyLessThan30PercentVowels() { assertEquals("blah", mommifier.mommify("blah")); }
  • 55. TEST private Mommifier mommifier; @Before public void setUp() {...} @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() {...} @Test public void shouldMommifyVowel() {...} @Test public void shouldMommifyConsonantsAndSingleVowel() {...} @Test public void shouldNotMommifyLessThan30PercentVowels() { assertEquals("blah", mommifier.mommify("blah")); }
  • 56. SOURCE ... private static final double THRESHOLD = 0.3; public String mommify(String word) { int vowelCount = 0; String mommifiedWord = ""; for (Character character : word.toCharArray()) { if (isAVowel(character)) { mommifiedWord += REPLACEMENT_WORD; vowelCount++; } else { mommifiedWord += character; } } if((double)vowelCount/word.toCharArray().length < THRESHOLD){ return word; } return mommifiedWord; } ...
  • 57. TEST private Mommifier mommifier; @Before public void setUp() {...} @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() {...} @Test public void shouldMommifyVowel() {...} @Test public void shouldMommifyConsonantsAndSingleVowel() {...} @Test public void shouldNotMommifyLessThan30PercentVowels() { assertEquals("blah", mommifier.mommify("blah")); }
  • 58. SOURCE public String mommify(String word) { if(vowelCountLessThanThreshold(word)){ return word; } return replaceVowels(word); } private boolean vowelCountLessThanThreshold(String word){...} private String replaceVowels(String word) {...} private boolean isAVowel(Character character) {...}
  • 59. TEST private Mommifier mommifier; @Before public void setUp() {...} @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() {...} @Test public void shouldMommifyVowel() {...} @Test public void shouldMommifyConsonantsAndSingleVowel() {...} @Test public void shouldNotMommifyLessThan30PercentVowels() { assertEquals("blah", mommifier.mommify("blah")); }
  • 60. TEST private Mommifier mommifier; @Before public void setUp() {...} @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() {...} @Test public void shouldMommifyVowel() {...} @Test public void shouldMommifyConsonantsAndSingleVowel() {...} @Test public void shouldNotMommifyLessThan30PercentVowels() {...} @Test public void shouldMommifyContinuousVowelsOnlyOnce() { assertEquals("blmommyh”, mommifier.mommify("blaah")); }
  • 61. TEST private Mommifier mommifier; @Before public void setUp() {...} @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() {...} @Test public void shouldMommifyVowel() {...} @Test public void shouldMommifyConsonantsAndSingleVowel() {...} @Test public void shouldNotMommifyLessThan30PercentVowels() {...} @Test public void shouldMommifyContinuousVowelsOnlyOnce() { assertEquals("blmommyh”, mommifier.mommify("blaah")); }
  • 62. SOURCE ... public String mommify(String word) {...} private String replaceVowels(String word) { String mommifiedWord = ""; for (Character character : word.toCharArray()) { if (!isVowel(character)) { mommifiedWord += character; } else if(!mommifiedWord.endsWith(REPLACEMENT_WORD)){ mommifiedWord += REPLACEMENT_WORD; } } return mommifiedWord; } private boolean vowelCountLessThanThreshold(String word){...} private boolean isVowel(Character character) {...} ...
  • 63. TEST private Mommifier mommifier; @Before public void setUp() {...} @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() {...} @Test public void shouldMommifyVowel() {...} @Test public void shouldMommifyConsonantsAndSingleVowel() {...} @Test public void shouldNotMommifyLessThan30PercentVowels() {...} @Test public void shouldMommifyContinuousVowelsOnlyOnce() { assertEquals("blmommyh”, mommifier.mommify("blaah")); }
  • 64. TEST private Mommifier mommifier; @Before public void setUp() {...} @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() {...} @Test public void shouldMommifyVowel() {...} @Test public void shouldMommifyConsonantsAndSingleVowel() {...} @Test public void shouldNotMommifyLessThan30PercentVowels() {...} @Test public void shouldMommifyContinuousVowelsOnlyOnce() {...} @Test public void shouldMommifyMultipleSetsOfVowels() { assertEquals("blmommyhmommy”, mommifier.mommify("blaha")); }
  • 65. TEST private Mommifier mommifier; @Before public void setUp() {...} @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() {...} @Test public void shouldMommifyVowel() {...} @Test public void shouldMommifyConsonantsAndSingleVowel() {...} @Test public void shouldNotMommifyLessThan30PercentVowels() {...} @Test public void shouldMommifyContinuousVowelsOnlyOnce() {...} @Test public void shouldMommifyMultipleSetsOfVowels() { assertEquals("blmommyhmommy”, mommifier.mommify("blaha")); }
  • 66. TEST @Before public void setUp() {...} @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() {...} @Test public void shouldMommifyVowel() {...} @Test public void shouldMommifyConsonantsAndSingleVowel() {...} @Test public void shouldNotMommifyLessThan30PercentVowels() {...} @Test public void shouldMommifyContinuousVowelsOnlyOnce() {...} @Test public void shouldMommifyMultipleSetsOfVowels() {...} @Test public void shouldMommifyCapitalVowels() { assertEquals("BLmommy", mommifier.mommify("BLA")); }
  • 67. TEST @Before public void setUp() {...} @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() {...} @Test public void shouldMommifyVowel() {...} @Test public void shouldMommifyConsonantsAndSingleVowel() {...} @Test public void shouldNotMommifyLessThan30PercentVowels() {...} @Test public void shouldMommifyContinuousVowelsOnlyOnce() {...} @Test public void shouldMommifyMultipleSetsOfVowels() {...} @Test public void shouldMommifyCapitalVowels() { assertEquals("BLmommy", mommifier.mommify("BLA")); }
  • 68. SOURCE public class Mommifier { private static final String VOWELS = "aeiou"; private static final String REPLACEMENT_WORD = "mommy"; private static final double THRESHOLD = 0.3; public String mommify(String word) {...} private String replaceVowels(String word) {...} private boolean vowelCountLessThanThreshold(String word){...} private boolean isVowel(Character character) { Character lowerCase = Character.toLowerCase(character); return VOWELS.contains(lowerCase.toString()); } }
  • 69. TEST @Before public void setUp() {...} @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() {...} @Test public void shouldMommifyVowel() {...} @Test public void shouldMommifyConsonantsAndSingleVowel() {...} @Test public void shouldNotMommifyLessThan30PercentVowels() {...} @Test public void shouldMommifyContinuousVowelsOnlyOnce() {...} @Test public void shouldMommifyMultipleSetsOfVowels() {...} @Test public void shouldMommifyCapitalVowels() { assertEquals("BLmommy", mommifier.mommify("BLA")); }
  • 70. TEST @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() {...} @Test public void shouldMommifyVowel() {...} @Test public void shouldMommifyConsonantsAndSingleVowel() {...} @Test public void shouldNotMommifyLessThan30PercentVowels() {...} @Test public void shouldMommifyContinuousVowelsOnlyOnce() {...} @Test public void shouldMommifyMultipleSetsOfVowels() {...} @Test public void shouldMommifyCapitalVowels() {...} @Test(expected = NullPointerException.class) public void shouldErrorOnNull() { mommifier.mommify(null); }
  • 71. TEST @Test public void shouldNotMommifyEmptyString() {...} @Test public void shouldNotMommifyWordsWithNoVowels() {...} @Test public void shouldMommifyVowel() {...} @Test public void shouldMommifyConsonantsAndSingleVowel() {...} @Test public void shouldNotMommifyLessThan30PercentVowels() {...} @Test public void shouldMommifyContinuousVowelsOnlyOnce() {...} @Test public void shouldMommifyMultipleSetsOfVowels() {...} @Test public void shouldMommifyCapitalVowels() {...} @Test(expected = NullPointerException.class) public void shouldErrorOnNull() { mommifier.mommify(null); }
  • 72. TEST CASES “” → “” “str” → “str” “a” → “mommy” “blah” → “blah” “bla” → “blmommy” “blaa” → “blmommy” “blaaha” → “blmommyhmommy” “blA” → “blmommy” Null → raise exception
  • 73. TEST CASES public void shouldNotMommifyEmptyString public void shouldNotMommifyWordsWithNoVowels public void shouldMommifyVowel public void shouldMommifyConsonantsAndSingleVowel public void shouldNotMommifyLessThan30PercentVowels public void shouldMommifyContinuousVowelsOnlyOnce public void shouldMommifyMultipleSetsOfVowels public void shouldMommifyCapitalVowels public void shouldErrorOnNull
  • 76. THANK YOU Gabriel Gavasso Anand Iyengar Thao Dang Hung Dang Mommifier Dojo by TWU team

Hinweis der Redaktion

  1. This talk will be mainly about what benefits Test Driven Development brings and includes a practical example.
  2. Before we start on TDD, let’s quickly look at testing
  3. Why do we test? For a number of reasons! Testing allows us to verify the behaviour of software and ensures these are not changed unintentionally. It allows us to track bugs. Call out the possible ones and having a test in place prevents it from coming back. It also serves as documentation for the current state of the software.
  4. But if we add tests after we have completed a functionality… How do we make sure we have full test coverage? How can we be confident all cases are covered? How can we prevent bugs from happening in the first place?
  5. This is where TDD comes in!
  6. … or Test Driven Development!
  7. But wait…
  8. … what exactly does TDD even mean?
  9. Test driving means… We write the tests before implementing the code. And then we write the minimum amount of code possible to make this single test pass – baby steps. Then we write another test and the process repeats.
  10. But why test first?
  11. Let’s go back to the questions we asked previously for writing tests after: How can we be more confident about: Test coverage Test cases covered Preventing bugs
  12. Tests written before implementing code
  13. Means that all the code you write should be covered by a test. Writing minimum amount of code to make tests pass means that you won’t have untested code.
  14. This will result in higher test coverage
  15. So yay. What about test cases?
  16. Writing tests first and having high code coverage means the tests reflect exactly what the code does.
  17. Having a very visible list of the current functionality of the software…
  18. …allows you to see which cases are tested and which are missing
  19. Finally bug prevention
  20. TDD creates a mental shift in having more focus on test cases
  21. When we can see all currently tested cases and try and think about which cases are missing it encourages people to think about the edge cases where the software is likely to fail
  22. And what we expect to happen in these cases.
  23. TDD helps address all these questions…
  24. But that’s not all
  25. Having a high level of test coverage means that it is much easier to debug. Just need to go to the test case you want and debug that. This also ensures that we are not breaking functionality when refactoring. Allowing people to be more confident to make bolder and more risky refactorings.
  26. TDD also helps drive out the design of the software. When you write tests first, you think about the usage of the code before writing it, making it more usable. Writing only a minimum necessary amount of code means there are no unnecessary functionality that needs support. You ain’t gonna need it!
  27. Now that we’ve been through why.. Let’s talk about the how
  28. Red – Green – Refactor. Write the test, see your code fail for the right reasons to make sure you’re testing the right thing (red) Make the test pass (green) Only refactor while the tests are green Write a new test and repeat the process
  29. Let’s go through a coding example of TDD
  30. Thinking up different possible test cases
  31. Let’s start with a test. Since the implementation does not exist, it will not compile.
  32. Make the code compile
  33. Now the test fails for the right reason
  34. Minimum step necessary to make it pass.
  35. And it passes
  36. Now we need another test case to force us to add more functionality to the code
  37. It fails for the right reason
  38. Again minimum amount of code to make it pass – remembering to keep the old tests passing too.
  39. And they pass
  40. Adding actual replacement of vowels.
  41. It fails for the right reason
  42. And the logic for vowel replacement is added
  43. Tests all pass
  44. Now that tests pass we can go ahead and refactor
  45. Notice the logic has changed. It’s a step for us to improve our design.
  46. Tests still pass
  47. Since tests are also code we can refactor this too
  48. And they still pass
  49. Adding new tests for actual replace mixed vowels and consonants
  50. It fails for the right reason
  51. And we modify the code to make it pass.
  52. And all tests including old ones still work
  53. Now for the logic of not replacing vowels if it’s less than 30%
  54. It fails for the right reason
  55. we modify the code to make the tests pass
  56. It does
  57. We can then go and refactor the code to make it more readable and maintainable
  58. Making sure our tests still pass
  59. Continuous vowels
  60. Fails for the right reason
  61. Adding logic
  62. Tests pass
  63. How about multiple sets of vowels in a word?
  64. It passes since our code already works with this scenario. Sometimes people like to change the code to see it fail just to make sure it’s passing for the right reason and not because of some coincidence.
  65. How about capital letters?
  66. It fails.
  67. Again making it pass
  68. And it does
  69. Null checks?
  70. It already passes because runtime exceptions.
  71. And we’re done! Let’s look at all the test cases we came up before.
  72. The tests now serve as documentations of these functionality.
  73. In terms of writing different types of tests, I personally prefer to Test Drive from ‘Top down” This means starting out writing higher level tests such as functional tests or integration tests and then using this to drive out your unit tests. And having your unit tests then drive out the implementation.
  74. Here are some books if you’re interested in reading more about TDD: Test Driven Development by example by Kent Beck Refactoring by Martin Fowler
  75. Special thanks – any questions?