News for hackers. Stuff that matters.
Re:Where unit testing fails by peteretep on Monday July 25, 2011 @06:33AM (#2802084)
It's hocus where contrasted to developer-driven testing, because Test Driven Development - as a development methodology (as opposed to a tool) - espouses that you Write All Your Tests first.

Have I had experience (and much value) out of sometimes writing tests for certain problem classes before writing any code? Yes. Changes to existing functionality are often a good candidate.

Does TDD as a methodology suggest you should ALWAYS write your tests first? Everything I've read suggests so.

And "as any fule kno" [sic], this is idioicy during a design or hacking or greenfield phase of development. Allowing your tests to dictate your code (rather than influence the design of modular code) and to dictate your design because you wrote over-invasive test.

tl;dr: Writing tests before code works pretty well in some situations. Test Driven Development, as handed down to us mortals by Agile Testing Experts and other assorted shills, is hocus.

Re:Where unit testing fails by Volpe on Monday July 25, 2011 @07:03AM (#2802148)
> Writing tests before code works pretty well in some situations. Test Driven Development, as handed down to us mortals by Agile Testing Experts and other assorted shills, is hocus.

What? So it works in some situations, but not all. Thus hocus?

I'm no 'Agile Testing Expert', but I have worked for the last 2-3 years doing TDD exclusively (as in ALWAYS writing tests first). It isn't hocus. It is effective. I can understand it doesn't suit all problems, and can potentially be a hinderance sometimes, but that is the same for ANY methodology/practice. I don't quite understand your hostility towards it.

What do you mean by 'developer driven testing'?

Re:Where unit testing fails by tomjen3 on Monday July 25, 2011 @07:56AM (#2802261)
The hocus is not that you can use TDD, if, in your professional judgment, you believe that to be the best solution to the problem.

The hocus is that you must use it, because some guru said so.

Re:Where unit testing fails by peteretep on Monday July 25, 2011 @10:01AM (#2802631)
> I can understand it doesn't suit all problems, and can potentially be a hinderance sometimes

Then why do it exclusively?

Testing is about helping developers, and recognizing that automated testing is about benefit to developers, rather than cargo-culting a workflow and decreeing that one size fits all.

Writing tests first as a tool to be deployed where it works is "Developer Driven Testing" - focussing on making the developer more productive by choosing the right tool for the job. Generalizing a bunch of testing rules and saying This Is The One True Way Even When It Isn't (I mean seriously, you continued to use it when it was a hindrance?!) - that's not right.

Re:Where unit testing fails by Volpe on Monday July 25, 2011 @08:27PM (#2805390)
Primarily I do web development, with python and ruby, TDDing is VERY well supported, and thus has allowed me to do it exclusively. But I can imagine there are systems out there that are difficult to TDD, web apps are not among them though.

Sounds like you are interpreting TDD in a rather extreme way. If you haven't found it useful, then fine don't use it. But that doesn't mean it is universally bad, and thus doesn't deserve the "It's all hocus and you are a stupid zealot if you do it"

Re:Where unit testing fails by berntb on Monday July 25, 2011 @08:36AM (#2802342)
Excuse me for interrupting the budding flame war, but I have a question regarding the subject, which you seem qualified to answer? :-)

My experience is the same as (what I believe is) the usual criticism of tests-first.

I often need to rethink the API to my functions/methods, sometimes more than once. This goes for both external and internal APIs, so it doesn't help with detailed interface specifications between modules.

Test-first is a problem, since it needs a fixed interface before I'm ready to lock down the interface.

I tend to instead write inside-out; a few pages of code and then write tests for that code. That model isn't really kosher/halal/etc, according to TDD?

Re:Where unit testing fails by tychof on Monday July 25, 2011 @09:13AM (#2802446)
One benefit to TDD is that you become a user for your API much more quickly, and so your API doesn't need to change as much.

TDD suggests 3 steps: 1. Write one test 2. Write the minimal code to make it pass 3. Refactor the code you've got.

Try not to think of tests as immutable. You can throw away tests when they don't provide value.

Finally, make sure you're using an IDE with refactoring support. That helps immensely when you make an API change which will affect your tests.

Re:Where unit testing fails by berntb on Monday July 25, 2011 @10:19AM (#2802697)
OK, thanks to you and zumda.

Interesting TDD argument. I'll buy a book or something and try again when my present hobby project is done and I have time for experimenting.

(IDE refactoring needs a stricter language than I prefer. Also, without an IDE and using my old eyes I have 2 A4 of code + 1 A4 of bash on a 24" monitor...)

Re:Where unit testing fails by zts on Monday July 25, 2011 @12:16PM (#2803212)
If you're looking for book suggestions, I'd recommend "Growing Object-Oriented Software, Guided By Tests" by Steve Freeman and Nat Pryce. It's pretty pragmatic, and the treatment of the subject is pretty thought-provoking (at least, I thought so when I read it).

The examples are all Java, but the accompanying website (http://www.growing-object-oriented-software.com/) has links to reimplementations in several other languages.

Re:Where unit testing fails by zumda on Monday July 25, 2011 @09:17AM (#2802459)
According to TDD writing inside-out is one of the points it tries to combat.

The point of using TDD to write interfaces is that you first write the code you wish you had, and then implement it. The other way around you could end up with code that is optimized for the code inside the module, and not optimized for using it.

Of course now you have to rewrite your tests and your code when changing an API, but at least you know that no other part of your application got broken by the new API.

I personally like the TDD approach to write interfaces, since then I won't take shortcuts just because it is easier to do in the specific module that I'm programming/extending. It will actually produce code that can be used easily from the outside and removes a lot of dependencies in the process.

Re:Where unit testing fails by arethuza on Monday July 25, 2011 @07:26AM (#2802197)
I don't think I've ever seen a description of TDD that suggests you write all of your tests before writing any production code - rather you iteratively write some tests, have them fail then write the code to make them work and then see the tests pass, repeating that process until you have implemented everything you need.
Re:Where unit testing fails by eru on Monday July 25, 2011 @09:59AM (#2802621)
You can work within TDD by just calling all code that comes before the tests a `prototype'.
Re:Where unit testing fails by peteretep on Monday July 25, 2011 @09:58AM (#2802616)
Sure, but you write /some/ tests first. And that means, if you want to do it meaningfully, that you either need to zoom down in to tiny bits of functionality first in order to be able to write those tests (see the isPalindrome discussion in the article), or you write a test that requires most of the software to be finished, or you cheat and fudge it.

Making tests a central part of the process because they're useful to developers? Awesome. Dictating a workflow to developers that works in some cases as the One True Way: ridiculous.

Re:Where unit testing fails by jsdalton on Monday July 25, 2011 @08:47AM (#2802363)
I've always thought of testing as simply a way to verify that your code does what is supposed to do.

I tend to agree with you that TDD as a development methodology is deeply flawed. I have never found that the act of writing a test case and making it pass has helped me with the actual creative process of solving a problem via code. In fact, I'll frequently dash out a method I'm writing quickly, and then go back and reconstruct it piece by piece via TDD.

The main benefit writing tests first gives you is that you know your test is actually working (i.e. because it first fails) and that the code you implement actually passes it. It also keeps you honest because it prevents you from writing "extraneous" code, i.e. code that exists but is not specified by a test.

So yeah, I totally agree with you that the cult of TDD kind of sucks. But I haven't stumbled upon a better way yet. I've often thought it would be cool if there was some way for e.g. your version control software to be tied to the code you write that passes certain test(s), such that you could somehow verify that without that code your test fails and with that code your test passes. For the present though, TDD tends to work pretty well for me.

Re:Where unit testing fails by peteretep on Monday July 25, 2011 @09:55AM (#2802596)
I think you're narrowing in on the distinction I'm trying to make between a methodology and a tool there; writing tests before you implement a piece of functionality is a useful tool to have in your testing toolbox.

Labouring under the idea that Tests Must Come First (and everything I've seen, and everything I /do/ see now suggests that that is the central idea in TDD - you write a test, then you write the code to pass it) without pivoting to see that testing is a useful practice in so much as it helps developers is the wrong approach.

Re:Where unit testing fails by misfo on Monday July 25, 2011 @11:07AM (#2802900)
I think you've hit the nail on the head, @peteretep.

The problem is that ideologies like TDD try to come up with simple rules for how to develop (i.e. always write tests first). In reality, it's better to use your brain when you're deciding how to approach something (i.e. is this a good situation for writing tests first?)

Re:Where unit testing fails by wnight on Wednesday July 27, 2011 @05:19AM (#2811425)
Perhaps by permuting your code the system could determine if there was anything that wasn't required to make the test pass and exclude it from the check-in.

I often code three or four commits worth at once when on a roll and it's a pain doing multiple staged adds, stashes, tests, and commits to store each sub-change on its own. Having a tool to help with this would be great.

Re:Where unit testing fails by elmomalmo on Monday July 25, 2011 @06:47AM (#2802107)
This is a common misconception. TDD does not 'espouse' in any way that you write all your tests first. Nothing I have read suggests so.

For me, TDD, in practice means switching back and forth between writing tests and production code. That is, write some test code, run, fail, fix the production code, write some more test code. It is incremental.

EDIT: Fixed a typo

Re:Where unit testing fails by wnight on Wednesday July 27, 2011 @05:13AM (#2811414)
> And "as any fule kno" [sic], this is idioicy during a design or hacking or greenfield phase of development.

When you write something you run it to make sure it works. Bottle that and call it a test. And then merely do this before you write the code. "What will I be done when I get this code to do?"

Don't plan, and spec, your whole API before you've written a line of code or anything, but do write a one-liner to check whatever it is you're going to do so you know when you're done.

Ideally you'll write a test (still just a one-liner) for every corner-case that you cover in code, because you need a failing test to know if your fix actually worked.

And face it, if you're doing "real" development work you've got business goals, and a spec with features intended to deliver on that, and you need to cover every tiny detail. If you don't have the spec ('fail on values over n') directly linked to the code that implements it, it will get lost, and if you aren't testing it you can't legitimately claim to be delivering it.

A spec, such as you'd get by performing useful TDD, is a requirement for modern software development. You could write it all up-front in the planning phase (waterfall style), or all after in the testing phase (waterfall style again), or you could interleave it with research and development, which if you think about it, sounds kind of agile by comparison...