Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have been designing and developing code with TDD style for a long time. What disturbs me about TDD is writing tests for code that does not contain any business logic or interesting behaviour. I know TDD is a design activity more than testing but sometimes I feel it's useless to write tests in these scenarios.

For example I have a simple scenario like "When user clicks check button, it should check file's validity". For this scenario I usually start writing tests for presenter/controller class like the one below.

@Test
public void when_user_clicks_check_it_should_check_selected_file_validity(){
    MediaService service =mock(MediaService);
    View view =mock(View);

    when(view.getSelectedFile).thenReturns("c:\\Dir\\file.avi");

    MediaController controller =new MediaController(service,view);
    controller.check();

    verify(service).check("c:\\Dir\\file.avi");
}

As you can see there is no design decision or interesting code to verify behaviour. I am testing values from view passed to MediaService. I usually write but don't like these kind of tests. What do yo do about these situations ? Do you write tests for all the time ?

UPDATE :

I have changed the test name and code after complaints. Some users said that you should write tests for the trivial cases like this so in the future someone might add interesting behaviour. But what about “Code for today, design for tomorrow.” ? If someone, including myself, adds more interesting code in the future the test can be created for it then. Why should I do it now for the trivial cases ?

share|improve this question

migrated from stackoverflow.com Jun 22 '11 at 10:40

This question came from our site for professional and enthusiast programmers.

    
"Some users said that you should write tests for the trivial cases like this so in the future someone might add interesting behaviour.But what about “Code for today, design for tomorrow.” ? " Brilliant rebuttal! +1 –  maple_shaft Jun 22 '11 at 12:34

7 Answers 7

up vote 4 down vote accepted

I don't aim for 100 % of code coverage. And I usually don't write tests of methods which will obviously not contain any business logic and/or more than a few lines of code. But I still write unit tests (using TDD) of methods which not seem that complex. This is mostly because I like to have the unit test already, when coming back to that code months or even years later, and want to make it more complex. It's always easier to extend existing tests, than having to build it all from scratch. As Noufal said, it's subjective. My advice is to write the tests, if you think the method is a bit complex or have the potential to get more complex.

share|improve this answer

This is the second TDD question today that conveys annoyance at the number of tests to be written.

"Test it only if you would want it to work."

I'm not really sure I understand the test in the question.

Are you checking that Controller.Check() delegates to the service (dependency) with the argument as the selected file value from the view ? If yes, This is a good test. It allows you to test the controller without the actual service implementation. (interaction-based micro-tests).

Update: Now that I'm clear on what you're trying to test, I'd probably move some code around and rename a few things so that it reads "Test Media Controller delegates selected file check to media service." - which is a valid spec for the controller.

public class TestMediaController

@Test
public void DelegatesSelectedFileCheckToMediaService(){
    string selectedMediaFileInView = "c:\\Dir\\file.avi";

    when(_view.getSelectedFile).thenReturns(selectedMediaFileInView);

    new MediaController(_service, _view).check();

    verify(_service).check(selectedMediaFileInView);
}
share|improve this answer
    
Yes It delegates to the service class. –  mcaaltuntas Jun 22 '11 at 7:17
    
But question: is it worth it to write this test to only verify parameter passed from view to service class? –  mcaaltuntas Jun 22 '11 at 7:25
    
@Yes - it tests that check() is wired correctly. There should be another test that Service.Check() works once it receives the call. This test looks trivial today but as time goes on someone might add more code to this method (e.g. a guard clause if some-condition return;) and break existing behavior. This test safe-guards against that. –  Gishu Jun 22 '11 at 7:41
    
Ok I got your point but what about “Code for today, design for tomorrow.” ? If someone or I add more interesting code in the future I can create test for it then. Why should I do it now for the trivial cases ? –  mcaaltuntas Jun 22 '11 at 8:47
1  
@mcaaltuntas: the whole point of TDD is that you test the current specification, so that if a future code change no longer satisfies the current spec, you find out about it. No matter how easy you think it is to implement the spec now, someone might in future change the code without paying attention to this specific requirement, in which case they might break it and they won't realise they need to add a test for it. If you don't write the test now, then you are not doing TDD. If you don't want to test the whole spec, that's your call, but you aren't applying TDD to that part of it. –  Steve Jessop Jun 22 '11 at 9:15

I wouldn't write a test like that (or at least I would not name it like that). Instead, I would write a test for the feature which requires that call to check(), so that if that check or an equivalent action is not done, the high-level feature would not work. Why does your code need to call the check() method?

In general, I try to keep the tests decoupled from the implementation details, so that at least the name of the test talks only about the external features provided by the object. Implementation details such as objects and methods are not mentioned in the test name.

This makes it easier to do refactoring (it shouldn't be necessary to change tests when you change the implementation) and it will also make it easier to find out whether a test is out of date (the feature it specifies is not anymore needed). It will also make it easier to notice unnecessary/dead code, because low-level boilerplate (such as getters and setters) will only be added/kept if they are required by higher level features.

share|improve this answer
    
Ok.You are right about naming you can think of its name "when user clicks check it should check selected file's properties" . But the question is not about naming Do you write tests for "obvious" code or not –  mcaaltuntas Jun 22 '11 at 6:40
    
I have changed test name but question still remains. –  mcaaltuntas Jun 22 '11 at 6:47
    
What should the system do, if that check fails? Throw an exception or something else? I would probably write two tests: what happens when the file is valid, and when it's invalid. If there are many ways a file can be invalid, I would write those tests directly against MediaService. –  Esko Luontola Jun 22 '11 at 7:07
    
Yes Probaby I would write two tests too but not against Controller class I would write them against (like you said) MediaService class. So Actually the test only verifies service class has been called with parameters from view. Do you think is it worth writing this test to only verify arguments passed from view to service class ? –  mcaaltuntas Jun 22 '11 at 7:22
    
"Do you think is it worth writing this test to only verify arguments passed from view to service class?" It depends. If there are end-to-end tests in place which make sure that check works (i.e. it gives an error message or something when the file is not valid), then for the controller's unit tests it might be enough to just check that the method is called; it would give faster protection during refactoring than the end-to-end tests. –  Esko Luontola Jun 22 '11 at 10:04

This is subjective. I don't always do TDD but when I do, I try to keep code coverage as my metric for whether my tests are comprehensive or not. Sometimes, I get lazy and simply skip parts which to me seem "obvious". Sometimes, I violate the Red, Green, Refactor cycle and write more code than is necessary but over time, I've gotten into a rhythm than I'm comfortable with.

share|improve this answer

Interactions between classes like the above and the simpler original I would write a test for. Interactions can become more complex over time so having the ground work in place is a good thing.

share|improve this answer

If someone or I add more interesting code in the future I can create test for it then. Why should I do it now for the trivial cases?

You assume that in the future someone will know that this UI element exists and what it calls on the backend.

My current project has over 30 developers on six distinct teams inside the same code base. Trivial UI additions disappear into the fog all the time. No one will go back and add a test case for this later because no one will remember it is there and when it breaks the demand becomes "Why didn't they write a test? It would have been so simple!"

share|improve this answer

As usual...

It Depends

It's difficult to see the usefulness of this particular test in a TDD context because we don't know the story.

If the story is As a [media user] I want to [be able to check media validity] So that [I'll know when a file is not available]

then the scenario Given [a check media button] When [the user clicks the button] Then [the file validity is checked]

makes sense. It's trivial, but it makes sense.

If the overarching story is larger than this, then the scenario definition may be too narrow.

Remember:

TDD != Unit Testing

TDD tests features. If it's a feature, then it deserves a test to verify it.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.