unit-testingtestingtddatdd

TDD and "honesty" of test


I have a concern with "honesty" of test when doing TDD. TDD is

  1. Write red test
  2. Write just enough code to make it green
  3. Refactor and let the test green

So far so good. Now here is an example of applying the principle above, such kind of example were already met in tutorial & real life :

I want to check that the current user email is displayed on the default page of my webapp.

  1. Write a red test : "example@user.com" is displayed inside default_page.html
  2. Write just enough code to make it green : hardcode "example@user.com" inside default_page.html
  3. Refactor by implementing get_current_user(), some other code in some others layers etc, letting the test green.

I'm "shocked" by step 2. There is something wrong here : the test is green even if nothing is actually working. There a test smell here, it means that maybe at some point someone could break the production code without breaking the test suite.

What I am missing here ?


Solution

  • I would say that what you have is only partially complete. You said:

    I want to check that the current user email is displayed on the default page of my webapp.

    The test doesn't check the current users email address on the default page, it checks that the fixed email address "example@user.com" is in the page.

    To address this you either need to provide more examples (ie have multiple tests with different email addresses) or to randomly generate the email address in the test setup.

    So I would say what you have is something like this is pseudo code:

    Given current user has email address "example@user.com"
    When they visit the default page
    The page should contain the email address "example@user.com"
    

    This is the first test you can write in TDD and you can indeed hardcode this to avoid implementing unnecessary stuff. You can now add another test which will force you to implement the correct behavior

    Given current user has email address "example2@user.com"
    When they visit the default page
    The page should contain the email address "example2@user.com"
    

    Now you have to remove the hardcoding as you cannot satisfy both of these tests with a hardcoded solution.So this will force you to get the actual email address from the current user and display this.

    Often it makes sense to end up with 3 examples in your tests. These don't need to be 3 separate tests, you can use data driven tests to reuse the same test method with different values. You don't say what test framework you are using, so I can't give a specific example.

    This approach is common in TDD and is called triangualtion.