Live data from Hacker News

Write tests. Not too many. Mostly integration

blog.kentcdodds.com

161–170 of 338 posts

Re: Write tests. Not too many. Mostly integration

#161
I disagree with this article.

Software projects can be extremely large and have wildly different requirements. Software that needs to operate at high scale and require high reliability will have differenet requirements for say - a web application that has low traffic.

I think making rules of thumbs like the title of this article defeats the purpose of one of the essential tasks of being an engineer - making good tradeoffs between different approaches to solving problems. It's not hard to see that some projects will require more unit testing, some may require more integration testing and others may require more of both.

Re: Write tests. Not too many. Mostly integration

#162

Earlier quoted context omitted.

People just don't write comments or tests after, that's the problem. If you do then that's fine, but after trying both routes I actually find TDD to feel like less work - not having to wait on large build times and manually navigating the UI actually makes for a more fun experience. Instant feedback being the fun part. Additionally writing tests 'after' always feels like work to me and I end up hating it, especially…

> People just don't write comments or tests after, that's the problem. Doesn't that get caught in code review anyway though? I find being forced to write tests first can be clunky and inefficient. Also, I've worked with people who insist on the "write the minimum thing that makes the test pass" mantra which I find really unnatural like you're programming with blinkers on. TDD takes the fun out of coding for me someti…

>I find when you're writing tests first, you're being forced to write code without understanding the problem space yet and you don't have enough code yet to see the better abstractions.

That's why it's better to start with the highest level tests first and then move down an abstraction level once you have a clearer understanding of what abstractions you will need.

Re: Write tests. Not too many. Mostly integration

#163

Earlier quoted context omitted.

>That said, if you go for functional style in OOP, i.e. shoving as much as you can into static helper functions and most of the rest into dumb private stateless functions, you suddenly gain both a clean architecture and lots of test points to use in unit tests. So you can have testable code, but you have to chill out with the OOP thing a bit. Wow, this is exactely totally opposite of how one can achieve testability i…

I'm not sure if this article is clever satire. > The basic issue with static methods is they are procedural code. So is any object-oriented code. OOP is a subparadigm of procedural programming. > Unit-testing needs seams, seams is where we prevent the execution of normal code path and is how we achieve isolation of the class under test. seams work through polymorphism, we override/implement class/interface and than w…

The OOP = Java trap is all too common, but the converse is also a trap: just because you've written OOP code in a different environment doesn't mean that pattern will work in Java.

Go with what the ecosystem supports, and you'll find your tooling helps you a lot more than if you fight against it by trying to force non-idiomatic structures. Your colleagues will appreciate it, too.

Re: Write tests. Not too many. Mostly integration

#164
post #27

Earlier quoted context omitted.

It depends on what you unit test and why. If it's for 100% test coverage: forget about it. If you test private methods: you're doing something wrong. What people usually see from the "unit test evangelists" are codebase for which you have tests for every method in the code. Then you do some refactoring and you have to rewrite tons of tests. And as those tests are just made to get 100% coverage you end-up with logic b…

People test private methods because edge cases occur in those private methods and the test for the edge cases do not belong in the unit test for the consumer of the private unit. If the consumer simply loops over a list of objects which it receives from the private unit, the consumer does not need to know that particular integer arguments are special cases in the private unit; that would be a leaky abstraction. Howev…

My general theory is that if a private method is complex enough to need separate testing, it's usually complex enough to pull out into its own class and test as a separate public interface. That's 'interface' as in 'what a class exposes to its callers', not necessarily using an actual Java interface or making it part of the public API of the library.

A side-benefit is that the tests for the original class can be a lot simpler too, as I can just mock the responses from what used to be the class internals. Another benefit for libraries, is that it allows consumers to swap out your implementation. I've lost track of the times I've wanted to change something deep inside a library but it's implemented in a private method so I can't even override it.

This does lead to more, smaller, class files. But unless taken to extremes I've not found it to make things less comprehensible, and it definitely makes things more composable.

Re: Write tests. Not too many. Mostly integration

#165
post #150
post #6

I'd take a slightly different take: - Structure your code so it is mostly leaves. - Unit test the leaves. - Integration test the rest if needed. I like this approach in part because making lots of leaves also adds to the "literate"-ness of the code. With lots of opportunities to name your primitives, the code is much closer to being self documenting. Depending on the project and its requirements, I also think "lazy"…

I have adopted the same philosophy. A few resources on this, part of the so-called London school TDD: - https://github.com/testdouble/contributing-tests/wiki/London... (and the rest of the Wiki) - http://blog.testdouble.com/posts/2015-09-10-how-i-use-test-d... - Most of the screencasts and articles at https://www.destroyallsoftware.com/screencasts (especially this brilliant talk https://www.destroyallsoftware.com/tal…

Thanks for the links, they make sense - I've always had trouble with blind "you should unit test" advice, but especially the video explains the reasoning very well :)

Re: Write tests. Not too many. Mostly integration

#166
post #150
post #6

I'd take a slightly different take: - Structure your code so it is mostly leaves. - Unit test the leaves. - Integration test the rest if needed. I like this approach in part because making lots of leaves also adds to the "literate"-ness of the code. With lots of opportunities to name your primitives, the code is much closer to being self documenting. Depending on the project and its requirements, I also think "lazy"…

I have adopted the same philosophy. A few resources on this, part of the so-called London school TDD: - https://github.com/testdouble/contributing-tests/wiki/London... (and the rest of the Wiki) - http://blog.testdouble.com/posts/2015-09-10-how-i-use-test-d... - Most of the screencasts and articles at https://www.destroyallsoftware.com/screencasts (especially this brilliant talk https://www.destroyallsoftware.com/tal…

[deleted]

Re: Write tests. Not too many. Mostly integration

#167

Integration testing is especially important when talking to a database. People seem to like mocking the data, but that completely misses the subtleties of how databases actually work, including aspects such as concurrency, transaction isolation levels, locking and such. There should be a few well crafted tests that modify the database from several parallel threads, and afterwards verify that no invariants have been b…

This is the part I don't get when people preach the gospel of ultra-isolated test suites where nothing talks to an external system. The most nontrivial parts of your code, the most likely to break, are those that talk to external systems.

Building a mock of that system sophisticated enough to sufficiently capture even a significant fraction of the "real" failure modes is just as, if not more error-prone and daunting a task.

Totally isolated tests make it impossible to test the most failure-prone parts of your code in anything approaching a satisfactory manner. Maybe I'm just misunderstanding people's advice but it drives me crazy when I see that.

Re: Write tests. Not too many. Mostly integration

#168

Earlier quoted context omitted.

> People just don't write comments or tests after, that's the problem. Doesn't that get caught in code review anyway though? I find being forced to write tests first can be clunky and inefficient. Also, I've worked with people who insist on the "write the minimum thing that makes the test pass" mantra which I find really unnatural like you're programming with blinkers on. TDD takes the fun out of coding for me someti…

What you describe is the typical mindset against TDD, it's difficult to explain the benefits, and really you just have to experience them for yourself. Changing your mindset is difficult, I know, why change what works right? My only tip is to keep an open mind about it, as TDD benefits are often not apparent to begin with, they only come after a couple of days work or weeks or months later or even years later. You fi…

> Any refactoring done is safe from regressions, because of your comprehensive test suite.

As much as I like the idea of TDD, I have a problem with this part. When some refactoring is needed, or the approach changes, it seems like you have two choices. One is to write the new version from scratch using TDD. This wastes extra time. The other is to refactor which breaks all the guarantees you got before. Since both the code and the tests are changing, you may lose the old coverage and gain extra functionality/bugs.

And unfortunately in my experience, the first version of the code rarely survives until the deployment.

Re: Write tests. Not too many. Mostly integration

#169
post #26
post #3

Good lord. Why integration tests? I think the biggest thing you can do to write more integration tests is to just stop mocking so much stuff. Okay. The biggest problem I see with people trying to write unit tests is that they don’t want to change how they write code. They just want tests for it. It’s like watching an OO person try their hardest to write OO code in a functional language. So they try to write E2E tests…

No true Scotsman. You might be speaking about those cases where people write large god classes, pervasively side-effectful code, zero API design, and a general lack of pure abstractions - then their tests would equally be bad. Tests are code, so one's ability to design programs would reflect on their tests and vice versa. But a reasonable programmer who cares enough about what they do can still end up with a brittle…

This is a great comment, not sure why it's at the bottom of the thread. Gets to the core values underlying the main religious beliefs about testing.

Re: Write tests. Not too many. Mostly integration

#170
I am currently in a project where we do not use TDD, even remotely, but we do have almost 100% coverage, since we need it for certification purposes.

These tests are fairly easy to write, actually, with a test framework that helps mock everything automatically.

Then we have some internal tools written that makes these tests worth a lot less, we produce a lot of the test data and then just record the outputs as "correct". We have no real idea if they are correct, but at least the tests as they are now works as regression tests. This is what happens when you realize you need unit tests for tens of thousands of line of code in a few weeks' time, instead of writing the tests when you write the code.

There are of course testing on higher levels for this industrial system, multiple levels even and I have to say that the unit tests are fairly useless in comparison.

Post reply on HN