A resounding YES with TDD (and with a few exceptions)
Controversial alright, but I'd argue that anyone who answers 'no' to this question is missing a fundamental concept of TDD.
For me, the answer is a resounding yes if you follow TDD. If you aren't then no is a plausible answer.
The DDD in TDD
TDD is often quoted as having thee main benefits.
- Defence
- Ensuring the code may change but not its behaviour.
- This allows the ever so important practice of refactoring.
- You gain this TDD or not.
- Design
- You specify what something should do, how it should behaves before implementing it.
- This often means more informed implementation decisions.
- Documentation
- The test suite should serve as the specification (requirements) documentation.
- Using tests for such purpose mean that the documentation and implementation are always in consistent state - a change to one means a change to other. Compare with keeping requirements and design on separate word document.
Separate responsibility from implementation
As programmers, it is terribly tempting to think of attributes as something of significance and getters and setter as some sort of overhead.
But attributes are an implementation detail, while setters and getters are the contractual interface that actually make programs work.
It is far more important to spell that an object should:
Allow its clients to change its state
and
Allow its clients to query its state
then how this state is actually stored (for which an attribute is the most common, but not the only way).
A test such as
(The Painter class) should store the provided colour
is important for the documentation part of TDD.
The fact that the eventual implementation is trivial (attribute) and carries no defence benefit should be unknown to you when you write the test.
The lack of round-trip engineering...
One of the key problems in the system development world is the lack of round-trip engineering1 - the development process of a system is fragmented into disjointed sub-processes the artifacts of which (documentation, code) are often inconsistent.
1Brodie, Michael L. "John Mylopoulos: sewing seeds of conceptual modelling." Conceptual Modeling: Foundations and Applications. Springer Berlin Heidelberg, 2009. 1-9.
...and how TDD solves it
It is the documentation part of TDD that ensures that the specifications of the system and its code are always consistent.
Design first, implement later
Within TDD we write failing acceptance test first, only then write the code that let them pass.
Within the higher-level BDD, we write scenarios first, then make them pass.
Why should you exclude setters and getter?
In theory, it is perfectly possible within TDD for one person to write the test, and another one to implement the code that makes it pass.
So ask yourself:
Should the person writing the tests for a class mention getters and setter.
Since getters and setters are a public interface to a class, the answer is obviously yes, or there will be no way to set or query the state of an object.
Obviously, if you write the code first, the answer may not be so clearcut.
Exceptions
There are some obvious exceptions to this rule - functions that are clearcut implementation detail and clearly not part of the design of the system.
For instance, a the local method 'B()':
function A() {
// B() will be called here
function B() {
...
}
}
Or the private function square()
here:
class Something {
private:
square() {...}
public:
addAndSquare() {...}
substractAndSquare() {...}
}
Or any other function that is not part of a public
interface that needs spelling in the design of the system component.