SlideShare a Scribd company logo
1 of 47
Download to read offline
Unbearable Test Smells
Steven Mak
steven@odd-e.com
www.odd-e.com
twitter: stevenmak
1
Monday, 15 November 2010
Who am I?
2
Name: Steven Mak
Agile Coach at Odd-e
Lives in Hong Kong
Agile/Scrum, TDD Coaching
I love coding - Java, C/C++,
PHP, Perl, C#, VB, and some
weird languages
Monday, 15 November 2010
Copy and Paste Code
Long test codes are copied and pasted somewhere else with only a few
lines changing
3
Monday, 15 November 2010
DRY
Donʼt Repeat Yourself!
Donʼt Repeat Yourself!
Donʼt Repeat Yourself!
Donʼt Repeat Yourself!
Donʼt Repeat Yourself!
Donʼt Repeat Yourself!
Donʼt Repeat Yourself!
Donʼt Repeat Yourself!
4
Monday, 15 November 2010
Not knowing the fixtures
Some initialisation and clean up codes that are repeated in each tests...
5
Monday, 15 November 2010
What is fixture?
TEST_GROUP (TEST_thisObject)
{
void setup() {
}
void teardown() {
}
};
6
Monday, 15 November 2010
Duplication causing fragile
tests
Where is the duplication?
EXPECT_LOG(“ABC error”);
7
Monday, 15 November 2010
Duplication causing fragile
tests
Where is the duplication?
EXPECT_LOG(“ABC error”);
So there is a line in code that
prints this log message
8
Monday, 15 November 2010
Duplication causing fragile
tests
Put it under centralise header file:
#define ABC_ERROR_WITH_EC “ABC error”
The test will then look like:
EXPECT_LOG(ABC_ERROR);
9
Monday, 15 November 2010
Over-Optimism?
Tests that forgot to cover exceptional cases or just covered the easiest
condition
if (aaa() || bbb() || ccc() {
...
} else {
...
}
10
Monday, 15 November 2010
Tests donʼt have assertions
TEST(TEST_GROUP, TEST_THIS)
{
runThisFunctionLaLaLa();
}
11
Monday, 15 November 2010
12
What does it mean by 80% Unit
Test Coverage?
Monday, 15 November 2010
Why xUnits donʼt have
CHECK_NOT_EQUAL?
What is the problem with:
CHECK(TRUE, xxx != 3);
13
Monday, 15 November 2010
Why xUnits donʼt have
CHECK_NOT_EQUAL?
What is the problem with:
CHECK(TRUE, xxx != 3);
Is there any good reason why you
cannot know the output value?
So, tell me what it is then. 14
Monday, 15 November 2010
OK, fine, so I use CHECK with a
specific output value, what now?
What is the problem with:
CHECK(TRUE, xxx == 4);
15
Monday, 15 November 2010
OK, fine, so I use CHECK with a
specific output value, what now?
What is the problem with:
CHECK(TRUE, xxx == 4);
In most xUnits, we have
LONGS_EQUAL telling you the actual
value when it goes wrong instead of a
“false”
16
Monday, 15 November 2010
17
Do you know your xUnit harness?
Monday, 15 November 2010
Further example

 try {

 
 readConfigurationFile();

 
 assertTrue(true);

 } catch (IOException e) {

 
 assertTrue(false);

 
 e.printStackTrace();

 }
These are the places you know your
team does not know the test harness.
18
Monday, 15 November 2010
19
Some xUnit harness
Java: JUnit
.Net: NUnit
C/C++: CppUTest
PHP: PHPUnit
Monday, 15 November 2010
Whatʼs wrong?
What is the problem with:
TEST(TEST_AIH, FAIL_BAD_PARAM)
20
Monday, 15 November 2010
Names donʼt really tell
What is the problem with:
TEST(TEST_AIH, FAIL_BAD_PARAM)
Be more precise about how it
triggered the failure
21
Monday, 15 November 2010
What names tell us?
• Who
- Name of the SUT class
- Name of the method or feature being exercised
• Input
- Important characteristics of any input values
- Anything relevant about the state
• Output
- The outputs expected
- The expected post-exercise state
22
Monday, 15 November 2010
Conditional Test Logic?
// verify Vancouver is in the list
actual = null;
i = flightsFromCalgary.iterator();
while (i.hasNext()) {

 FlightDto flightDto = (FlightDto) i.next();

 if (flightDto.getFlightNumber().equals(

 
 expectedCalgaryToVan.getFlightNumber()))

 {

 
 actual = flightDto;

 
 assertEquals("Flight from Calgary to Vancouver",

 
 
 expectedCalgaryToVan,

 
 
 flightDto);

 
 break;

 }
}
23
Monday, 15 November 2010
Tests that crash 50% of the
time?!!
24
Monday, 15 November 2010
public void testFlightMileage_asKm2() throws Exception {

 // set up fixture

 // exercise constructor

 Flight newFlight = new Flight(validFlightNumber);

 // verify constructed object

 assertEquals(validFlightNumber, newFlight.number);

 assertEquals("", newFlight.airlineCode);

 assertNull(newFlight.airline);

 // set up mileage

 newFlight.setMileage(1122);

 // exercise mileage translator

 int actualKilometres = newFlight.getMileageAsKm();

 // verify results

 int expectedKilometres = 1810;

 assertEquals( expectedKilometres, actualKilometres);

 // now try it with a canceled flight

 newFlight.cancel();

 try {

 
 newFlight.getMileageAsKm();

 
 fail("Expected exception");

 } catch (InvalidRequestException e) {

 
 assertEquals( "Cannot get cancelled flight mileage",

 
 e.getMessage());

 }
}
25
Testing everything at a time
Monday, 15 November 2010
Testing everything at a time
public void testFlightMileage_asKm2() throws Exception {

 // set up fixture

 // exercise constructor

 Flight newFlight = new Flight(validFlightNumber);

 // verify constructed object

 assertEquals(validFlightNumber, newFlight.number);

 assertEquals("", newFlight.airlineCode);

 assertNull(newFlight.airline);

 // set up mileage

 newFlight.setMileage(1122);

 // exercise mileage translator

 int actualKilometres = newFlight.getMileageAsKm();

 // verify results

 int expectedKilometres = 1810;

 assertEquals( expectedKilometres, actualKilometres);

 // now try it with a canceled flight

 newFlight.cancel();

 try {

 
 newFlight.getMileageAsKm();

 
 fail("Expected exception");

 } catch (InvalidRequestException e) {

 
 assertEquals( "Cannot get cancelled flight mileage",

 
 e.getMessage());

 }
}
26
Comments as
deodorant
Monday, 15 November 2010
Testing everything at a time
public void testFlightMileage_asKm2() throws Exception {

 // set up fixture

 // exercise constructor

 Flight newFlight = new Flight(validFlightNumber);

 // verify constructed object

 assertEquals(validFlightNumber, newFlight.number);

 assertEquals("", newFlight.airlineCode);

 assertNull(newFlight.airline);

 // set up mileage

 newFlight.setMileage(1122);

 // exercise mileage translator

 int actualKilometres = newFlight.getMileageAsKm();

 // verify results

 int expectedKilometres = 1810;

 assertEquals( expectedKilometres, actualKilometres);

 // now try it with a canceled flight

 newFlight.cancel();

 try {

 
 newFlight.getMileageAsKm();

 
 fail("Expected exception");

 } catch (InvalidRequestException e) {

 
 assertEquals( "Cannot get cancelled flight mileage",

 
 e.getMessage());

 }
}
27
Duplications with
application logic?
Monday, 15 November 2010
Inappropriate dependencies
• Test setup depending on other tests files
• A test file depending on another test file
• Stub functions depending on other tests
extern int reg_ecx; // in the stub program
int reg_exc; // in SUT
28
Monday, 15 November 2010
What can we do?
29
Monday, 15 November 2010
Try: one test group per file
But why canʼt? is it because of... ?
30
Monday, 15 November 2010
Test initialisation hard to read
and shared among test groups
in the same test file
• Fixtures
• Test Data Builder
• Parameterised Creation
• make-it-easy
31
Monday, 15 November 2010
Dont forget fixtures
TEST_GROUP (TEST_thisObject)
{

 void setup()

 {

 }

 void teardown()

 {

 }
};
32
Monday, 15 November 2010
Test Data Builder
eth_data_buf
->setControl(2)
->withParameterA(3)
->build();
33
Monday, 15 November 2010
Parameterised Creation
@Before
public void setUp() throws Exception {

 alice = new Person();

 alice.setId(1L);

 alice.setFirstname("Alice");

 alice.setLastname("Adams");

 alice.setSsn("111111");

 billy = new Person();

 billy.setId(2L);

 billy.setFirstname("Billy");

 billy.setLastname("Burke");

 billy.setSsn("222222");

 clark = new Person();

 clark.setId(3L);

 clark.setFirstname("Clark");

 clark.setLastname("Cable");

 clark.setSsn("333333");

 alice.isInLoveWith(billy);
}
34
Monday, 15 November 2010
Parameterised Creation
public class ParameterizedCreationMethodExample {

 private Person alice, billy, clark;

 @Before

 public void setUp() throws Exception {

 
 clark = createPerson("Clark", "Cable");

 
 billy = createPerson("Billy", "Burke");

 
 alice = createPerson("Alice", "Adams");

 
 alice.isInLoveWith(billy);

 }

 private Person createPerson(String firstName, String lastName) {

 
 Person person = new Person();

 
 person.setFirstname(firstName);

 
 person.setLastname(lastName);

 
 person.setId(UniqueNumber.next());

 
 person.setSsn(String.valueOf(UniqueNumber.next()));

 
 return person;

 }

 @Test

 public void aliceShouldAcceptWhenProposedToByBilly()

 
 throws Exception {

 
 billy.proposeTo(alice);

 
 assertTrue(alice.isEngagedWith(billy));

 }
}
35
Monday, 15 November 2010
make-it-easy
36
http://code.google.com/p/make-it-easy/
Maker<Apple> appleWith2Leaves = an(Apple, with(2, leaves));
Maker<Apple> ripeApple = appleWith2Leaves.but(with(ripeness, 0.9));
Maker<Apple> unripeApple = appleWith2Leaves.but(with(ripeness, 0.125));
       
Apple apple1 = make(ripeApple);
Apple apple2 = make(unripeApple);
       
Banana defaultBanana = make(a(Banana));
Banana straightBanana = make(a(Banana, with(curve, 0.0)));
Banana squishyBanana = make(a(Banana, with(ripeness, 1.0)));
Monday, 15 November 2010
Try: One assertion per test
37
Monday, 15 November 2010
Customised Assertions
#define CHECK_OBJ(a,b) CHECK_OBJ(a,b, __FILE__,__FILE__)
void CHECK_OBJ(struct* yourObj, struct* myObj, const char* file, int line)
{

 if (structs are not equal) {

 
 SimpleString errorMessage = StringFromFormat(

 
 
 “My struct: %d, %p, %s”, myObj->d, myObj->p, myObj->s);

 
 FAIL_LOCATION(errorMessage.asCharString(), file, line);

 }
}
38
Monday, 15 November 2010
At least: One concept per test
39
Monday, 15 November 2010
Hamcrest
• Framework for writing declarative match criteria
40http://code.google.com/p/hamcrest/
String s = "yes we have no bananas today";
Matcher<String> containsBananas = new StringContains("bananas");
Matcher<String> containsMangoes = new StringContains("mangoes");
assertTrue(containsBananas.matches(s));
assertFalse(containsMangoes.matches(s));
assertThat(s, containsString("bananas"));
assertThat(s, not(containsString("mangoes"));
Or even better
Monday, 15 November 2010
Meaningful Assertion Messages
41
• Donʼt repeat what the built-in test framework
outputs to the console (e.g. name of the test
method)
• Donʼt repeat what the test name explains
• If you donʼt have anything good to say, you donʼt
have to say anything
• Write what should have happened, or what failed
to happen, and possibly mention when it should
have happened
Monday, 15 November 2010
Itʼs Design Smell!!!
42
Monday, 15 November 2010
Extra Constructor
43
public class LogFileMerge {

 private URL logFileA, logFileB;

 public LogFileMerge() {

 
 this(new URL("http://server1/system.log"),

 
 new URL("http://server2/system.log"));

 }

 LogFileMerge(URL a, URL b) {

 
 this.logFileA = a;

 
 this.logFileB = b;

 }
}
Monday, 15 November 2010
Test-Specific SubClass
44
public class CreditCardProcessing {

 public boolean isValid(String cardnumber) {

 
 return validationCodeMatches(cardnumber)

 
 
 && cardIsActive(cardnumber);

 }

 protected boolean validationCodeMatches(String cardnumber) {

 
 // validation logic omitted for brevity...

 }

 protected boolean cardIsActive(String cardnumber) {

 
 // access to merchant system's web service

 
 // omitted for brevity...

 }
}
Monday, 15 November 2010
Still not testable?
45
• Do you follow good design principles?
Monday, 15 November 2010
Thinking
46
Test code is not second class citizen
Good design principles apply:
• Responsibility
• Dependency
• Low Coupling
• High Cohesion
• Indirection
• Protected Variations
Watch out for organisational dysfunction!
Monday, 15 November 2010
References
• Practical TDD and ATDD for Java Developers - Lasse Koskela
• Growing OO Software, guided by tests - Steve Freeman
• xUnit Test Patterns - Gerard Meszaros
47
Steven Mak
steven@odd-e.com
www.odd-e.com
twitter: stevenmak
Monday, 15 November 2010

More Related Content

What's hot

Introduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxIntroduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxDavid Rodenas
 
Software Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW SydneySoftware Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW Sydneyjulien.ponge
 
ReactJS for Programmers
ReactJS for ProgrammersReactJS for Programmers
ReactJS for ProgrammersDavid Rodenas
 
Kotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresKotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresiMasters
 
Proxies are Awesome!
Proxies are Awesome!Proxies are Awesome!
Proxies are Awesome!Brendan Eich
 
Using Reflections and Automatic Code Generation
Using Reflections and Automatic Code GenerationUsing Reflections and Automatic Code Generation
Using Reflections and Automatic Code GenerationIvan Dolgushin
 
0003 es5 핵심 정리
0003 es5 핵심 정리0003 es5 핵심 정리
0003 es5 핵심 정리욱래 김
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleThierry Wasylczenko
 
TDC2016SP - Trilha .NET
TDC2016SP - Trilha .NETTDC2016SP - Trilha .NET
TDC2016SP - Trilha .NETtdc-globalcode
 
JavaScript Survival Guide
JavaScript Survival GuideJavaScript Survival Guide
JavaScript Survival GuideGiordano Scalzo
 
G*におけるソフトウェアテスト・シーズンIII
G*におけるソフトウェアテスト・シーズンIIIG*におけるソフトウェアテスト・シーズンIII
G*におけるソフトウェアテスト・シーズンIIITakuma Watabiki
 
Spock Testing Framework - The Next Generation
Spock Testing Framework - The Next GenerationSpock Testing Framework - The Next Generation
Spock Testing Framework - The Next GenerationBTI360
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS ProgrammersDavid Rodenas
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good TestsTomek Kaczanowski
 
ES3-2020-06 Test Driven Development (TDD)
ES3-2020-06 Test Driven Development (TDD)ES3-2020-06 Test Driven Development (TDD)
ES3-2020-06 Test Driven Development (TDD)David Rodenas
 
ES6 PPT FOR 2016
ES6 PPT FOR 2016ES6 PPT FOR 2016
ES6 PPT FOR 2016Manoj Kumar
 

What's hot (20)

Introduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxIntroduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicox
 
Software Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW SydneySoftware Testing - Invited Lecture at UNSW Sydney
Software Testing - Invited Lecture at UNSW Sydney
 
ReactJS for Programmers
ReactJS for ProgrammersReactJS for Programmers
ReactJS for Programmers
 
Kotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan SoaresKotlin : Advanced Tricks - Ubiratan Soares
Kotlin : Advanced Tricks - Ubiratan Soares
 
Proxies are Awesome!
Proxies are Awesome!Proxies are Awesome!
Proxies are Awesome!
 
Using Reflections and Automatic Code Generation
Using Reflections and Automatic Code GenerationUsing Reflections and Automatic Code Generation
Using Reflections and Automatic Code Generation
 
EcmaScript 6
EcmaScript 6 EcmaScript 6
EcmaScript 6
 
0003 es5 핵심 정리
0003 es5 핵심 정리0003 es5 핵심 정리
0003 es5 핵심 정리
 
Easy Button
Easy ButtonEasy Button
Easy Button
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
 
TDC2016SP - Trilha .NET
TDC2016SP - Trilha .NETTDC2016SP - Trilha .NET
TDC2016SP - Trilha .NET
 
JavaScript Survival Guide
JavaScript Survival GuideJavaScript Survival Guide
JavaScript Survival Guide
 
G*におけるソフトウェアテスト・シーズンIII
G*におけるソフトウェアテスト・シーズンIIIG*におけるソフトウェアテスト・シーズンIII
G*におけるソフトウェアテスト・シーズンIII
 
Spock Testing Framework - The Next Generation
Spock Testing Framework - The Next GenerationSpock Testing Framework - The Next Generation
Spock Testing Framework - The Next Generation
 
Redux for ReactJS Programmers
Redux for ReactJS ProgrammersRedux for ReactJS Programmers
Redux for ReactJS Programmers
 
2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests2012 JDays Bad Tests Good Tests
2012 JDays Bad Tests Good Tests
 
#JavaFX.forReal() - ElsassJUG
#JavaFX.forReal() - ElsassJUG#JavaFX.forReal() - ElsassJUG
#JavaFX.forReal() - ElsassJUG
 
ES6 in Real Life
ES6 in Real LifeES6 in Real Life
ES6 in Real Life
 
ES3-2020-06 Test Driven Development (TDD)
ES3-2020-06 Test Driven Development (TDD)ES3-2020-06 Test Driven Development (TDD)
ES3-2020-06 Test Driven Development (TDD)
 
ES6 PPT FOR 2016
ES6 PPT FOR 2016ES6 PPT FOR 2016
ES6 PPT FOR 2016
 

Similar to Unbearable Test Code Smell

Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516SOAT
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good TestsTomek Kaczanowski
 
Conf soat tests_unitaires_Mockito_jUnit_170113
Conf soat tests_unitaires_Mockito_jUnit_170113Conf soat tests_unitaires_Mockito_jUnit_170113
Conf soat tests_unitaires_Mockito_jUnit_170113SOAT
 
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017 Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017 Codemotion
 
Developer Test - Things to Know
Developer Test - Things to KnowDeveloper Test - Things to Know
Developer Test - Things to Knowvilniusjug
 
Dat testing - An introduction to Java and Android Testing
Dat testing - An introduction to Java and Android TestingDat testing - An introduction to Java and Android Testing
Dat testing - An introduction to Java and Android TestingSaúl Díaz González
 
Imagine a world without mocks
Imagine a world without mocksImagine a world without mocks
Imagine a world without mockskenbot
 
JavaScript Iteration Protocols - Workshop NodeConf EU 2022
JavaScript Iteration Protocols - Workshop NodeConf EU 2022JavaScript Iteration Protocols - Workshop NodeConf EU 2022
JavaScript Iteration Protocols - Workshop NodeConf EU 2022Luciano Mammino
 
Workshop 5: JavaScript testing
Workshop 5: JavaScript testingWorkshop 5: JavaScript testing
Workshop 5: JavaScript testingVisual Engineering
 
Improving the java type system
Improving the java type systemImproving the java type system
Improving the java type systemJoão Loff
 
Javascript: the important bits
Javascript: the important bitsJavascript: the important bits
Javascript: the important bitsChris Saylor
 
Whats new in_csharp4
Whats new in_csharp4Whats new in_csharp4
Whats new in_csharp4Abed Bukhari
 
Cool JVM Tools to Help You Test
Cool JVM Tools to Help You TestCool JVM Tools to Help You Test
Cool JVM Tools to Help You TestSchalk Cronjé
 
Kotlin Overview (PT-BR)
Kotlin Overview (PT-BR)Kotlin Overview (PT-BR)
Kotlin Overview (PT-BR)ThomasHorta
 

Similar to Unbearable Test Code Smell (20)

Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
 
Conf soat tests_unitaires_Mockito_jUnit_170113
Conf soat tests_unitaires_Mockito_jUnit_170113Conf soat tests_unitaires_Mockito_jUnit_170113
Conf soat tests_unitaires_Mockito_jUnit_170113
 
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017 Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
 
A Test of Strength
A Test of StrengthA Test of Strength
A Test of Strength
 
Developer Test - Things to Know
Developer Test - Things to KnowDeveloper Test - Things to Know
Developer Test - Things to Know
 
Dat testing - An introduction to Java and Android Testing
Dat testing - An introduction to Java and Android TestingDat testing - An introduction to Java and Android Testing
Dat testing - An introduction to Java and Android Testing
 
Imagine a world without mocks
Imagine a world without mocksImagine a world without mocks
Imagine a world without mocks
 
JavaScript Iteration Protocols - Workshop NodeConf EU 2022
JavaScript Iteration Protocols - Workshop NodeConf EU 2022JavaScript Iteration Protocols - Workshop NodeConf EU 2022
JavaScript Iteration Protocols - Workshop NodeConf EU 2022
 
Kotlin Generation
Kotlin GenerationKotlin Generation
Kotlin Generation
 
Workshop 5: JavaScript testing
Workshop 5: JavaScript testingWorkshop 5: JavaScript testing
Workshop 5: JavaScript testing
 
Improving the java type system
Improving the java type systemImproving the java type system
Improving the java type system
 
Javascript: the important bits
Javascript: the important bitsJavascript: the important bits
Javascript: the important bits
 
Whats new in_csharp4
Whats new in_csharp4Whats new in_csharp4
Whats new in_csharp4
 
Writing Good Tests
Writing Good TestsWriting Good Tests
Writing Good Tests
 
Kotlin
KotlinKotlin
Kotlin
 
C# labprograms
C# labprogramsC# labprograms
C# labprograms
 
Cool JVM Tools to Help You Test
Cool JVM Tools to Help You TestCool JVM Tools to Help You Test
Cool JVM Tools to Help You Test
 
Kotlin Overview (PT-BR)
Kotlin Overview (PT-BR)Kotlin Overview (PT-BR)
Kotlin Overview (PT-BR)
 
Google guava
Google guavaGoogle guava
Google guava
 

More from Steven Mak

Continuous Security Testing
Continuous Security TestingContinuous Security Testing
Continuous Security TestingSteven Mak
 
Quality comes free with open source testing tools
Quality comes free with open source testing toolsQuality comes free with open source testing tools
Quality comes free with open source testing toolsSteven Mak
 
Adopting technical practices 2013
Adopting technical practices 2013Adopting technical practices 2013
Adopting technical practices 2013Steven Mak
 
100 doors kata solution
100 doors kata solution100 doors kata solution
100 doors kata solutionSteven Mak
 
Bossless companies
Bossless companiesBossless companies
Bossless companiesSteven Mak
 
Is this how you hate unit testing?
Is this how you hate unit testing?Is this how you hate unit testing?
Is this how you hate unit testing?Steven Mak
 
Driving Quality with TDD
Driving Quality with TDDDriving Quality with TDD
Driving Quality with TDDSteven Mak
 
Sustainable TDD
Sustainable TDDSustainable TDD
Sustainable TDDSteven Mak
 
Introduction to Acceptance Test Driven Development
Introduction to Acceptance Test Driven DevelopmentIntroduction to Acceptance Test Driven Development
Introduction to Acceptance Test Driven DevelopmentSteven Mak
 
Essential practices and thinking tools for Agile Adoption
Essential practices and thinking tools for Agile AdoptionEssential practices and thinking tools for Agile Adoption
Essential practices and thinking tools for Agile AdoptionSteven Mak
 
ATDD in Practice
ATDD in PracticeATDD in Practice
ATDD in PracticeSteven Mak
 

More from Steven Mak (11)

Continuous Security Testing
Continuous Security TestingContinuous Security Testing
Continuous Security Testing
 
Quality comes free with open source testing tools
Quality comes free with open source testing toolsQuality comes free with open source testing tools
Quality comes free with open source testing tools
 
Adopting technical practices 2013
Adopting technical practices 2013Adopting technical practices 2013
Adopting technical practices 2013
 
100 doors kata solution
100 doors kata solution100 doors kata solution
100 doors kata solution
 
Bossless companies
Bossless companiesBossless companies
Bossless companies
 
Is this how you hate unit testing?
Is this how you hate unit testing?Is this how you hate unit testing?
Is this how you hate unit testing?
 
Driving Quality with TDD
Driving Quality with TDDDriving Quality with TDD
Driving Quality with TDD
 
Sustainable TDD
Sustainable TDDSustainable TDD
Sustainable TDD
 
Introduction to Acceptance Test Driven Development
Introduction to Acceptance Test Driven DevelopmentIntroduction to Acceptance Test Driven Development
Introduction to Acceptance Test Driven Development
 
Essential practices and thinking tools for Agile Adoption
Essential practices and thinking tools for Agile AdoptionEssential practices and thinking tools for Agile Adoption
Essential practices and thinking tools for Agile Adoption
 
ATDD in Practice
ATDD in PracticeATDD in Practice
ATDD in Practice
 

Recently uploaded

Escorts Service Nagavara ☎ 7737669865☎ Book Your One night Stand (Bangalore)
Escorts Service Nagavara ☎ 7737669865☎ Book Your One night Stand (Bangalore)Escorts Service Nagavara ☎ 7737669865☎ Book Your One night Stand (Bangalore)
Escorts Service Nagavara ☎ 7737669865☎ Book Your One night Stand (Bangalore)amitlee9823
 
VVIP Pune Call Girls Hadapsar (7001035870) Pune Escorts Nearby with Complete ...
VVIP Pune Call Girls Hadapsar (7001035870) Pune Escorts Nearby with Complete ...VVIP Pune Call Girls Hadapsar (7001035870) Pune Escorts Nearby with Complete ...
VVIP Pune Call Girls Hadapsar (7001035870) Pune Escorts Nearby with Complete ...Call Girls in Nagpur High Profile
 
VIP Call Girls Service Bhagyanagar Hyderabad Call +91-8250192130
VIP Call Girls Service Bhagyanagar Hyderabad Call +91-8250192130VIP Call Girls Service Bhagyanagar Hyderabad Call +91-8250192130
VIP Call Girls Service Bhagyanagar Hyderabad Call +91-8250192130Suhani Kapoor
 
DragonBall PowerPoint Template for demo.pptx
DragonBall PowerPoint Template for demo.pptxDragonBall PowerPoint Template for demo.pptx
DragonBall PowerPoint Template for demo.pptxmirandajeremy200221
 
WAEC Carpentry and Joinery Past Questions
WAEC Carpentry and Joinery Past QuestionsWAEC Carpentry and Joinery Past Questions
WAEC Carpentry and Joinery Past QuestionsCharles Obaleagbon
 
Best VIP Call Girls Noida Sector 44 Call Me: 8448380779
Best VIP Call Girls Noida Sector 44 Call Me: 8448380779Best VIP Call Girls Noida Sector 44 Call Me: 8448380779
Best VIP Call Girls Noida Sector 44 Call Me: 8448380779Delhi Call girls
 
The_Canvas_of_Creative_Mastery_Newsletter_April_2024_Version.pdf
The_Canvas_of_Creative_Mastery_Newsletter_April_2024_Version.pdfThe_Canvas_of_Creative_Mastery_Newsletter_April_2024_Version.pdf
The_Canvas_of_Creative_Mastery_Newsletter_April_2024_Version.pdfAmirYakdi
 
Design Inspiration for College by Slidesgo.pptx
Design Inspiration for College by Slidesgo.pptxDesign Inspiration for College by Slidesgo.pptx
Design Inspiration for College by Slidesgo.pptxTusharBahuguna2
 
VIP Model Call Girls Kalyani Nagar ( Pune ) Call ON 8005736733 Starting From ...
VIP Model Call Girls Kalyani Nagar ( Pune ) Call ON 8005736733 Starting From ...VIP Model Call Girls Kalyani Nagar ( Pune ) Call ON 8005736733 Starting From ...
VIP Model Call Girls Kalyani Nagar ( Pune ) Call ON 8005736733 Starting From ...SUHANI PANDEY
 
CALL ON ➥8923113531 🔝Call Girls Kalyanpur Lucknow best Female service 🧵
CALL ON ➥8923113531 🔝Call Girls Kalyanpur Lucknow best Female service  🧵CALL ON ➥8923113531 🔝Call Girls Kalyanpur Lucknow best Female service  🧵
CALL ON ➥8923113531 🔝Call Girls Kalyanpur Lucknow best Female service 🧵anilsa9823
 
Top Rated Pune Call Girls Koregaon Park ⟟ 6297143586 ⟟ Call Me For Genuine S...
Top Rated  Pune Call Girls Koregaon Park ⟟ 6297143586 ⟟ Call Me For Genuine S...Top Rated  Pune Call Girls Koregaon Park ⟟ 6297143586 ⟟ Call Me For Genuine S...
Top Rated Pune Call Girls Koregaon Park ⟟ 6297143586 ⟟ Call Me For Genuine S...Call Girls in Nagpur High Profile
 
Escorts Service Basapura ☎ 7737669865☎ Book Your One night Stand (Bangalore)
Escorts Service Basapura ☎ 7737669865☎ Book Your One night Stand (Bangalore)Escorts Service Basapura ☎ 7737669865☎ Book Your One night Stand (Bangalore)
Escorts Service Basapura ☎ 7737669865☎ Book Your One night Stand (Bangalore)amitlee9823
 
Chapter 19_DDA_TOD Policy_First Draft 2012.pdf
Chapter 19_DDA_TOD Policy_First Draft 2012.pdfChapter 19_DDA_TOD Policy_First Draft 2012.pdf
Chapter 19_DDA_TOD Policy_First Draft 2012.pdfParomita Roy
 
The history of music videos a level presentation
The history of music videos a level presentationThe history of music videos a level presentation
The history of music videos a level presentationamedia6
 
Pooja 9892124323, Call girls Services and Mumbai Escort Service Near Hotel Gi...
Pooja 9892124323, Call girls Services and Mumbai Escort Service Near Hotel Gi...Pooja 9892124323, Call girls Services and Mumbai Escort Service Near Hotel Gi...
Pooja 9892124323, Call girls Services and Mumbai Escort Service Near Hotel Gi...Pooja Nehwal
 
VIP Call Girls Service Kukatpally Hyderabad Call +91-8250192130
VIP Call Girls Service Kukatpally Hyderabad Call +91-8250192130VIP Call Girls Service Kukatpally Hyderabad Call +91-8250192130
VIP Call Girls Service Kukatpally Hyderabad Call +91-8250192130Suhani Kapoor
 
Booking open Available Pune Call Girls Kirkatwadi 6297143586 Call Hot Indian...
Booking open Available Pune Call Girls Kirkatwadi  6297143586 Call Hot Indian...Booking open Available Pune Call Girls Kirkatwadi  6297143586 Call Hot Indian...
Booking open Available Pune Call Girls Kirkatwadi 6297143586 Call Hot Indian...Call Girls in Nagpur High Profile
 
Fashion trends before and after covid.pptx
Fashion trends before and after covid.pptxFashion trends before and after covid.pptx
Fashion trends before and after covid.pptxVanshNarang19
 

Recently uploaded (20)

Escorts Service Nagavara ☎ 7737669865☎ Book Your One night Stand (Bangalore)
Escorts Service Nagavara ☎ 7737669865☎ Book Your One night Stand (Bangalore)Escorts Service Nagavara ☎ 7737669865☎ Book Your One night Stand (Bangalore)
Escorts Service Nagavara ☎ 7737669865☎ Book Your One night Stand (Bangalore)
 
꧁❤ Hauz Khas Call Girls Service Hauz Khas Delhi ❤꧂ 9999965857 ☎️ Hard And Sex...
꧁❤ Hauz Khas Call Girls Service Hauz Khas Delhi ❤꧂ 9999965857 ☎️ Hard And Sex...꧁❤ Hauz Khas Call Girls Service Hauz Khas Delhi ❤꧂ 9999965857 ☎️ Hard And Sex...
꧁❤ Hauz Khas Call Girls Service Hauz Khas Delhi ❤꧂ 9999965857 ☎️ Hard And Sex...
 
VVIP Pune Call Girls Hadapsar (7001035870) Pune Escorts Nearby with Complete ...
VVIP Pune Call Girls Hadapsar (7001035870) Pune Escorts Nearby with Complete ...VVIP Pune Call Girls Hadapsar (7001035870) Pune Escorts Nearby with Complete ...
VVIP Pune Call Girls Hadapsar (7001035870) Pune Escorts Nearby with Complete ...
 
VIP Call Girls Service Bhagyanagar Hyderabad Call +91-8250192130
VIP Call Girls Service Bhagyanagar Hyderabad Call +91-8250192130VIP Call Girls Service Bhagyanagar Hyderabad Call +91-8250192130
VIP Call Girls Service Bhagyanagar Hyderabad Call +91-8250192130
 
DragonBall PowerPoint Template for demo.pptx
DragonBall PowerPoint Template for demo.pptxDragonBall PowerPoint Template for demo.pptx
DragonBall PowerPoint Template for demo.pptx
 
WAEC Carpentry and Joinery Past Questions
WAEC Carpentry and Joinery Past QuestionsWAEC Carpentry and Joinery Past Questions
WAEC Carpentry and Joinery Past Questions
 
Best VIP Call Girls Noida Sector 44 Call Me: 8448380779
Best VIP Call Girls Noida Sector 44 Call Me: 8448380779Best VIP Call Girls Noida Sector 44 Call Me: 8448380779
Best VIP Call Girls Noida Sector 44 Call Me: 8448380779
 
Call Girls Service Mukherjee Nagar @9999965857 Delhi 🫦 No Advance VVIP 🍎 SER...
Call Girls Service Mukherjee Nagar @9999965857 Delhi 🫦 No Advance  VVIP 🍎 SER...Call Girls Service Mukherjee Nagar @9999965857 Delhi 🫦 No Advance  VVIP 🍎 SER...
Call Girls Service Mukherjee Nagar @9999965857 Delhi 🫦 No Advance VVIP 🍎 SER...
 
The_Canvas_of_Creative_Mastery_Newsletter_April_2024_Version.pdf
The_Canvas_of_Creative_Mastery_Newsletter_April_2024_Version.pdfThe_Canvas_of_Creative_Mastery_Newsletter_April_2024_Version.pdf
The_Canvas_of_Creative_Mastery_Newsletter_April_2024_Version.pdf
 
Design Inspiration for College by Slidesgo.pptx
Design Inspiration for College by Slidesgo.pptxDesign Inspiration for College by Slidesgo.pptx
Design Inspiration for College by Slidesgo.pptx
 
VIP Model Call Girls Kalyani Nagar ( Pune ) Call ON 8005736733 Starting From ...
VIP Model Call Girls Kalyani Nagar ( Pune ) Call ON 8005736733 Starting From ...VIP Model Call Girls Kalyani Nagar ( Pune ) Call ON 8005736733 Starting From ...
VIP Model Call Girls Kalyani Nagar ( Pune ) Call ON 8005736733 Starting From ...
 
CALL ON ➥8923113531 🔝Call Girls Kalyanpur Lucknow best Female service 🧵
CALL ON ➥8923113531 🔝Call Girls Kalyanpur Lucknow best Female service  🧵CALL ON ➥8923113531 🔝Call Girls Kalyanpur Lucknow best Female service  🧵
CALL ON ➥8923113531 🔝Call Girls Kalyanpur Lucknow best Female service 🧵
 
Top Rated Pune Call Girls Koregaon Park ⟟ 6297143586 ⟟ Call Me For Genuine S...
Top Rated  Pune Call Girls Koregaon Park ⟟ 6297143586 ⟟ Call Me For Genuine S...Top Rated  Pune Call Girls Koregaon Park ⟟ 6297143586 ⟟ Call Me For Genuine S...
Top Rated Pune Call Girls Koregaon Park ⟟ 6297143586 ⟟ Call Me For Genuine S...
 
Escorts Service Basapura ☎ 7737669865☎ Book Your One night Stand (Bangalore)
Escorts Service Basapura ☎ 7737669865☎ Book Your One night Stand (Bangalore)Escorts Service Basapura ☎ 7737669865☎ Book Your One night Stand (Bangalore)
Escorts Service Basapura ☎ 7737669865☎ Book Your One night Stand (Bangalore)
 
Chapter 19_DDA_TOD Policy_First Draft 2012.pdf
Chapter 19_DDA_TOD Policy_First Draft 2012.pdfChapter 19_DDA_TOD Policy_First Draft 2012.pdf
Chapter 19_DDA_TOD Policy_First Draft 2012.pdf
 
The history of music videos a level presentation
The history of music videos a level presentationThe history of music videos a level presentation
The history of music videos a level presentation
 
Pooja 9892124323, Call girls Services and Mumbai Escort Service Near Hotel Gi...
Pooja 9892124323, Call girls Services and Mumbai Escort Service Near Hotel Gi...Pooja 9892124323, Call girls Services and Mumbai Escort Service Near Hotel Gi...
Pooja 9892124323, Call girls Services and Mumbai Escort Service Near Hotel Gi...
 
VIP Call Girls Service Kukatpally Hyderabad Call +91-8250192130
VIP Call Girls Service Kukatpally Hyderabad Call +91-8250192130VIP Call Girls Service Kukatpally Hyderabad Call +91-8250192130
VIP Call Girls Service Kukatpally Hyderabad Call +91-8250192130
 
Booking open Available Pune Call Girls Kirkatwadi 6297143586 Call Hot Indian...
Booking open Available Pune Call Girls Kirkatwadi  6297143586 Call Hot Indian...Booking open Available Pune Call Girls Kirkatwadi  6297143586 Call Hot Indian...
Booking open Available Pune Call Girls Kirkatwadi 6297143586 Call Hot Indian...
 
Fashion trends before and after covid.pptx
Fashion trends before and after covid.pptxFashion trends before and after covid.pptx
Fashion trends before and after covid.pptx
 

Unbearable Test Code Smell

  • 1. Unbearable Test Smells Steven Mak steven@odd-e.com www.odd-e.com twitter: stevenmak 1 Monday, 15 November 2010
  • 2. Who am I? 2 Name: Steven Mak Agile Coach at Odd-e Lives in Hong Kong Agile/Scrum, TDD Coaching I love coding - Java, C/C++, PHP, Perl, C#, VB, and some weird languages Monday, 15 November 2010
  • 3. Copy and Paste Code Long test codes are copied and pasted somewhere else with only a few lines changing 3 Monday, 15 November 2010
  • 4. DRY Donʼt Repeat Yourself! Donʼt Repeat Yourself! Donʼt Repeat Yourself! Donʼt Repeat Yourself! Donʼt Repeat Yourself! Donʼt Repeat Yourself! Donʼt Repeat Yourself! Donʼt Repeat Yourself! 4 Monday, 15 November 2010
  • 5. Not knowing the fixtures Some initialisation and clean up codes that are repeated in each tests... 5 Monday, 15 November 2010
  • 6. What is fixture? TEST_GROUP (TEST_thisObject) { void setup() { } void teardown() { } }; 6 Monday, 15 November 2010
  • 7. Duplication causing fragile tests Where is the duplication? EXPECT_LOG(“ABC error”); 7 Monday, 15 November 2010
  • 8. Duplication causing fragile tests Where is the duplication? EXPECT_LOG(“ABC error”); So there is a line in code that prints this log message 8 Monday, 15 November 2010
  • 9. Duplication causing fragile tests Put it under centralise header file: #define ABC_ERROR_WITH_EC “ABC error” The test will then look like: EXPECT_LOG(ABC_ERROR); 9 Monday, 15 November 2010
  • 10. Over-Optimism? Tests that forgot to cover exceptional cases or just covered the easiest condition if (aaa() || bbb() || ccc() { ... } else { ... } 10 Monday, 15 November 2010
  • 11. Tests donʼt have assertions TEST(TEST_GROUP, TEST_THIS) { runThisFunctionLaLaLa(); } 11 Monday, 15 November 2010
  • 12. 12 What does it mean by 80% Unit Test Coverage? Monday, 15 November 2010
  • 13. Why xUnits donʼt have CHECK_NOT_EQUAL? What is the problem with: CHECK(TRUE, xxx != 3); 13 Monday, 15 November 2010
  • 14. Why xUnits donʼt have CHECK_NOT_EQUAL? What is the problem with: CHECK(TRUE, xxx != 3); Is there any good reason why you cannot know the output value? So, tell me what it is then. 14 Monday, 15 November 2010
  • 15. OK, fine, so I use CHECK with a specific output value, what now? What is the problem with: CHECK(TRUE, xxx == 4); 15 Monday, 15 November 2010
  • 16. OK, fine, so I use CHECK with a specific output value, what now? What is the problem with: CHECK(TRUE, xxx == 4); In most xUnits, we have LONGS_EQUAL telling you the actual value when it goes wrong instead of a “false” 16 Monday, 15 November 2010
  • 17. 17 Do you know your xUnit harness? Monday, 15 November 2010
  • 18. Further example try { readConfigurationFile(); assertTrue(true); } catch (IOException e) { assertTrue(false); e.printStackTrace(); } These are the places you know your team does not know the test harness. 18 Monday, 15 November 2010
  • 19. 19 Some xUnit harness Java: JUnit .Net: NUnit C/C++: CppUTest PHP: PHPUnit Monday, 15 November 2010
  • 20. Whatʼs wrong? What is the problem with: TEST(TEST_AIH, FAIL_BAD_PARAM) 20 Monday, 15 November 2010
  • 21. Names donʼt really tell What is the problem with: TEST(TEST_AIH, FAIL_BAD_PARAM) Be more precise about how it triggered the failure 21 Monday, 15 November 2010
  • 22. What names tell us? • Who - Name of the SUT class - Name of the method or feature being exercised • Input - Important characteristics of any input values - Anything relevant about the state • Output - The outputs expected - The expected post-exercise state 22 Monday, 15 November 2010
  • 23. Conditional Test Logic? // verify Vancouver is in the list actual = null; i = flightsFromCalgary.iterator(); while (i.hasNext()) { FlightDto flightDto = (FlightDto) i.next(); if (flightDto.getFlightNumber().equals( expectedCalgaryToVan.getFlightNumber())) { actual = flightDto; assertEquals("Flight from Calgary to Vancouver", expectedCalgaryToVan, flightDto); break; } } 23 Monday, 15 November 2010
  • 24. Tests that crash 50% of the time?!! 24 Monday, 15 November 2010
  • 25. public void testFlightMileage_asKm2() throws Exception { // set up fixture // exercise constructor Flight newFlight = new Flight(validFlightNumber); // verify constructed object assertEquals(validFlightNumber, newFlight.number); assertEquals("", newFlight.airlineCode); assertNull(newFlight.airline); // set up mileage newFlight.setMileage(1122); // exercise mileage translator int actualKilometres = newFlight.getMileageAsKm(); // verify results int expectedKilometres = 1810; assertEquals( expectedKilometres, actualKilometres); // now try it with a canceled flight newFlight.cancel(); try { newFlight.getMileageAsKm(); fail("Expected exception"); } catch (InvalidRequestException e) { assertEquals( "Cannot get cancelled flight mileage", e.getMessage()); } } 25 Testing everything at a time Monday, 15 November 2010
  • 26. Testing everything at a time public void testFlightMileage_asKm2() throws Exception { // set up fixture // exercise constructor Flight newFlight = new Flight(validFlightNumber); // verify constructed object assertEquals(validFlightNumber, newFlight.number); assertEquals("", newFlight.airlineCode); assertNull(newFlight.airline); // set up mileage newFlight.setMileage(1122); // exercise mileage translator int actualKilometres = newFlight.getMileageAsKm(); // verify results int expectedKilometres = 1810; assertEquals( expectedKilometres, actualKilometres); // now try it with a canceled flight newFlight.cancel(); try { newFlight.getMileageAsKm(); fail("Expected exception"); } catch (InvalidRequestException e) { assertEquals( "Cannot get cancelled flight mileage", e.getMessage()); } } 26 Comments as deodorant Monday, 15 November 2010
  • 27. Testing everything at a time public void testFlightMileage_asKm2() throws Exception { // set up fixture // exercise constructor Flight newFlight = new Flight(validFlightNumber); // verify constructed object assertEquals(validFlightNumber, newFlight.number); assertEquals("", newFlight.airlineCode); assertNull(newFlight.airline); // set up mileage newFlight.setMileage(1122); // exercise mileage translator int actualKilometres = newFlight.getMileageAsKm(); // verify results int expectedKilometres = 1810; assertEquals( expectedKilometres, actualKilometres); // now try it with a canceled flight newFlight.cancel(); try { newFlight.getMileageAsKm(); fail("Expected exception"); } catch (InvalidRequestException e) { assertEquals( "Cannot get cancelled flight mileage", e.getMessage()); } } 27 Duplications with application logic? Monday, 15 November 2010
  • 28. Inappropriate dependencies • Test setup depending on other tests files • A test file depending on another test file • Stub functions depending on other tests extern int reg_ecx; // in the stub program int reg_exc; // in SUT 28 Monday, 15 November 2010
  • 29. What can we do? 29 Monday, 15 November 2010
  • 30. Try: one test group per file But why canʼt? is it because of... ? 30 Monday, 15 November 2010
  • 31. Test initialisation hard to read and shared among test groups in the same test file • Fixtures • Test Data Builder • Parameterised Creation • make-it-easy 31 Monday, 15 November 2010
  • 32. Dont forget fixtures TEST_GROUP (TEST_thisObject) { void setup() { } void teardown() { } }; 32 Monday, 15 November 2010
  • 34. Parameterised Creation @Before public void setUp() throws Exception { alice = new Person(); alice.setId(1L); alice.setFirstname("Alice"); alice.setLastname("Adams"); alice.setSsn("111111"); billy = new Person(); billy.setId(2L); billy.setFirstname("Billy"); billy.setLastname("Burke"); billy.setSsn("222222"); clark = new Person(); clark.setId(3L); clark.setFirstname("Clark"); clark.setLastname("Cable"); clark.setSsn("333333"); alice.isInLoveWith(billy); } 34 Monday, 15 November 2010
  • 35. Parameterised Creation public class ParameterizedCreationMethodExample { private Person alice, billy, clark; @Before public void setUp() throws Exception { clark = createPerson("Clark", "Cable"); billy = createPerson("Billy", "Burke"); alice = createPerson("Alice", "Adams"); alice.isInLoveWith(billy); } private Person createPerson(String firstName, String lastName) { Person person = new Person(); person.setFirstname(firstName); person.setLastname(lastName); person.setId(UniqueNumber.next()); person.setSsn(String.valueOf(UniqueNumber.next())); return person; } @Test public void aliceShouldAcceptWhenProposedToByBilly() throws Exception { billy.proposeTo(alice); assertTrue(alice.isEngagedWith(billy)); } } 35 Monday, 15 November 2010
  • 36. make-it-easy 36 http://code.google.com/p/make-it-easy/ Maker<Apple> appleWith2Leaves = an(Apple, with(2, leaves)); Maker<Apple> ripeApple = appleWith2Leaves.but(with(ripeness, 0.9)); Maker<Apple> unripeApple = appleWith2Leaves.but(with(ripeness, 0.125));         Apple apple1 = make(ripeApple); Apple apple2 = make(unripeApple);         Banana defaultBanana = make(a(Banana)); Banana straightBanana = make(a(Banana, with(curve, 0.0))); Banana squishyBanana = make(a(Banana, with(ripeness, 1.0))); Monday, 15 November 2010
  • 37. Try: One assertion per test 37 Monday, 15 November 2010
  • 38. Customised Assertions #define CHECK_OBJ(a,b) CHECK_OBJ(a,b, __FILE__,__FILE__) void CHECK_OBJ(struct* yourObj, struct* myObj, const char* file, int line) { if (structs are not equal) { SimpleString errorMessage = StringFromFormat( “My struct: %d, %p, %s”, myObj->d, myObj->p, myObj->s); FAIL_LOCATION(errorMessage.asCharString(), file, line); } } 38 Monday, 15 November 2010
  • 39. At least: One concept per test 39 Monday, 15 November 2010
  • 40. Hamcrest • Framework for writing declarative match criteria 40http://code.google.com/p/hamcrest/ String s = "yes we have no bananas today"; Matcher<String> containsBananas = new StringContains("bananas"); Matcher<String> containsMangoes = new StringContains("mangoes"); assertTrue(containsBananas.matches(s)); assertFalse(containsMangoes.matches(s)); assertThat(s, containsString("bananas")); assertThat(s, not(containsString("mangoes")); Or even better Monday, 15 November 2010
  • 41. Meaningful Assertion Messages 41 • Donʼt repeat what the built-in test framework outputs to the console (e.g. name of the test method) • Donʼt repeat what the test name explains • If you donʼt have anything good to say, you donʼt have to say anything • Write what should have happened, or what failed to happen, and possibly mention when it should have happened Monday, 15 November 2010
  • 43. Extra Constructor 43 public class LogFileMerge { private URL logFileA, logFileB; public LogFileMerge() { this(new URL("http://server1/system.log"), new URL("http://server2/system.log")); } LogFileMerge(URL a, URL b) { this.logFileA = a; this.logFileB = b; } } Monday, 15 November 2010
  • 44. Test-Specific SubClass 44 public class CreditCardProcessing { public boolean isValid(String cardnumber) { return validationCodeMatches(cardnumber) && cardIsActive(cardnumber); } protected boolean validationCodeMatches(String cardnumber) { // validation logic omitted for brevity... } protected boolean cardIsActive(String cardnumber) { // access to merchant system's web service // omitted for brevity... } } Monday, 15 November 2010
  • 45. Still not testable? 45 • Do you follow good design principles? Monday, 15 November 2010
  • 46. Thinking 46 Test code is not second class citizen Good design principles apply: • Responsibility • Dependency • Low Coupling • High Cohesion • Indirection • Protected Variations Watch out for organisational dysfunction! Monday, 15 November 2010
  • 47. References • Practical TDD and ATDD for Java Developers - Lasse Koskela • Growing OO Software, guided by tests - Steve Freeman • xUnit Test Patterns - Gerard Meszaros 47 Steven Mak steven@odd-e.com www.odd-e.com twitter: stevenmak Monday, 15 November 2010