views:

198

answers:

8

I've been using TDD for server-side development. I'm not really sure if the benefits of having all of my production code surrounded by unit tests outweigh the disadvantage of spending 4x more time than needed on refactoring.

But when I'm developing UI code, I simply cannot apply TDD. To all fundamentalists out there, the first law of TDD states that "you may not write production code until you have written a failing unit test". But how can this be if you are developing UIs?

(One can use acceptance test frameworks like Selenium, but that doesn't count, because you don't interact directly with the source code.)

So, can I tell my manager that because of the new >90% code coverage policy I cannot write user interface code?

A: 

Unit tests are inappropriate for UI code. Functional tests are used to test the UI, but you cannot feasibly write those first. You should check with your manager to see if the >90% code coverage policy covers UI code as well. If it does, he should probably seriously rethink that move.

Marc W
You cannot use TDD for Markup, nor for javascript (if you're using ASP.NET) but you can use TDD for your code behind, even for the UI elements, if there is logic and computation going on in the C# codebehind, then you can unit test it.
A: 

Separate the business logic from the UI and ensure that the UI code takes less than 10% of the total? Separation of concerns is the main goal of TDD, so that's actually a good thing.

As far as 90% coverage goes ... well, best course is to review extant literature (I'd focus on Kent Beck and Bob Martin), and I think you'll find support for not following a mindless coverage percentage (in fact, I think Uncle Bob wrote a blog post on this recently).

kdgregory
Kent Beck and Bob Martin? Can you clarify? Their books are used as arguments defending high code coverage... Uncle Bob even says not using TDD is irresponsible and unprofessional... Do you have the link to that blog post? Thanks
ivo
+3  A: 

TDD is about testing methods in isolation. If you want to test your UI you are doing integration tests and not unit tests. So if you carefully separate the concerns in your application you will be able to successfully apply TDD to ANY kind of project.

Darin Dimitrov
Suppose you have some sort of a Menu class and you want to implement user interaction behavior. This is not an integration test. How can you test it? How can you write a unit test that fails prior to write the production code? Can you also apply TDD to this class?
ivo
Sure, you need to check out the MVP pattern (http://msdn.microsoft.com/en-us/magazine/cc188690.aspx) which is great for such scenarios.
Darin Dimitrov
Basically it is the presenter that has a reference to your view (an interface) and manipulates it.
Darin Dimitrov
A: 

A having a >90% code coverage is dumb because a smart dev can get 100% coverage in one test. ;)

If you are using WPF, you can test your UI code if you use the MVVM pattern. By test your UI code, i mean you can test the ModleView but there is nothing that I know that can test XAML.

Tony
+4  A: 

If you find that writing TDD causes you to spend 4x more time on refactoring, you need to be writing better, more isolated tests, and really let the tests drive the design, as intended. You are also not counting the time you spend in the debugger when you refactor without tests, not to mention how much time everyone else spends on bugs you introduce when you refactor.

Anyway, here is some good advice about what TDD means for UI development. How much that will translate into code coverage depends heavily on the UI framework.

Definitely don't tell your manager you can't do it, he may just replace you with someone who can.

Yishai
+1  A: 

That policy sounds a little artificial, but I would agree with the answer that UIs require functional test cases, not unit test. I disagree however with the point about which comes first. I've worked in an environment where the UI functional tests had to be written before the UI was developed and found it to work extremely well. Of course, this assumes that you do some design work up front too. As long as the test case author and the developer agree on the design it's possible for someone to write the test cases before you start coding; then your code has to make all the test cases pass. Same basic principle but it doesn't follow the law to the letter.

James Cadd
I agree with the artificial characterization. It sounds like a manager heard somewhere that 90 is a good number and made it a rule without having a full understanding of coverage issues.
JeffH
A: 

Read Phlip's book

Carl Manaster
+3  A: 

First off, even Robert Martin has testing challenges with UIs.

When TDDing a UI, you write "behavioral contracts" that get as close to the action as possible. Ideally that means unit tests. But some UI frameworks make that inordinately difficult, requiring that you step back and use integration or "acceptance" tests to capture how you expect the UI to behave.

Does it not count if you can't use unit tests? That depends on which rules you're using to keep score. The "only unit tests count" rule is a good one for beginners to try to live with, in the same vein as "don't split infinitives" or "avoid the passive voice". Eventually, you learn where the boundaries of that rule are. In one podcast, Kent Beck talks about using combinations of unit and integration tests, as appropriate (adding, if I recall correctly, that it doesn't bother him).

And if TDD is your goal, you can most certainly write Selenium tests first, though that can be a slow way to proceed. I've worked on several projects that have used Selenium RC to great effect (and great pain, because the tests run so slowly).

Whatever your framework, you can Google around for TDD tips from people who've fought the same battles.

Dave W. Smith