4 ms·
Agree with the reasoning here, so as a result I almost never use TDD: I pretty much always have to spike + iterate in order to come to a reasonable and clean so
by thatswrong0 5y ago
Agree with the reasoning here, so as a result I almost never use TDD: I pretty much always have to spike + iterate in order to come to a reasonable and clean solution for whatever I'm working on.. no matter how much I've tried to spec things out exactly how they should work, it always ends up being different. I'm also just not great at abstract vs. hands on thinking.
On top of this, I've also come to find unit tests to generally require more work and be less useful for identifying regressions than integration tests for the work I do. Maybe this is just a result of the kind of work I do though.
- bvirb 5y agoSame here. So much so we've basically just dropped "unit" testing in favor of integration testing. I guess we still call it TDD though. I was actually surprised what the author was describing was somehow _not_ TDD. I thought it was pretty normal to try some things out, make some decisions, and then return to codifying those decisions in tests. We do web app development, and 90% of our tests are browser-based integration tests that test whether the given inputs (usually forms) lead to the expected outputs (usually something printed on a web page). I wonder if this is more natural when you're mostly writing integration tests?
- deleted 5y ago[deleted]
- jasonswett 5y agoI personally don't see any reason why the type of test matters when doing TDD. As I see it you can do TDD with integration tests just as much as you can do TDD with unit tests. The only difference to me is that the work involved might take on a bit of a different character. But that doesn't make it not TDD to me.
- pydry 5y agoI've found TDD can work pretty well with integration tests. Often better. I dont really get why the practise is so intrinsically linked to the practise of writing unit tests. Increasingly I'm starting to believe unit tests are a scam, but TDD is going to stick around in one form of another forever.
- markmaglana 5y agoJB Rainsberger would like a word with you :-) https://blog.thecodewhisperer.com/permalink/integrated-tests-are-a-scam https://blog.thecodewhisperer.com/permalink/integrated-tests...
- leemcalilly 5y agoI find my system/integration tests to be the most valuable because those test the behavior of my code, what the end user cares about. It often helps to start with the design first (even if just a napkin sketch). Once I’ve done that I usually have enough information to write system tests (which also forces me to consider edge cases). Then I can then fill in with unit tests as needed as I write the code to get the system tests for that feature passing.
- no_wizard 5y agoI think this highlights that the core of TDD is understated. The core of TDD is encapsulated in the saying Red, Green, Refactor - Write the Test, they're going to fail cause you have no implementation - Write the implementation, so that those tests are green - Refactor to clean up the code, make it real nice Rinse and repeat as needed, until you've settled on a fully tested solutions. If you do this, you are practicing TDD as its intended. I think the overall message around TDD, how it gets talked about in industry, and how its gotten promoted (or not promoted, I guess?) makes it so confusing. This is the heart of it here, is to rinse and repeat these 3 steps, always starting with writing Tests first, which is to validate that you understand what you're building What I have found in my decade+ doing this is that most of the time when I run into team members who draw blanks or feel that TDD is a roadblock is that's one way or another they don't have enough information about the requirements of the work involved in what they're doing. Not sure if this helps anyone or not, this has been my general experience and may not capture every case, though I feel confident enough that this is a shared experience that I hope it brings another way to think about TDD in terms of simplicity.
- eesmith 5y agoI've never liked what's missing under the red-green-refactor TDD description. Perhaps your experience can offer insights? Consider Martin's primes kata, at http://www.butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata http://www.butunclebob.com/ArticleS.UncleBob.ThePrimeFactors... . The final version is: public class PrimeFactors { public static List<Integer> generate(int n) { List<Integer> primes = new ArrayList<Integer>(); for (int candidate = 2; n > 1; candidate++) for (; n%candidate == 0; n/=candidate) primes.add(candidate); return primes; } } In red-green-refector TDD, where do I add tests that are expected to pass? In this case, boundary analysis says that if the function takes an int, then I should include tests for negative numbers, and tests for large values, like 2^31-1, which is MAXINT and also a Mersenne prime. (Neither of these are in Martin's tests, which only test 1, 2, 3, 4, 6, 8, and 9.) When should I add the test for 2^31-1? Your "Write the test" says we should only write tests which will fail because it has no implementation, but in this case we expect it to pass because we have an implementation. Do we not write that test? Which leads to my issue with the "refactor" step of "red-green-refactor." Suppose you add that test for MAXINT. It takes about 5 seconds to run because of it does >2.1B modulo tests. Implicitly, TDD tests are a supposed to be fast. Not 5 seconds per test. Or the spec might explicitly require (say) a 1ms execution time, or you might find that system tests fail because this algorithm is too slow. There are any number of faster factoring methods, as Eratosthenes well knew, so pick one and implement it. Is this in the "refactor" step? Technically "Substitute Algorithm" is one of Fowler's refactorings, so yes. But Fowler's refactoring are meant to make things cleaner and easier to understand. Not whole-sale replacements with additional complexity. In the discussions I've seen, the refactor step in red-green-refactor starts and ends with the same tests. While a more complicated implementation may have its own set of special cases to consider. (For example, a complex sorting method like Timsort needs more tests than quicksort to cover all the code paths.) The descriptions of "red, green, refactor" TDD I've seen completely ignore these issues of when to add additional tests you expect to pass, and how to refactor for purposes other than "make it real nice." I agree that starting with MAXINT would immediately 'validate that you understand what you're building.' But most TDD examples seem to start with the easy cases first, not the hardest. They teach an incremental design approach where experience from the easy cases helps progress towards the final solution. My experience is that approach can lead to an implementation which requires a design methodology more powerful than red-green-refactor to resolve.
- commandlinefan 5y ago> less useful for identifying regressions I've observed the same, but having the ability to run any given function in isolation is huge for diagnosing problems. Does this function respond correctly to the correct input? Yes? Ok, that's not where the problem is. Next.