Your SlideShare is downloading. ×
0
Seven Ineffective
Coding Habits of
Many Programmers
@KevlinHenney
It turns out that style matters in
programming for the same
reason that it matters in writing.
It makes for better reading...
Noisy Code
Signal-to-noise ratio (often abbreviated SNR or
S/N) is a measure used in science and engineering
that compares the level ...
To be, or not to be: that is the question:
Whether 'tis nobler in the mind to suffer
The slings and arrows of outrageous f...
Continuing existence or cessation of
existence: those are the scenarios. Is it
more empowering mentally to work towards
an...
public class RecentlyUsedList
{
private List<string> items;
public RecentlyUsedList()
{
items = new List<string>();
}
publ...
public class RecentlyUsedList
{
private List<string> items;
public RecentlyUsedList()
{
items = new List<string>();
}
publ...
Comments
A delicate matter, requiring taste and judgement. I tend to err on the side of
eliminating comments, for several ...
There is a famously bad comment style:
i=i+1; /* Add one to i */
and there are worse ways to do it:
/*********************...
A common fallacy is to assume authors
of incomprehensible code will somehow
be able to express themselves lucidly
and clea...
Unsustainable Spacing
To be, or not to be: that is the question:
Whether 'tis nobler in the mind to suffer
The slings and arrows of outrageous f...
Continuing existence or cessation of
existence: those are the scenarios. Is it
more empowering mentally to work towards
an...
Continuing existence or cessation of existence:
those are the
more empowe
to work towa
accommodati
downsizings
outcomes of...
How many programmers lay out their code
Column 80
How people read
To answer the question "What is clean design?"
most succinctly: a clean design is one that
supports visual thinking so peo...
You convey information by the way you arrange
a design's elements in relation to each other. This
information is understoo...
This is great if the visual relationships are
obvious and accurate, but if they're not, your
audience is going to get conf...
public int howNotToLayoutAMethodHeader(int firstArgument,
String secondArgument)
public int ensureArgumentsAreAlignedLikeT...
int doNotFormat = likeThis(someArgumentOrExpression,
anotherArgumentOrExpression);
int insteadFormat =
somethingLikeThis(
...
int asItIs = unstable(someArgumentOrExpression,
anotherArgumentOrExpression);
int butThisIs =
stable(
someArgumentOrExpres...
public ResultType arbitraryMethodName(FirstArgumentType firs
SecondArgumentType sec
ThirdArgumentType thir
LocalVariableTy...
public ResultType arbitraryMethodName(
FirstArgumentType firstArgument,
SecondArgumentType secondArgument,
ThirdArgumentTy...
XXXXXX XXXXXXXXXX XXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXX XXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXX ...
public ResultType arbitraryMethodName(
FirstArgumentType firstArgument,
SecondArgumentType secondArgument,
ThirdArgumentTy...
XXXXXX XXXXXXXXXX XXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXX XXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXX ...
public ResultType arbitraryMethodName(
FirstArgumentType firstArgument,
SecondArgumentType secondArgument,
ThirdArgumentTy...
XXXXXX XXXXXXXXXX XXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXX XXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXX ...
Lego Naming
Agglutination is a process in linguistic morphology
derivation in which complex words are formed by
stringing together mor...
pneumonoultramicroscopicsilicovolcanoconiosis
Rindfleischetikettierungsüberwachungsaufgabenübertragungsgesetz
fylkestrafik...
Proxy
validate
Service
Value
get
create
Manager
check
Controller
set
Factory
Object
doenable
process
disable
Exception
add...
public interface ConditionChecker
{
boolean checkCondition();
}
public interface Condition
{
boolean isTrue();
}
public Connection createConnection(Provider...)
throws ConnectionFailureException
...
public Connection connectTo(Provider...)
throws ConnectionFailure
...
Omit needless words.
William Strunk and E B White
The Elements of Style
Underabstraction
http://fragmental.tw/2009/04/29/tag-clouds-see-how-noisy-your-code-is/
http://fragmental.tw/2009/04/29/tag-clouds-see-how-noisy-your-code-is/
if (portfolioIdsByTraderId.get(trader.getId())
.containsKey(portfolio.getId()))
{
...
}
Dan North, "Code in the Language o...
if (trader.canView(portfolio))
{
...
}
Dan North, "Code in the Language of the Domain"
97 Things Every Programmer Should K...
parser.processNodes(text, false);
Gregor Hohpe, "Convenience Is Not an -ility"
97 Things Every Programmer Should Know
If you have a procedure with
ten parameters, you probably
missed some.
Alan Perlis
Unencapsulated State
encapsulate
 enclose (something) in or as if in a capsule.
 express the essential feature of (someone or
something) succ...
An affordance is a quality of an
object, or an environment, which
allows an individual to perform an
action. For example, ...
public class RecentlyUsedList
{
private List<string> items = new List<string>();
public List<string> Items
{
get
{
return ...
public class RecentlyUsedList
{
private List<string> items = new List<string>();
public List<string> Items
{
get
{
return ...
public class RecentlyUsedList
{
private List<string> items = new List<string>();
public List<string> Items
{
get
{
return ...
Don't ever invite a
vampire into your
house, you silly boy.
It renders you
powerless.
public class RecentlyUsedList
{
private IList<string> items = new List<string>();
public int Count
{
get
{
return items.Co...
public class RecentlyUsedList
{
private IList<string> items = new List<string>();
public int Count
{
get
{
return items.Co...
Getters and Setters
public class Money implements ...
{
...
public int getUnits() ...
public int getHundredths() ...
public Currency getCurren...
public final class Money implements ...
{
...
public int getUnits() ...
public int getHundredths() ...
public Currency get...
public final class Money implements ...
{
...
public int units() ...
public int hundredths() ...
public Currency currency(...
When it is not
necessary to
change, it is
necessary not to
change.
Lucius Cary
Uncohesive Tests
Everybody knows that TDD stands for Test Driven
Development. However, people too often concentrate
on the words "Test" and...
public class RecentlyUsedList
{
...
public RecentlyUsedList() ...
public int Count
{
get...
}
public string this[int index...
[TestFixture]
public class RecentlyUsedListTests
{
[Test]
public void TestConstructor() ...
[Test]
public void TestCount()...
So who should you be writing the tests
for? For the person trying to
understand your code.
Good tests act as documentation...
namespace RecentlyUsedList_spec
{
[TestFixture]
public class A_new_list
{
[Test] public void Is_empty() 
}
[TestFixture]
...
namespace RecentlyUsedList_spec
{
[TestFixture]
public class A_new_list
{
[Test] public void Is_empty() 
}
[TestFixture]
...
A test case should
be just that: it
should correspond
to a single case.
At some level
the style
becomes the
substance.
Seven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many Programmers
Seven Ineffective Coding Habits of Many Programmers
Upcoming SlideShare
Loading in...5
×

Seven Ineffective Coding Habits of Many Programmers

7,292

Published on

Presented at NDC 2014 in Oslo (4th June 2014)
Video available on Vimeo: https://vimeo.com/97329157

Habits help you manage the complexity of code. You apply existing skill and knowledge automatically to the detail while focusing on the bigger picture. But because you acquire habits largely by imitation, and rarely question them, how do you know your habits are effective? Many of the habits that programmers have for naming, formatting, commenting and unit testing do not stand up as rational and practical on closer inspection.

This talk examines seven coding habits that are not as effective as programmers believe, and suggests alternatives.

0 Comments
26 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
7,292
On Slideshare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
50
Comments
0
Likes
26
Embeds 0
No embeds

No notes for slide

Transcript of "Seven Ineffective Coding Habits of Many Programmers"

  1. 1. Seven Ineffective Coding Habits of Many Programmers @KevlinHenney
  2. 2. It turns out that style matters in programming for the same reason that it matters in writing. It makes for better reading. Douglas Crockford JavaScript: The Good Parts
  3. 3. Noisy Code
  4. 4. Signal-to-noise ratio (often abbreviated SNR or S/N) is a measure used in science and engineering that compares the level of a desired signal to the level of background noise. Signal-to-noise ratio is sometimes used informally to refer to the ratio of useful information to false or irrelevant data in a conversation or exchange. http://en.wikipedia.org/wiki/Signal_to_noise_ratio
  5. 5. To be, or not to be: that is the question: Whether 'tis nobler in the mind to suffer The slings and arrows of outrageous fortune, Or to take arms against a sea of troubles, And by opposing end them? William Shakespeare Hamlet
  6. 6. Continuing existence or cessation of existence: those are the scenarios. Is it more empowering mentally to work towards an accommodation of the downsizings and negative outcomes of adversarial circumstance, or would it be a greater enhancement of the bottom line to move forwards to a challenge to our current difficulties, and, by making a commitment to opposition, to effect their demise? Tom Burton Long Words Bother Me
  7. 7. public class RecentlyUsedList { private List<string> items; public RecentlyUsedList() { items = new List<string>(); } public void Add(string newItem) { if (items.Contains(newItem)) { int position = items.IndexOf(newItem); string existingItem = items[position]; items.RemoveAt(position); items.Insert(0, existingItem); } else { items.Insert(0, newItem); } } public int Count { get { int size = items.Count; return size; } } public string this[int index] { get { int position = 0; foreach (string item in items) { if (position == index) return item; ++position; } throw new ArgumentOutOfRangeException(); } } }
  8. 8. public class RecentlyUsedList { private List<string> items; public RecentlyUsedList() { items = new List<string>(); } public void Add(string newItem) { if (items.Contains(newItem)) { int position = items.IndexOf(newItem); string existingItem = list[position]; items.RemoveAt(position); items.Insert(0, existingItem); } else { items.Insert(0, newItem); } } public int Count { get { int size = items.Count; return size; } } public string this[int index] { get { int position = 0; foreach (string value in items) { if (position == index) return value; ++position; } throw new ArgumentOutOfRangeException(); } } } public class RecentlyUsedList { private List<string> items = new List<string>(); public void Add(string newItem) { items.Remove(newItem); items.Add(newItem); } public int Count { get { return items.Count; } } public string this[int index] { get { return items[Count - index - 1]; } } }
  9. 9. Comments A delicate matter, requiring taste and judgement. I tend to err on the side of eliminating comments, for several reasons. First, if the code is clear, and uses good type names and variable names, it should explain itself. Second, comments aren't checked by the compiler, so there is no guarantee they're right, especially after the code is modified. A misleading comment can be very confusing. Third, the issue of typography: comments clutter code. Rob Pike, "Notes on Programming in C"
  10. 10. There is a famously bad comment style: i=i+1; /* Add one to i */ and there are worse ways to do it: /********************************** * * * Add one to i * * * **********************************/ i=i+1; Don't laugh now, wait until you see it in real life. Rob Pike, "Notes on Programming in C"
  11. 11. A common fallacy is to assume authors of incomprehensible code will somehow be able to express themselves lucidly and clearly in comments. Kevlin Henney https://twitter.com/KevlinHenney/status/381021802941906944
  12. 12. Unsustainable Spacing
  13. 13. To be, or not to be: that is the question: Whether 'tis nobler in the mind to suffer The slings and arrows of outrageous fortune, Or to take arms against a sea of troubles, And by opposing end them? William Shakespeare Hamlet
  14. 14. Continuing existence or cessation of existence: those are the scenarios. Is it more empowering mentally to work towards an accommodation of the downsizings and negative outcomes of adversarial circumstance, or would it be a greater enhancement of the bottom line to move forwards to a challenge to our current difficulties, and, by making a commitment to opposition, to effect their demise? Tom Burton Long Words Bother Me
  15. 15. Continuing existence or cessation of existence: those are the more empowe to work towa accommodati downsizings outcomes of circumstance a greater enh the bottom li forwards to a our current d by making a opposition, t demise?
  16. 16. How many programmers lay out their code Column 80
  17. 17. How people read
  18. 18. To answer the question "What is clean design?" most succinctly: a clean design is one that supports visual thinking so people can meet their informational needs with a minimum of conscious effort. Daniel Higginbotham ∙ "Clean Up Your Mess — A Guide to Visual Design for Everyone ∙ http://www.visualmess.com/
  19. 19. You convey information by the way you arrange a design's elements in relation to each other. This information is understood immediately, if not consciously, by the people viewing your designs. Daniel Higginbotham ∙ "Clean Up Your Mess — A Guide to Visual Design for Everyone ∙ http://www.visualmess.com/
  20. 20. This is great if the visual relationships are obvious and accurate, but if they're not, your audience is going to get confused. They'll have to examine your work carefully, going back and forth between the different parts to make sure they understand. Daniel Higginbotham ∙ "Clean Up Your Mess — A Guide to Visual Design for Everyone ∙ http://www.visualmess.com/
  21. 21. public int howNotToLayoutAMethodHeader(int firstArgument, String secondArgument) public int ensureArgumentsAreAlignedLikeThis( int firstArgument, String secondArgument) public int orEnsureArgumentsAreGroupedLikeThis( int firstArgument, String secondArgument) public int butNotAlignedLikeThis(int firstArgument, String secondArgument)
  22. 22. int doNotFormat = likeThis(someArgumentOrExpression, anotherArgumentOrExpression); int insteadFormat = somethingLikeThis( someArgumentOrExpression, anotherArgumentOrExpression); int orFormat = somethingLikeThis( someArgumentOrExpression, anotherArgumentOrExpression);
  23. 23. int asItIs = unstable(someArgumentOrExpression, anotherArgumentOrExpression); int butThisIs = stable( someArgumentOrExpression, anotherArgumentOrExpression); int andThisIs = stable( someArgumentOrExpression, anotherArgumentOrExpression);
  24. 24. public ResultType arbitraryMethodName(FirstArgumentType firs SecondArgumentType sec ThirdArgumentType thir LocalVariableType localVariable = method(firstArgument, secondArgument) if (localVariable.isSomething(thirdArgument, SOME_SHOUTY_CONSTANT)) { doSomethingWith(localVariable); } return localVariable.getSomething(); }
  25. 25. public ResultType arbitraryMethodName( FirstArgumentType firstArgument, SecondArgumentType secondArgument, ThirdArgumentType thirdArgument) { LocalVariableType localVariable = method(firstArgument, secondArgument); if (localVariable.isSomething( thirdArgument, SOME_SHOUTY_CONSTANT)) { doSomething(localVariable); } return localVariable.getSomething(); }
  26. 26. XXXXXX XXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXX XXXXXXXXXXXXX XXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXX XXXXXXXXXXXXXXXXX XXXXXXXXXXXXX XXXXXXXXXXXXXXXXX XXXXXXXXXXXXX XXXXXX XXXXXXXXXXXXX XXXXXXXXXXXXXX XX XXXXXXXXXXXXX XXXXXXXXXXX XXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXX XXXXXXXXXXX XXXXXXXXXXXXX XXXXXX XXXXXXXXXXXXX XXXXXXXXXXXX
  27. 27. public ResultType arbitraryMethodName( FirstArgumentType firstArgument, SecondArgumentType secondArgument, ThirdArgumentType thirdArgument) { LocalVariableType localVariable = method(firstArgument, secondArgument); if (localVariable.isSomething( thirdArgument, SOME_SHOUTY_CONSTANT)) { doSomething(localVariable); } return localVariable.getSomething(); }
  28. 28. XXXXXX XXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXX XXXXXXXXXXXXX XXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXX XXXXXXXXXXXXXXXXX XXXXXXXXXXXXX XXXXXXXXXXXXXXXXX XXXXXXXXXXXXX XXXXXX XXXXXXXXXXXXX XXXXXXXXXXXXXX XX XXXXXXXXXXXXX XXXXXXXXXXX XXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXX XXXXXXXXXXX XXXXXXXXXXXXX XXXXXX XXXXXXXXXXXXX XXXXXXXXXXXX
  29. 29. public ResultType arbitraryMethodName( FirstArgumentType firstArgument, SecondArgumentType secondArgument, ThirdArgumentType thirdArgument) { LocalVariableType localVariable = method(firstArgument, secondArgument); if (localVariable.isSomething( thirdArgument, SOME_SHOUTY_CONSTANT)) { doSomething(localVariable); } return localVariable.getSomething(); }
  30. 30. XXXXXX XXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXX XXXXXXXXXXXXX XXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXX XXXXXXXXXXXXXXXXX XXXXXXXXXXXXX XXXXXXXXXXXXXXXXX XXXXXXXXXXXXX XXXXXX XXXXXXXXXXXXX XXXXXXXXXXXXXX XX XXXXXXXXXXXXX XXXXXXXXXXX XXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXX XXXXXXXXXXX XXXXXXXXXXXXX XXXXXX XXXXXXXXXXXXX XXXXXXXXXXXX
  31. 31. Lego Naming
  32. 32. Agglutination is a process in linguistic morphology derivation in which complex words are formed by stringing together morphemes, each with a single grammatical or semantic meaning. Languages that use agglutination widely are called agglutinative languages. http://en.wikipedia.org/wiki/Agglutination
  33. 33. pneumonoultramicroscopicsilicovolcanoconiosis Rindfleischetikettierungsüberwachungsaufgabenübertragungsgesetz fylkestrafikksikkerhetsutvalgssekretariatslederfunksjonene
  34. 34. Proxy validate Service Value get create Manager check Controller set Factory Object doenable process disable Exception add remove
  35. 35. public interface ConditionChecker { boolean checkCondition(); }
  36. 36. public interface Condition { boolean isTrue(); }
  37. 37. public Connection createConnection(Provider...) throws ConnectionFailureException ...
  38. 38. public Connection connectTo(Provider...) throws ConnectionFailure ...
  39. 39. Omit needless words. William Strunk and E B White The Elements of Style
  40. 40. Underabstraction
  41. 41. http://fragmental.tw/2009/04/29/tag-clouds-see-how-noisy-your-code-is/
  42. 42. http://fragmental.tw/2009/04/29/tag-clouds-see-how-noisy-your-code-is/
  43. 43. if (portfolioIdsByTraderId.get(trader.getId()) .containsKey(portfolio.getId())) { ... } Dan North, "Code in the Language of the Domain" 97 Things Every Programmer Should Know
  44. 44. if (trader.canView(portfolio)) { ... } Dan North, "Code in the Language of the Domain" 97 Things Every Programmer Should Know
  45. 45. parser.processNodes(text, false); Gregor Hohpe, "Convenience Is Not an -ility" 97 Things Every Programmer Should Know
  46. 46. If you have a procedure with ten parameters, you probably missed some. Alan Perlis
  47. 47. Unencapsulated State
  48. 48. encapsulate  enclose (something) in or as if in a capsule.  express the essential feature of (someone or something) succinctly.  provide an interface for (a piece of software or hardware) to allow or simplify access for the user. The New Oxford Dictionary of English
  49. 49. An affordance is a quality of an object, or an environment, which allows an individual to perform an action. For example, a knob affords twisting, and perhaps pushing, while a cord affords pulling. http://en.wikipedia.org/wiki/Affordance
  50. 50. public class RecentlyUsedList { private List<string> items = new List<string>(); public List<string> Items { get { return items; } } public void Add(string newItem) { if(newItem == null) throw new ArgumentNullException(); items.Remove(newItem); items.Insert(0, newItem); } ... }
  51. 51. public class RecentlyUsedList { private List<string> items = new List<string>(); public List<string> Items { get { return items; } } public void Add(string newItem) { if(newItem == null) throw new ArgumentNullException(); items.Remove(newItem); items.Insert(0, newItem); } ... }
  52. 52. public class RecentlyUsedList { private List<string> items = new List<string>(); public List<string> Items { get { return items; } } public void Add(string newItem) { if(newItem == null) throw new ArgumentNullException(); items.Remove(newItem); items.Insert(0, newItem); } ... } var list = new RecentlyUsedList(); list.Add("Hello, World!"); Console.WriteLine(list.Items.Count); list.Items.Add("Hello, World!"); Console.WriteLine(list.Items.Count); list.Items.Add(null);
  53. 53. Don't ever invite a vampire into your house, you silly boy. It renders you powerless.
  54. 54. public class RecentlyUsedList { private IList<string> items = new List<string>(); public int Count { get { return items.Count; } } public string this[int index] { get { return items[index]; } } public void Add(string newItem) { if(newItem == null) throw new ArgumentNullException(); items.Remove(newItem); items.Insert(0, newItem); } ... }
  55. 55. public class RecentlyUsedList { private IList<string> items = new List<string>(); public int Count { get { return items.Count; } } public string this[int index] { get { return items[Count – index - 1]; } } public void Add(string newItem) { if(newItem == null) throw new ArgumentNullException(); items.Remove(newItem); items.Add(newItem); } ... }
  56. 56. Getters and Setters
  57. 57. public class Money implements ... { ... public int getUnits() ... public int getHundredths() ... public Currency getCurrency() ... ... public void setUnits(int newUnits) ... public void setHundredths(int newHundredths) ... public void setCurrency(Currency newCurrency) ... ... }
  58. 58. public final class Money implements ... { ... public int getUnits() ... public int getHundredths() ... public Currency getCurrency() ... ... }
  59. 59. public final class Money implements ... { ... public int units() ... public int hundredths() ... public Currency currency() ... ... }
  60. 60. When it is not necessary to change, it is necessary not to change. Lucius Cary
  61. 61. Uncohesive Tests
  62. 62. Everybody knows that TDD stands for Test Driven Development. However, people too often concentrate on the words "Test" and "Development" and don't consider what the word "Driven" really implies. For tests to drive development they must do more than just test that code performs its required functionality: they must clearly express that required functionality to the reader. That is, they must be clear specifications of the required functionality. Tests that are not written with their role as specifications in mind can be very confusing to read. Nat Pryce and Steve Freeman "Are Your Tests Really Driving Your Development?"
  63. 63. public class RecentlyUsedList { ... public RecentlyUsedList() ... public int Count { get... } public string this[int index] { get... } public void Add(string newItem) ... ... }
  64. 64. [TestFixture] public class RecentlyUsedListTests { [Test] public void TestConstructor() ... [Test] public void TestCount() ... [Test] public void TestIndexer() ... [Test] public void TestAdd() ... ... }
  65. 65. 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 Different usage scenarios will have slightly different versions of each of these. Gerard Meszaros "Write Tests for People"
  66. 66. 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()  } }
  67. 67. 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()  } }
  68. 68. A test case should be just that: it should correspond to a single case.
  69. 69. At some level the style becomes the substance.
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×