Hacker News new | ask | show | jobs
by bluejekyll 3825 days ago
I'm sorry, but what?!

Unit testing is not an exercise in the mundane by making your manager happy, it is about validating that the thing you just wrote actually works, so that you can move on to the next thing, eventually aggregating all of that work together and constructing code that works!

As others have said, you test inputs and outputs (and maybe you need to test some failure modes depending on the complexity of the situation). When you're working on a parser, or lexical analyzer of any sort, wouldn't it be nice to know that it is capable of parsing what you thought it should?

System/BlackBox/Integration tests are too high-level and the more you rely on those as your sole testing, the more brittle and difficult you make it to track down the cause of test failures. It also means that you have to spend more time constructing test scenarios to testing the inner-workings of the system, things that are easier to do in unit tests. Bloated tests at that layer actually make it MORE difficult to refactor.

Decent unit tests help you define the inputs and outputs of your functions/classes/design. If it's hard to write a unit test on it, then you probably have side-effects in the code that you can't properly account for (bad code design). When it comes to a point that you need to refactor and the unit test is in your way, then guess what? refactor/delete the test...

2 comments

> As others have said, you test inputs and outputs (and maybe you need to test some failure modes depending on the complexity of the situation). When you're working on a parser, or lexical analyzer of any sort, wouldn't it be nice to know that it is capable of parsing what you thought it should?

That would be a system test. Nobody would write a parser in one function, so it's full functionality can't be tested in a unit test. This is also exactly the sort of test I'm advocating. The thing I'll guarantee you though : it won't provide 100% code coverage.

Unit tests are this kind of crap, testing trivial things 100 times. You immediately see why they provide 100% code coverage : https://en.wikipedia.org/wiki/Unit_testing#Design

> the more brittle and difficult you make it to track down the cause of test failures

Yes ! This of course happens because they find ever-more subtle bugs, not because there's something wrong with the test.

> it won't provide 100% code coverage.

Yeah. 100% coverage is BS, again I go back to proof of quality.

> because the find ever-more subtle bugs

Well, yes and no. Yes integration tests are important for finding subtle bugs between different components of a larger system. No, bc an over-reliance on these instead of proper unit-testing, you end up with code bloat in your integration tests, and a maintenance nightmare because the tests are more complex. On top of that because you have so many integration tests It becomes unclear when the integration test is testing a valid API construct, vs something internal, making it very difficult to refactor code because you don't know what's expected API response vs some odd internal bug that you had to test for bc you didn't have a good unit test for the internals.

There's an old and frustrating terminology problem here. You mention testing a parser; assuming the parser contains more than one class, or group of functions, i would consider a test of the whole parser to be an integration test, not a unit test.
By parser I mean any small thing that might parse text.

Since I tend to deal with distributed systems, I generally think in terms of blackbox tests as dealing with application APIs rather than function APIs, and integration tests as multiple system components being tested together.