Let's say I try to test drive a calculator addition function.
Test 1:
public void Adding_0_And_0_Should_Return_0() { ... }
Production 1:
public int Add(int a, int b)
{
return 0;
}
Test 2:
public void Adding_3_And_0_Should_Return_3() { ... }
Production 2:
public int Add(int a, int b)
{
return a;
}
Test 3:
public void Adding_6_And_4_Should_Return_10() { ... }
Production 3:
public int Add(int a, int b)
{
return a + b;
}
You can see the tests gradually becoming more specific (taken as a whole - by applying more constraints with each case), and as a consequence, with each iteration, the implementation ends up more generic, because a single implementation needs to handle an increasing number of specific test cases.
So initially your production code can only handle a single case where the result of addition is 1. Then with the second iteration you can handle a more generic case, where your first number can be anything you want, as long as you're adding it to 0. With the final case, you become completely generic, by being able to add any two numbers, not just the specific ones from the earlier tests.