SlideShare a Scribd company logo
Programming with GUTs 
@KevlinHenney 
kevlin@curbralan.com
Programming with GUTs
When you write unit tests, TDD- style or after your development, you scrutinize, you think, and often you prevent problems without even encountering a test failure. 
Michael Feathers "The Flawed Theory Behind Unit Testing" http://michaelfeathers.typepad.com/michael_feathers_blog/2008/06/the-flawed-theo.html
Very many people say "TDD" when they really mean, "I have good unit tests" ("I have GUTs"?). 
Ron Jeffries tried for years to explain what this was, but we never got a catch-phrase for it, and now TDD is being watered down to mean GUTs. 
Alistair Cockburn "The modern programming professional has GUTs" http://alistair.cockburn.us/The+modern+programming+professional+has+GUTs
size_t ints_to_csv( 
const int * to_write, size_t how_many, 
char * output, size_t length);
size_t ints_to_csv( 
const int * to_write, size_t how_many, char * output, size_t length) 
{ 
size_t result = 0; 
if(length != 0) 
{ 
if(how_many == 0) 
{ 
output[0] = '0'; 
} 
else 
{ 
for(size_t which = 0; which != how_many && result != length; ++which) 
{ 
result += 
snprintf( 
output + result, length - result, 
which == 0 ? "%i" : ",%i", 
to_write[which]); 
} 
result = result > length - 1 ? length - 1 : result; 
} 
} 
return result; 
}
extern "C" size_t ints_to_csv( 
const int * to_write, size_t how_many, char * output, size_t length) 
{ 
size_t result = 0; 
if(length != 0) 
{ 
output[length - 1] = '0'; 
std::ostrstream buffer(output, length - 1); 
for(size_t which = 0; which != how_many; ++which) 
buffer << (which == 0 ? "" : ",") << to_write[which]; 
buffer << std::ends; 
result = std::strlen(output); 
} 
return result; 
}
function 
test
void test_ints_to_csv() 
{ 
size_t written = ints_to_csv(NULL, 0, NULL, 0); 
assert(written == 0); 
const int input[] = { 42 }; 
written = ints_to_csv(input, 1, NULL, 0); 
assert(written == 0); 
char output[3] = "+++"; 
written = ints_to_csv(NULL, 0, output, sizeof output); 
assert(written == 0); 
assert(output[0] == '0'); 
memcpy(output, "+++", sizeof output); 
written = ints_to_csv(input, 1, output, sizeof output); 
assert(written == 2); 
assert(strcmp(output, "42") == 0); 
... 
}
void test_ints_to_csv() 
{ 
// no values from null to null output writes nothing 
size_t written = ints_to_csv(NULL, 0, NULL, 0); 
assert(written == 0); 
// value to null output writes nothing 
const int input[] = { 42 }; 
written = ints_to_csv(input, 1, NULL, 0); 
assert(written == 0); 
// no values to sufficient output writes empty 
char output[3] = "+++"; 
written = ints_to_csv(NULL, 0, output, sizeof output); 
assert(written == 0); 
assert(output[0] == '0'); 
// positive value to sufficient output writes value without sign 
memcpy(output, "+++", sizeof output); 
written = ints_to_csv(input, 1, output, sizeof output); 
assert(written == 2); 
assert(strcmp(output, "42") == 0); 
... 
}
void test_ints_to_csv() 
{ 
// no values from null to null output writes nothing 
{ 
size_t written = ints_to_csv(NULL, 0, NULL, 0); 
assert(written == 0); 
} 
// value to null output writes nothing 
{ 
const int input[] = { 42 }; 
size_t written = ints_to_csv(input, 1, NULL, 0); 
assert(written == 0); 
} 
// no values to sufficient output writes empty 
{ 
char output[3] = "+++"; 
size_t written = ints_to_csv(NULL, 0, output, sizeof output); 
assert(written == 0); 
assert(output[0] == '0'); 
} 
// positive value to sufficient output writes value without sign 
{ 
const int input[] = { 42 }; 
char output[3] = "+++"; 
size_t written = ints_to_csv(input, 1, output, sizeof output); 
assert(written == 2); 
assert(strcmp(output, "42") == 0); 
}
void no_values_from_null_to_null_output_writes_nothing() 
{ 
size_t written = ints_to_csv(NULL, 0, NULL, 0); 
assert(written == 0); 
} 
void value_to_null_output_writes_nothing() 
{ 
const int input[] = { 42 }; 
size_t written = ints_to_csv(input, 1, NULL, 0); 
assert(written == 0); 
} 
void no_values_to_sufficient_output_writes_empty() 
{ 
char output[3] = "+++"; 
size_t written = ints_to_csv(NULL, 0, output, sizeof output); 
assert(written == 0); 
assert(output[0] == '0'); 
} 
void positive_value_to_sufficient_output_writes_value_without_sign() 
{ 
const int input[] = { 42 }; 
char output[3] = "+++"; 
size_t written = ints_to_csv(input, 1, output, sizeof output); 
assert(written == 2); 
assert(strcmp(output, "42") == 0); 
} 
void negative_value_to_sufficient_output_writes_value_with_sign() 
{ 
const int input[] = { -42 }; 
char output[4] = "++++"; 
size_t written = ints_to_csv(input, 1, output, sizeof output); 
assert(written == 3); 
assert(strcmp(output, "-42") == 0); 
} 
void value_to_insufficient_output_writes_truncated_value() 
{ 
const int input[] = { 42 }; 
char output[2] = "++"; 
size_t written = ints_to_csv(input, 1, output, sizeof output); 
assert(written == 1); 
assert(strcmp(output, "4") == 0); 
} 
void multiple_values_to_sufficient_output_writes_comma_separated_values() 
{ 
const int input[] = { 42, -273, 0, 7 }; 
char output[12] = "++++++++++++"; 
size_t written = ints_to_csv(input, 4, output, sizeof output); 
assert(written == 11); 
assert(strcmp(output, "42,-273,0,7") == 0); 
} 
void multiple_values_to_insufficient_output_writes_truncated_value_sequence() 
{ 
const int input[] = { 42, -273, 0, 7 }; 
char output[9] = "+++++++++"; 
size_t written = ints_to_csv(input, 4, output, sizeof output); 
assert(written == 8); 
assert(strcmp(output, "42,-273,") == 0); 
}
void no_values_from_null_to_null_output_writes_nothing() 
{ 
... 
} 
void value_to_null_output_writes_nothing() 
{ 
... 
} 
void no_values_to_sufficient_output_writes_empty() 
{ 
... 
} 
void positive_value_to_sufficient_output_writes_value_without_sign() 
{ 
... 
} 
void negative_value_to_sufficient_output_writes_value_with_sign() 
{ 
... 
} 
void value_to_insufficient_output_writes_truncated_value() 
{ 
... 
} 
void multiple_values_to_sufficient_output_writes_comma_separated_values() 
{ 
... 
} 
void multiple_values_to_insufficient_output_writes_truncated_value_sequence() 
{ 
... 
}
function 
test 
test 
test
size_t ints_to_csv( const int * to_write, size_t how_many, char * output, size_t length); 
 No values from null to null output writes nothing 
 Value to null output writes nothing 
 No values to sufficient output writes empty 
 Positive value to sufficient output writes value without sign 
 Negative value to sufficient output writes value with sign 
 Value to insufficient output writes truncated value 
 Multiple values to sufficient output writes comma separated values 
 Multiple values to insufficient output writes truncated value sequence
Tests that are not written with their role as specifications in mind can be very confusing to read. The difficulty in understanding what they are testing can greatly reduce the velocity at which a codebase can be changed. 
Nat Pryce and Steve Freeman "Are Your Tests Really Driving Your Development?"
Programming with GUTs
Propositions are vehicles for stating how things are or might be.
Thus only indicative sentences which it makes sense to think of as being true or as being false are capable of expressing propositions.
public static boolean isLeapYear(int year) ...
yearsNotDivisibleBy4... 
yearsDivisibleBy4ButNotBy100... 
yearsDivisibleBy100ButNotBy400... 
yearsDivisibleBy400...
Years_not_divisible_by_4_... 
Years_divisible_by_4_but_not_by_100_... 
Years_divisible_by_100_but_not_by_400_... 
Years_divisible_by_400_...
Years_not_divisible_by_4_should_not_be_leap_years 
Years_divisible_by_4_but_not_by_100_should_be_leap_years 
Years_divisible_by_100_but_not_by_400_should_not_be_leap_years 
Years_divisible_by_400_should_be_leap_years
Programming with GUTs
Years_not_divisible_by_4_are_not_leap_years 
Years_divisible_by_4_but_not_by_100_are_leap_years 
Years_divisible_by_100_but_not_by_400_are_not_leap_years 
Years_divisible_by_400_are_not_leap_years
Years_not_divisible_by_4_are_not_leap_years 
Years_divisible_by_4_but_not_by_100_are_leap_years 
Years_divisible_by_100_but_not_by_400_are_not_leap_years 
Years_divisible_by_400_are_not_leap_years
Years_not_divisible_by_4_are_not_leap_years 
Years_divisible_by_4_but_not_by_100_are_leap_years 
Years_divisible_by_100_but_not_by_400_are_not_leap_years 
Years_divisible_by_400_are_not_leap_years
A test case should be just that: it should correspond to a single case.
public class Leap_year_spec 
{ 
public static class A_year_is_a_leap_year 
{ 
@Test public void If_it_is_divisible_by_4_but_not_by_100()  
@Test public void If_it_is_divisible_by_400()  
} 
public static class A_year_is_not_a_leap_year 
{ 
@Test public void If_it_is_not_divisible_by_4()  
@Test public void If_it_is_divisible_by_100_but_not_by_400()  
} 
}
public class Leap_year_spec 
{ 
public static class A_year_is_a_leap_year 
{ 
@Test public void If_it_is_divisible_by_4_but_not_by_100()  
@Test public void If_it_is_divisible_by_400()  
} 
public static class A_year_is_not_a_leap_year 
{ 
@Test public void If_it_is_not_divisible_by_4()  
@Test public void If_it_is_divisible_by_100_but_not_by_400()  
} 
}
method 
test 
test 
test 
method 
method
public class RecentlyUsedList 
{ 
... 
public RecentlyUsedList() ... 
public int Count 
{ 
get... 
} 
public string this[int index] 
{ 
get... 
} 
public void Add(string newItem) ... 
... 
}
[TestFixture] 
public class RecentlyUsedListTests 
{ 
[Test] 
public void TestConstructor() ... 
[Test] 
public void TestCountGet() ... 
[Test] 
public void TestIndexerGet() ... 
[Test] 
public void TestAdd() ... 
... 
}
method 
test 
test 
test 
method 
method 
test 
test
namespace RecentlyUsedList_spec 
{ 
[TestFixture] 
public class A_new_list 
{ 
[Test] public void Is_empty()  
} 
[TestFixture] 
public class An_empty_list 
{ 
[Test] public void Retains_a_single_addition()  
[Test] public void Retains_unique_additions_in_stack_order()  
} 
[TestFixture] 
public class A_non_empty_list 
{ 
[Test] public void Is_unchanged_when_head_item_is_readded()  
[Test] public void Moves_non_head_item_to_head_when_it_is_readded()  
} 
[TestFixture] 
public class Any_list 
{ 
[Test] public void Rejects_addition_of_null_items()  
[Test] public void Rejects_indexing_past_its_end()  
[Test] public void Rejects_negative_indexing()  
} 
}
namespace RecentlyUsedList_spec { [TestFixture] public class A_new_list { [Test] public void Is_empty()  } [TestFixture] public class An_empty_list { [Test] public void Retains_a_single_addition()  [Test] public void Retains_unique_additions_in_stack_order()  } [TestFixture] public class A_non_empty_list { [Test] public void Is_unchanged_when_head_item_is_readded()  [Test] public void Moves_non_head_item_to_head_when_it_is_readded()  } [TestFixture] public class Any_list { [Test] public void Rejects_addition_of_null_items()  [Test] public void Rejects_indexing_past_its_end()  [Test] public void Rejects_negative_indexing()  } }
Programming with GUTs
So who should you be writing the tests for? For the person trying to understand your code. 
Good tests act as documentation for the code they are testing. They describe how the code works. For each usage scenario, the test(s): 
Describe the context, starting point, or preconditions that must be satisfied 
Illustrate how the software is invoked 
Describe the expected results or postconditions to be verified 
Gerard Meszaros "Write Tests for People"
namespace RecentlyUsedList_spec 
{ 
[TestFixture] 
public class A_new_list ... 
[TestFixture] 
public class An_empty_list 
{ 
[Test] 
public void Retains_a_single_addition( 
[Values("Prague", "Oslo", "Bristol")] string addend) 
{ 
var items = new RecentlyUsedList(); // Given... 
items.Add(addend); // When... 
Assert.AreEqual(1, items.Count); // Then... 
Assert.AreEqual(addend, list[0]); 
} 
[Test] public void Retains_unique_additions_in_stack_order()  
} 
[TestFixture] 
public class A_non_empty_list ... 
[TestFixture] 
public class Any_list ... 
}
Less unit testing dogma. 
More unit testing karma. 
Alberto Savoia 
"The Way of Testivus" 
http://www.artima.com/weblogs/viewpost.jsp?thread=203994

More Related Content

What's hot

C program
C programC program
C program
Komal Singh
 
Useful c programs
Useful c programsUseful c programs
Useful c programs
MD SHAH FAHAD
 
Computer Science Practical Science C++ with SQL commands
Computer Science Practical Science C++ with SQL commandsComputer Science Practical Science C++ with SQL commands
Computer Science Practical Science C++ with SQL commands
Vishvjeet Yadav
 
Implementing string
Implementing stringImplementing string
Implementing string
mohamed sikander
 
COMPUTER SCIENCE CLASS 12 PRACTICAL FILE
COMPUTER SCIENCE CLASS 12 PRACTICAL FILECOMPUTER SCIENCE CLASS 12 PRACTICAL FILE
COMPUTER SCIENCE CLASS 12 PRACTICAL FILE
Anushka Rai
 
12th CBSE Practical File
12th CBSE Practical File12th CBSE Practical File
12th CBSE Practical File
Ashwin Francis
 
C++ L03-Control Structure
C++ L03-Control StructureC++ L03-Control Structure
C++ L03-Control Structure
Mohammad Shaker
 
Arrays
ArraysArrays
Arrays
fahadshakeel
 
Array notes
Array notesArray notes
Array notes
Hitesh Wagle
 
C++ L02-Conversion+enum+Operators
C++ L02-Conversion+enum+OperatorsC++ L02-Conversion+enum+Operators
C++ L02-Conversion+enum+Operators
Mohammad Shaker
 
Oops practical file
Oops practical fileOops practical file
Oops practical file
Ankit Dixit
 
An imperative study of c
An imperative study of cAn imperative study of c
An imperative study of c
Tushar B Kute
 
Practical Class 12th (c++programs+sql queries and output)
Practical Class 12th (c++programs+sql queries and output) Practical Class 12th (c++programs+sql queries and output)
Practical Class 12th (c++programs+sql queries and output)
Aman Deep
 
2014 computer science_question_paper
2014 computer science_question_paper2014 computer science_question_paper
2014 computer science_question_paper
vandna123
 
Computer Programming- Lecture 6
Computer Programming- Lecture 6Computer Programming- Lecture 6
Computer Programming- Lecture 6
Dr. Md. Shohel Sayeed
 
3. chapter ii
3. chapter ii3. chapter ii
3. chapter ii
Chhom Karath
 
Cquestions
Cquestions Cquestions
Cquestions
mohamed sikander
 
Stl algorithm-Basic types
Stl algorithm-Basic typesStl algorithm-Basic types
Stl algorithm-Basic types
mohamed sikander
 
Arrays
ArraysArrays
FP 201 - Unit 6
FP 201 - Unit 6FP 201 - Unit 6
FP 201 - Unit 6
rohassanie
 

What's hot (20)

C program
C programC program
C program
 
Useful c programs
Useful c programsUseful c programs
Useful c programs
 
Computer Science Practical Science C++ with SQL commands
Computer Science Practical Science C++ with SQL commandsComputer Science Practical Science C++ with SQL commands
Computer Science Practical Science C++ with SQL commands
 
Implementing string
Implementing stringImplementing string
Implementing string
 
COMPUTER SCIENCE CLASS 12 PRACTICAL FILE
COMPUTER SCIENCE CLASS 12 PRACTICAL FILECOMPUTER SCIENCE CLASS 12 PRACTICAL FILE
COMPUTER SCIENCE CLASS 12 PRACTICAL FILE
 
12th CBSE Practical File
12th CBSE Practical File12th CBSE Practical File
12th CBSE Practical File
 
C++ L03-Control Structure
C++ L03-Control StructureC++ L03-Control Structure
C++ L03-Control Structure
 
Arrays
ArraysArrays
Arrays
 
Array notes
Array notesArray notes
Array notes
 
C++ L02-Conversion+enum+Operators
C++ L02-Conversion+enum+OperatorsC++ L02-Conversion+enum+Operators
C++ L02-Conversion+enum+Operators
 
Oops practical file
Oops practical fileOops practical file
Oops practical file
 
An imperative study of c
An imperative study of cAn imperative study of c
An imperative study of c
 
Practical Class 12th (c++programs+sql queries and output)
Practical Class 12th (c++programs+sql queries and output) Practical Class 12th (c++programs+sql queries and output)
Practical Class 12th (c++programs+sql queries and output)
 
2014 computer science_question_paper
2014 computer science_question_paper2014 computer science_question_paper
2014 computer science_question_paper
 
Computer Programming- Lecture 6
Computer Programming- Lecture 6Computer Programming- Lecture 6
Computer Programming- Lecture 6
 
3. chapter ii
3. chapter ii3. chapter ii
3. chapter ii
 
Cquestions
Cquestions Cquestions
Cquestions
 
Stl algorithm-Basic types
Stl algorithm-Basic typesStl algorithm-Basic types
Stl algorithm-Basic types
 
Arrays
ArraysArrays
Arrays
 
FP 201 - Unit 6
FP 201 - Unit 6FP 201 - Unit 6
FP 201 - Unit 6
 

Similar to Programming with GUTs

C tutorial
C tutorialC tutorial
2 BytesC++ course_2014_c4_ arrays
2 BytesC++ course_2014_c4_ arrays2 BytesC++ course_2014_c4_ arrays
2 BytesC++ course_2014_c4_ arrays
kinan keshkeh
 
C tutorial
C tutorialC tutorial
C tutorial
Anurag Sukhija
 
Lab. Programs in C
Lab. Programs in CLab. Programs in C
Lab. Programs in C
Saket Pathak
 
Computation Chapter 4
Computation Chapter 4Computation Chapter 4
Computation Chapter 4
Inocentshuja Ahmad
 
VIT351 Software Development VI Unit2
VIT351 Software Development VI Unit2VIT351 Software Development VI Unit2
VIT351 Software Development VI Unit2
YOGESH SINGH
 
C++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerC++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical Reviewer
Andrey Karpov
 
pointers 1
pointers 1pointers 1
pointers 1
gaurav koriya
 
Python programming workshop session 2
Python programming workshop session 2Python programming workshop session 2
Python programming workshop session 2
Abdul Haseeb
 
Developer Experience i TypeScript. Najbardziej ikoniczne duo
Developer Experience i TypeScript. Najbardziej ikoniczne duoDeveloper Experience i TypeScript. Najbardziej ikoniczne duo
Developer Experience i TypeScript. Najbardziej ikoniczne duo
The Software House
 
Some examples of the 64-bit code errors
Some examples of the 64-bit code errorsSome examples of the 64-bit code errors
Some examples of the 64-bit code errors
PVS-Studio
 
C C++ tutorial for beginners- tibacademy.in
C C++ tutorial for beginners- tibacademy.inC C++ tutorial for beginners- tibacademy.in
C C++ tutorial for beginners- tibacademy.in
TIB Academy
 
Complete DB code following the instructions Implement the D.pdf
Complete DB code following the instructions Implement the D.pdfComplete DB code following the instructions Implement the D.pdf
Complete DB code following the instructions Implement the D.pdf
access2future1
 
R Language
R LanguageR Language
R Language
ShwetDadhaniya1
 
COM1407: Arrays
COM1407: ArraysCOM1407: Arrays
COM1407: Arrays
Hemantha Kulathilake
 
Programming Fundamentals Arrays and Strings
Programming Fundamentals   Arrays and Strings Programming Fundamentals   Arrays and Strings
Programming Fundamentals Arrays and Strings
imtiazalijoono
 
Data structure week 3
Data structure week 3Data structure week 3
Data structure week 3
karmuhtam
 
Arrays in c
Arrays in cArrays in c
Arrays in c
vampugani
 
20.1 Java working with abstraction
20.1 Java working with abstraction20.1 Java working with abstraction
20.1 Java working with abstraction
Intro C# Book
 
the refernce of programming C notes ppt.pptx
the refernce of programming C notes ppt.pptxthe refernce of programming C notes ppt.pptx
the refernce of programming C notes ppt.pptx
AnkitaVerma776806
 

Similar to Programming with GUTs (20)

C tutorial
C tutorialC tutorial
C tutorial
 
2 BytesC++ course_2014_c4_ arrays
2 BytesC++ course_2014_c4_ arrays2 BytesC++ course_2014_c4_ arrays
2 BytesC++ course_2014_c4_ arrays
 
C tutorial
C tutorialC tutorial
C tutorial
 
Lab. Programs in C
Lab. Programs in CLab. Programs in C
Lab. Programs in C
 
Computation Chapter 4
Computation Chapter 4Computation Chapter 4
Computation Chapter 4
 
VIT351 Software Development VI Unit2
VIT351 Software Development VI Unit2VIT351 Software Development VI Unit2
VIT351 Software Development VI Unit2
 
C++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerC++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical Reviewer
 
pointers 1
pointers 1pointers 1
pointers 1
 
Python programming workshop session 2
Python programming workshop session 2Python programming workshop session 2
Python programming workshop session 2
 
Developer Experience i TypeScript. Najbardziej ikoniczne duo
Developer Experience i TypeScript. Najbardziej ikoniczne duoDeveloper Experience i TypeScript. Najbardziej ikoniczne duo
Developer Experience i TypeScript. Najbardziej ikoniczne duo
 
Some examples of the 64-bit code errors
Some examples of the 64-bit code errorsSome examples of the 64-bit code errors
Some examples of the 64-bit code errors
 
C C++ tutorial for beginners- tibacademy.in
C C++ tutorial for beginners- tibacademy.inC C++ tutorial for beginners- tibacademy.in
C C++ tutorial for beginners- tibacademy.in
 
Complete DB code following the instructions Implement the D.pdf
Complete DB code following the instructions Implement the D.pdfComplete DB code following the instructions Implement the D.pdf
Complete DB code following the instructions Implement the D.pdf
 
R Language
R LanguageR Language
R Language
 
COM1407: Arrays
COM1407: ArraysCOM1407: Arrays
COM1407: Arrays
 
Programming Fundamentals Arrays and Strings
Programming Fundamentals   Arrays and Strings Programming Fundamentals   Arrays and Strings
Programming Fundamentals Arrays and Strings
 
Data structure week 3
Data structure week 3Data structure week 3
Data structure week 3
 
Arrays in c
Arrays in cArrays in c
Arrays in c
 
20.1 Java working with abstraction
20.1 Java working with abstraction20.1 Java working with abstraction
20.1 Java working with abstraction
 
the refernce of programming C notes ppt.pptx
the refernce of programming C notes ppt.pptxthe refernce of programming C notes ppt.pptx
the refernce of programming C notes ppt.pptx
 

More from Kevlin Henney

Program with GUTs
Program with GUTsProgram with GUTs
Program with GUTs
Kevlin Henney
 
The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical Excellence
Kevlin Henney
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical Development
Kevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
Kevlin Henney
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
Kevlin Henney
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid Deconstruction
Kevlin Henney
 
Get Kata
Get KataGet Kata
Get Kata
Kevlin Henney
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
Kevlin Henney
 
Structure and Interpretation of Test Cases
Structure and Interpretation of Test CasesStructure and Interpretation of Test Cases
Structure and Interpretation of Test Cases
Kevlin Henney
 
Agility ≠ Speed
Agility ≠ SpeedAgility ≠ Speed
Agility ≠ Speed
Kevlin Henney
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to Immutability
Kevlin Henney
 
Old Is the New New
Old Is the New NewOld Is the New New
Old Is the New New
Kevlin Henney
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-In
Kevlin Henney
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good Name
Kevlin Henney
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Kevlin Henney
 
Thinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantThinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation Quadrant
Kevlin Henney
 
Code as Risk
Code as RiskCode as Risk
Code as Risk
Kevlin Henney
 
Software Is Details
Software Is DetailsSoftware Is Details
Software Is Details
Kevlin Henney
 
Game of Sprints
Game of SprintsGame of Sprints
Game of Sprints
Kevlin Henney
 
Good Code
Good CodeGood Code
Good Code
Kevlin Henney
 

More from Kevlin Henney (20)

Program with GUTs
Program with GUTsProgram with GUTs
Program with GUTs
 
The Case for Technical Excellence
The Case for Technical ExcellenceThe Case for Technical Excellence
The Case for Technical Excellence
 
Empirical Development
Empirical DevelopmentEmpirical Development
Empirical Development
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Lambda? You Keep Using that Letter
Lambda? You Keep Using that LetterLambda? You Keep Using that Letter
Lambda? You Keep Using that Letter
 
Solid Deconstruction
Solid DeconstructionSolid Deconstruction
Solid Deconstruction
 
Get Kata
Get KataGet Kata
Get Kata
 
Procedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went AwayProcedural Programming: It’s Back? It Never Went Away
Procedural Programming: It’s Back? It Never Went Away
 
Structure and Interpretation of Test Cases
Structure and Interpretation of Test CasesStructure and Interpretation of Test Cases
Structure and Interpretation of Test Cases
 
Agility ≠ Speed
Agility ≠ SpeedAgility ≠ Speed
Agility ≠ Speed
 
Refactoring to Immutability
Refactoring to ImmutabilityRefactoring to Immutability
Refactoring to Immutability
 
Old Is the New New
Old Is the New NewOld Is the New New
Old Is the New New
 
Turning Development Outside-In
Turning Development Outside-InTurning Development Outside-In
Turning Development Outside-In
 
Giving Code a Good Name
Giving Code a Good NameGiving Code a Good Name
Giving Code a Good Name
 
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
Clean Coders Hate What Happens To Your Code When You Use These Enterprise Pro...
 
Thinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation QuadrantThinking Outside the Synchronisation Quadrant
Thinking Outside the Synchronisation Quadrant
 
Code as Risk
Code as RiskCode as Risk
Code as Risk
 
Software Is Details
Software Is DetailsSoftware Is Details
Software Is Details
 
Game of Sprints
Game of SprintsGame of Sprints
Game of Sprints
 
Good Code
Good CodeGood Code
Good Code
 

Recently uploaded

B.Sc. Computer Science Department PPT 2024
B.Sc. Computer Science Department PPT 2024B.Sc. Computer Science Department PPT 2024
B.Sc. Computer Science Department PPT 2024
vmsdeptcom
 
07. Ruby String Slides - Ruby Core Teaching
07. Ruby String Slides - Ruby Core Teaching07. Ruby String Slides - Ruby Core Teaching
07. Ruby String Slides - Ruby Core Teaching
quanhoangd129
 
ERP Software Solutions Provider in Coimbatore
ERP Software Solutions Provider in CoimbatoreERP Software Solutions Provider in Coimbatore
ERP Software Solutions Provider in Coimbatore
Nextskill Technologies
 
InflectraCON 360: Risk-Based Testing for Mission Critical Systems
InflectraCON 360: Risk-Based Testing for Mission Critical SystemsInflectraCON 360: Risk-Based Testing for Mission Critical Systems
InflectraCON 360: Risk-Based Testing for Mission Critical Systems
Inflectra
 
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
shanihomely
 
Celebrity Girls Call Mumbai 9930687706 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9930687706 Unlimited Short Providing Girls Servic...Celebrity Girls Call Mumbai 9930687706 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9930687706 Unlimited Short Providing Girls Servic...
kiara pandey
 
Amadeus Travel API, Amadeus Booking API, Amadeus GDS
Amadeus Travel API, Amadeus Booking API, Amadeus GDSAmadeus Travel API, Amadeus Booking API, Amadeus GDS
Amadeus Travel API, Amadeus Booking API, Amadeus GDS
aadhiyaeliza
 
Busty Girls Call Mumbai 9930245274 Unlimited Short Providing Girls Service Av...
Busty Girls Call Mumbai 9930245274 Unlimited Short Providing Girls Service Av...Busty Girls Call Mumbai 9930245274 Unlimited Short Providing Girls Service Av...
Busty Girls Call Mumbai 9930245274 Unlimited Short Providing Girls Service Av...
revolutionary575
 
High Girls Call Chennai 000XX00000 Provide Best And Top Girl Service And No1 ...
High Girls Call Chennai 000XX00000 Provide Best And Top Girl Service And No1 ...High Girls Call Chennai 000XX00000 Provide Best And Top Girl Service And No1 ...
High Girls Call Chennai 000XX00000 Provide Best And Top Girl Service And No1 ...
singhlata50dh
 
Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...
Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...
Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...
dream girl
 
Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...
Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...
Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...
3610stuck
 
Girls Call Jogeshwari 9967584737 Provide Best And Top Girl Service And No1 in...
Girls Call Jogeshwari 9967584737 Provide Best And Top Girl Service And No1 in...Girls Call Jogeshwari 9967584737 Provide Best And Top Girl Service And No1 in...
Girls Call Jogeshwari 9967584737 Provide Best And Top Girl Service And No1 in...
simran hot girls
 
Predicting Test Results without Execution (FSE 2024)
Predicting Test Results without Execution (FSE 2024)Predicting Test Results without Execution (FSE 2024)
Predicting Test Results without Execution (FSE 2024)
andrehoraa
 
TEQnation 2024: Sustainable Software: May the Green Code Be with You
TEQnation 2024: Sustainable Software: May the Green Code Be with YouTEQnation 2024: Sustainable Software: May the Green Code Be with You
TEQnation 2024: Sustainable Software: May the Green Code Be with You
marcofolio
 
06. Ruby Array & Hash - Ruby Core Teaching
06. Ruby Array & Hash - Ruby Core Teaching06. Ruby Array & Hash - Ruby Core Teaching
06. Ruby Array & Hash - Ruby Core Teaching
quanhoangd129
 
08. Ruby Enumerable - Ruby Core Teaching
08. Ruby Enumerable - Ruby Core Teaching08. Ruby Enumerable - Ruby Core Teaching
08. Ruby Enumerable - Ruby Core Teaching
quanhoangd129
 
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in CityGirls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
neshakor5152
 
Authentication Review-June -2024 AP & TS.pptx
Authentication Review-June -2024 AP & TS.pptxAuthentication Review-June -2024 AP & TS.pptx
Authentication Review-June -2024 AP & TS.pptx
DEMONDUOS
 
03. Ruby Variables & Regex - Ruby Core Teaching
03. Ruby Variables & Regex - Ruby Core Teaching03. Ruby Variables & Regex - Ruby Core Teaching
03. Ruby Variables & Regex - Ruby Core Teaching
quanhoangd129
 
Private Girls Call Navi Mumbai 🛵🚡9820252231 💃 Choose Best And Top Girl Servic...
Private Girls Call Navi Mumbai 🛵🚡9820252231 💃 Choose Best And Top Girl Servic...Private Girls Call Navi Mumbai 🛵🚡9820252231 💃 Choose Best And Top Girl Servic...
Private Girls Call Navi Mumbai 🛵🚡9820252231 💃 Choose Best And Top Girl Servic...
902basic
 

Recently uploaded (20)

B.Sc. Computer Science Department PPT 2024
B.Sc. Computer Science Department PPT 2024B.Sc. Computer Science Department PPT 2024
B.Sc. Computer Science Department PPT 2024
 
07. Ruby String Slides - Ruby Core Teaching
07. Ruby String Slides - Ruby Core Teaching07. Ruby String Slides - Ruby Core Teaching
07. Ruby String Slides - Ruby Core Teaching
 
ERP Software Solutions Provider in Coimbatore
ERP Software Solutions Provider in CoimbatoreERP Software Solutions Provider in Coimbatore
ERP Software Solutions Provider in Coimbatore
 
InflectraCON 360: Risk-Based Testing for Mission Critical Systems
InflectraCON 360: Risk-Based Testing for Mission Critical SystemsInflectraCON 360: Risk-Based Testing for Mission Critical Systems
InflectraCON 360: Risk-Based Testing for Mission Critical Systems
 
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
Russian Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service ...
 
Celebrity Girls Call Mumbai 9930687706 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9930687706 Unlimited Short Providing Girls Servic...Celebrity Girls Call Mumbai 9930687706 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9930687706 Unlimited Short Providing Girls Servic...
 
Amadeus Travel API, Amadeus Booking API, Amadeus GDS
Amadeus Travel API, Amadeus Booking API, Amadeus GDSAmadeus Travel API, Amadeus Booking API, Amadeus GDS
Amadeus Travel API, Amadeus Booking API, Amadeus GDS
 
Busty Girls Call Mumbai 9930245274 Unlimited Short Providing Girls Service Av...
Busty Girls Call Mumbai 9930245274 Unlimited Short Providing Girls Service Av...Busty Girls Call Mumbai 9930245274 Unlimited Short Providing Girls Service Av...
Busty Girls Call Mumbai 9930245274 Unlimited Short Providing Girls Service Av...
 
High Girls Call Chennai 000XX00000 Provide Best And Top Girl Service And No1 ...
High Girls Call Chennai 000XX00000 Provide Best And Top Girl Service And No1 ...High Girls Call Chennai 000XX00000 Provide Best And Top Girl Service And No1 ...
High Girls Call Chennai 000XX00000 Provide Best And Top Girl Service And No1 ...
 
Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...
Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...
Russian Girls Call Mumbai 🛵🚡9833363713 💃 Choose Best And Top Girl Service And...
 
Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...
Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...
Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...
 
Girls Call Jogeshwari 9967584737 Provide Best And Top Girl Service And No1 in...
Girls Call Jogeshwari 9967584737 Provide Best And Top Girl Service And No1 in...Girls Call Jogeshwari 9967584737 Provide Best And Top Girl Service And No1 in...
Girls Call Jogeshwari 9967584737 Provide Best And Top Girl Service And No1 in...
 
Predicting Test Results without Execution (FSE 2024)
Predicting Test Results without Execution (FSE 2024)Predicting Test Results without Execution (FSE 2024)
Predicting Test Results without Execution (FSE 2024)
 
TEQnation 2024: Sustainable Software: May the Green Code Be with You
TEQnation 2024: Sustainable Software: May the Green Code Be with YouTEQnation 2024: Sustainable Software: May the Green Code Be with You
TEQnation 2024: Sustainable Software: May the Green Code Be with You
 
06. Ruby Array & Hash - Ruby Core Teaching
06. Ruby Array & Hash - Ruby Core Teaching06. Ruby Array & Hash - Ruby Core Teaching
06. Ruby Array & Hash - Ruby Core Teaching
 
08. Ruby Enumerable - Ruby Core Teaching
08. Ruby Enumerable - Ruby Core Teaching08. Ruby Enumerable - Ruby Core Teaching
08. Ruby Enumerable - Ruby Core Teaching
 
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in CityGirls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
 
Authentication Review-June -2024 AP & TS.pptx
Authentication Review-June -2024 AP & TS.pptxAuthentication Review-June -2024 AP & TS.pptx
Authentication Review-June -2024 AP & TS.pptx
 
03. Ruby Variables & Regex - Ruby Core Teaching
03. Ruby Variables & Regex - Ruby Core Teaching03. Ruby Variables & Regex - Ruby Core Teaching
03. Ruby Variables & Regex - Ruby Core Teaching
 
Private Girls Call Navi Mumbai 🛵🚡9820252231 💃 Choose Best And Top Girl Servic...
Private Girls Call Navi Mumbai 🛵🚡9820252231 💃 Choose Best And Top Girl Servic...Private Girls Call Navi Mumbai 🛵🚡9820252231 💃 Choose Best And Top Girl Servic...
Private Girls Call Navi Mumbai 🛵🚡9820252231 💃 Choose Best And Top Girl Servic...
 

Programming with GUTs

  • 1. Programming with GUTs @KevlinHenney kevlin@curbralan.com
  • 3. When you write unit tests, TDD- style or after your development, you scrutinize, you think, and often you prevent problems without even encountering a test failure. Michael Feathers "The Flawed Theory Behind Unit Testing" http://michaelfeathers.typepad.com/michael_feathers_blog/2008/06/the-flawed-theo.html
  • 4. Very many people say "TDD" when they really mean, "I have good unit tests" ("I have GUTs"?). Ron Jeffries tried for years to explain what this was, but we never got a catch-phrase for it, and now TDD is being watered down to mean GUTs. Alistair Cockburn "The modern programming professional has GUTs" http://alistair.cockburn.us/The+modern+programming+professional+has+GUTs
  • 5. size_t ints_to_csv( const int * to_write, size_t how_many, char * output, size_t length);
  • 6. size_t ints_to_csv( const int * to_write, size_t how_many, char * output, size_t length) { size_t result = 0; if(length != 0) { if(how_many == 0) { output[0] = '0'; } else { for(size_t which = 0; which != how_many && result != length; ++which) { result += snprintf( output + result, length - result, which == 0 ? "%i" : ",%i", to_write[which]); } result = result > length - 1 ? length - 1 : result; } } return result; }
  • 7. extern "C" size_t ints_to_csv( const int * to_write, size_t how_many, char * output, size_t length) { size_t result = 0; if(length != 0) { output[length - 1] = '0'; std::ostrstream buffer(output, length - 1); for(size_t which = 0; which != how_many; ++which) buffer << (which == 0 ? "" : ",") << to_write[which]; buffer << std::ends; result = std::strlen(output); } return result; }
  • 9. void test_ints_to_csv() { size_t written = ints_to_csv(NULL, 0, NULL, 0); assert(written == 0); const int input[] = { 42 }; written = ints_to_csv(input, 1, NULL, 0); assert(written == 0); char output[3] = "+++"; written = ints_to_csv(NULL, 0, output, sizeof output); assert(written == 0); assert(output[0] == '0'); memcpy(output, "+++", sizeof output); written = ints_to_csv(input, 1, output, sizeof output); assert(written == 2); assert(strcmp(output, "42") == 0); ... }
  • 10. void test_ints_to_csv() { // no values from null to null output writes nothing size_t written = ints_to_csv(NULL, 0, NULL, 0); assert(written == 0); // value to null output writes nothing const int input[] = { 42 }; written = ints_to_csv(input, 1, NULL, 0); assert(written == 0); // no values to sufficient output writes empty char output[3] = "+++"; written = ints_to_csv(NULL, 0, output, sizeof output); assert(written == 0); assert(output[0] == '0'); // positive value to sufficient output writes value without sign memcpy(output, "+++", sizeof output); written = ints_to_csv(input, 1, output, sizeof output); assert(written == 2); assert(strcmp(output, "42") == 0); ... }
  • 11. void test_ints_to_csv() { // no values from null to null output writes nothing { size_t written = ints_to_csv(NULL, 0, NULL, 0); assert(written == 0); } // value to null output writes nothing { const int input[] = { 42 }; size_t written = ints_to_csv(input, 1, NULL, 0); assert(written == 0); } // no values to sufficient output writes empty { char output[3] = "+++"; size_t written = ints_to_csv(NULL, 0, output, sizeof output); assert(written == 0); assert(output[0] == '0'); } // positive value to sufficient output writes value without sign { const int input[] = { 42 }; char output[3] = "+++"; size_t written = ints_to_csv(input, 1, output, sizeof output); assert(written == 2); assert(strcmp(output, "42") == 0); }
  • 12. void no_values_from_null_to_null_output_writes_nothing() { size_t written = ints_to_csv(NULL, 0, NULL, 0); assert(written == 0); } void value_to_null_output_writes_nothing() { const int input[] = { 42 }; size_t written = ints_to_csv(input, 1, NULL, 0); assert(written == 0); } void no_values_to_sufficient_output_writes_empty() { char output[3] = "+++"; size_t written = ints_to_csv(NULL, 0, output, sizeof output); assert(written == 0); assert(output[0] == '0'); } void positive_value_to_sufficient_output_writes_value_without_sign() { const int input[] = { 42 }; char output[3] = "+++"; size_t written = ints_to_csv(input, 1, output, sizeof output); assert(written == 2); assert(strcmp(output, "42") == 0); } void negative_value_to_sufficient_output_writes_value_with_sign() { const int input[] = { -42 }; char output[4] = "++++"; size_t written = ints_to_csv(input, 1, output, sizeof output); assert(written == 3); assert(strcmp(output, "-42") == 0); } void value_to_insufficient_output_writes_truncated_value() { const int input[] = { 42 }; char output[2] = "++"; size_t written = ints_to_csv(input, 1, output, sizeof output); assert(written == 1); assert(strcmp(output, "4") == 0); } void multiple_values_to_sufficient_output_writes_comma_separated_values() { const int input[] = { 42, -273, 0, 7 }; char output[12] = "++++++++++++"; size_t written = ints_to_csv(input, 4, output, sizeof output); assert(written == 11); assert(strcmp(output, "42,-273,0,7") == 0); } void multiple_values_to_insufficient_output_writes_truncated_value_sequence() { const int input[] = { 42, -273, 0, 7 }; char output[9] = "+++++++++"; size_t written = ints_to_csv(input, 4, output, sizeof output); assert(written == 8); assert(strcmp(output, "42,-273,") == 0); }
  • 13. void no_values_from_null_to_null_output_writes_nothing() { ... } void value_to_null_output_writes_nothing() { ... } void no_values_to_sufficient_output_writes_empty() { ... } void positive_value_to_sufficient_output_writes_value_without_sign() { ... } void negative_value_to_sufficient_output_writes_value_with_sign() { ... } void value_to_insufficient_output_writes_truncated_value() { ... } void multiple_values_to_sufficient_output_writes_comma_separated_values() { ... } void multiple_values_to_insufficient_output_writes_truncated_value_sequence() { ... }
  • 15. size_t ints_to_csv( const int * to_write, size_t how_many, char * output, size_t length);  No values from null to null output writes nothing  Value to null output writes nothing  No values to sufficient output writes empty  Positive value to sufficient output writes value without sign  Negative value to sufficient output writes value with sign  Value to insufficient output writes truncated value  Multiple values to sufficient output writes comma separated values  Multiple values to insufficient output writes truncated value sequence
  • 16. Tests that are not written with their role as specifications in mind can be very confusing to read. The difficulty in understanding what they are testing can greatly reduce the velocity at which a codebase can be changed. Nat Pryce and Steve Freeman "Are Your Tests Really Driving Your Development?"
  • 18. Propositions are vehicles for stating how things are or might be.
  • 19. Thus only indicative sentences which it makes sense to think of as being true or as being false are capable of expressing propositions.
  • 20. public static boolean isLeapYear(int year) ...
  • 28. A test case should be just that: it should correspond to a single case.
  • 29. public class Leap_year_spec { public static class A_year_is_a_leap_year { @Test public void If_it_is_divisible_by_4_but_not_by_100()  @Test public void If_it_is_divisible_by_400()  } public static class A_year_is_not_a_leap_year { @Test public void If_it_is_not_divisible_by_4()  @Test public void If_it_is_divisible_by_100_but_not_by_400()  } }
  • 30. public class Leap_year_spec { public static class A_year_is_a_leap_year { @Test public void If_it_is_divisible_by_4_but_not_by_100()  @Test public void If_it_is_divisible_by_400()  } public static class A_year_is_not_a_leap_year { @Test public void If_it_is_not_divisible_by_4()  @Test public void If_it_is_divisible_by_100_but_not_by_400()  } }
  • 31. method test test test method method
  • 32. public class RecentlyUsedList { ... public RecentlyUsedList() ... public int Count { get... } public string this[int index] { get... } public void Add(string newItem) ... ... }
  • 33. [TestFixture] public class RecentlyUsedListTests { [Test] public void TestConstructor() ... [Test] public void TestCountGet() ... [Test] public void TestIndexerGet() ... [Test] public void TestAdd() ... ... }
  • 34. method test test test method method test test
  • 35. namespace RecentlyUsedList_spec { [TestFixture] public class A_new_list { [Test] public void Is_empty()  } [TestFixture] public class An_empty_list { [Test] public void Retains_a_single_addition()  [Test] public void Retains_unique_additions_in_stack_order()  } [TestFixture] public class A_non_empty_list { [Test] public void Is_unchanged_when_head_item_is_readded()  [Test] public void Moves_non_head_item_to_head_when_it_is_readded()  } [TestFixture] public class Any_list { [Test] public void Rejects_addition_of_null_items()  [Test] public void Rejects_indexing_past_its_end()  [Test] public void Rejects_negative_indexing()  } }
  • 36. namespace RecentlyUsedList_spec { [TestFixture] public class A_new_list { [Test] public void Is_empty()  } [TestFixture] public class An_empty_list { [Test] public void Retains_a_single_addition()  [Test] public void Retains_unique_additions_in_stack_order()  } [TestFixture] public class A_non_empty_list { [Test] public void Is_unchanged_when_head_item_is_readded()  [Test] public void Moves_non_head_item_to_head_when_it_is_readded()  } [TestFixture] public class Any_list { [Test] public void Rejects_addition_of_null_items()  [Test] public void Rejects_indexing_past_its_end()  [Test] public void Rejects_negative_indexing()  } }
  • 38. So who should you be writing the tests for? For the person trying to understand your code. Good tests act as documentation for the code they are testing. They describe how the code works. For each usage scenario, the test(s): Describe the context, starting point, or preconditions that must be satisfied Illustrate how the software is invoked Describe the expected results or postconditions to be verified Gerard Meszaros "Write Tests for People"
  • 39. namespace RecentlyUsedList_spec { [TestFixture] public class A_new_list ... [TestFixture] public class An_empty_list { [Test] public void Retains_a_single_addition( [Values("Prague", "Oslo", "Bristol")] string addend) { var items = new RecentlyUsedList(); // Given... items.Add(addend); // When... Assert.AreEqual(1, items.Count); // Then... Assert.AreEqual(addend, list[0]); } [Test] public void Retains_unique_additions_in_stack_order()  } [TestFixture] public class A_non_empty_list ... [TestFixture] public class Any_list ... }
  • 40. Less unit testing dogma. More unit testing karma. Alberto Savoia "The Way of Testivus" http://www.artima.com/weblogs/viewpost.jsp?thread=203994