Specifically I am worried about this scenario :
1) I write a class with 1 member variable and a copy function
class MyClass
{
private:
int grade;
public:
void setGrade(int x) { grade = x; }
int getGrade() { return grade; }
void copyFrom(const MyClass* src) { grade = src->grade; }
}
2) Write a unit test along these lines
void testCopyFrom()
{
MyClass mc1;
MyClass mc2;
mc1.setGrade(-347);
mc2.setGrade(10);
mc2.copyFrom(&mc1);
TS_ASSERT_EQUALS(mc2.getGrade(), -347);
}
3) After a couple months I add a second member variable
private:
int grade, extra;
and, (you guessed it !) forget to update the copyFrom() function accordingly.
In this case the unit test will falsely report success. Have I done something wrong with the testing design?
TDD means test first: before you change the code, you should update your code. In this case, if you decide to add
extra, you should be adding tests for the API aroundextra(so far you have none, but maybe you’ll wantgetExtra()et al.), and then, as you add and revise tests, you’ll notice that you need to addsetExtra()andgetExtra()calls totestCopyFrom().At this stage your tests will mostly be failing (red), and you can then do the real code to make them pass (green), and finally, clean up and refactor, using your tests as a guide as to whether you’ve broken anything.
Read more about red-green-refactor—it is TDD.
Also, you should mark
getGrade()asconst, i.e.This means you can use a
constpointer or reference to aMyClassinstance to get the grade.