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

Andere mochten auch

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 (9)

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
 
Javaone2008 Bof 5101 Groovytesting
Javaone2008 Bof 5101 GroovytestingJavaone2008 Bof 5101 Groovytesting
Javaone2008 Bof 5101 GroovytestingAndres Almiray
 
Boosting Your Testing Productivity with Groovy
Boosting Your Testing Productivity with GroovyBoosting Your Testing Productivity with Groovy
Boosting Your Testing Productivity with GroovyJames Williams
 
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
 
Javaone2008 Bof 5101 Groovytesting
Javaone2008 Bof 5101 GroovytestingJavaone2008 Bof 5101 Groovytesting
Javaone2008 Bof 5101 Groovytesting
 
Boosting Your Testing Productivity with Groovy
Boosting Your Testing Productivity with GroovyBoosting Your Testing Productivity with Groovy
Boosting Your Testing Productivity with Groovy
 
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

Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 

Kürzlich hochgeladen (20)

Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 

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?