Hacker News new | ask | show | jobs
by mempko 665 days ago
Unit tests are a waste of time.

Design by Contract + system tests are a far superior technique that take less time and find more bugs.

4 comments

The last comprehensive study I read indicates that they improve internal and external code quality by 76% and 88% respectively while reducing productivity some[1]. If you have papers that indicate your claim I'd be interested in reading them or in ones that refute the metastudy linked below.

1. https://doi.org/10.1016/j.infsof.2016.02.004

TDD and using unit tests are not the same thing, though.

I'm very much a TDD sceptic, but believe unit tests have a place.

Confused, how do you ensure that a change to your implementation of some function isn't going to break clients after deployment if you don't have a unit test?
The client doesn't run your unit tests, but will run you contracts (because contracts deploy with you software while unit tests dont).

You might have realized users of software do things the engineers don't expect, which are not covered in unit tests.

> The client doesn't run your unit tests

That's kinda the whole point... you run them to catch bugs and fix them so your clients never see the bugs you caught in the first place.

> but will run you contracts (because contracts deploy with you software while unit tests dont).

So you'd prefer your contracts to blow up your bugs in your clients' faces, rather than catch bugs yourself prior to releasing the code to them?!

You would obviously test the software before it goes to the users. With contracts you would be able to have information from your users that make it MUCH easier to fix. Without contracts you will have a much harder time fixing the bugs. Contracts catch bugs unit tests don't.
> You would obviously test the software before it goes to the users

That... is literally what unit tests do. Test the software before you give it to users.

You seem confused what the debate is over. Nobody is arguing against contracts. They're awesome. They're just not substitutes for unit tests (or vice versa for that matter). You guys have been arguing against unit tests, which is an absurd position to take, hence this whole debate.

It's not absurd. Unit test are expensive and slow you down while at the same time not targeting the part of software where bugs occur. It's usually HOW functions are composed that cause bugs, not the functions themselves. Contracts rest the interaction of components while unit tests don't.
Unit tests are only worthwhile when your internal machinery is part of the contract.
How do you know the contracts are being followed?
Either through assertions, through fuzz testing, or by formal verification.
Maybe I’m confused on the jargon here, but aren’t unit tests assertions?
No, a unit test is a stand alone bit of code that sets up the environment, runs a bit of code (the unit under test) and checks if the code worker as expected. This does tend to use assertions.

The idea of using assertions, is to put the assertions inside the 'unit under test' so they are checked every time the code is run (sometimes with a way to disable for performance). Then you can run the code normally, and don't need to write a separate bit of code, that has to set up a proper environment (usually with a lot of 'mock' objects).

This style can probably test less, but still works well for 'design by contract'. You can confirm the caller stuck to any requirements of the input, and you can confirm the code stuck to any post-conditions on it's results.

Assertions?
But assertions only tell you you broke someone after the fact (and only if they're enabled)? They don't do anything to help prevent you from breaking them in the first place.
Of course they don't, how could they? How could anything, for that matter? (Apart from guarantees you could ensure statically, natch.)
Assertions triggering in integration tests are different from unit tests. They don't involve writing mocks. They are generally closer to the code, especially with design by contract, so they are more likely to be fixed during a refactor. They encode what you believe your code should do more directly. And they can be used as a basis for formal verification.
Hey, I'm arguing in favour of contracts and assertions here... XD

I even considered formal verification, if under another name.

Ed.

I think I hit a posting limit. After reading dataflow's answer to gp I think I interpreted ggp differently from both of you.

I meant quite literally neither assertions nor unit tests prevent you from breaking things. Of course they'll help you to catch those mistakes before release. I didn't think that counts as prevention.

> Of course they don't, how could they? How could anything, for that matter?

Uh, that's literally what unit tests do? They tell you if you broke any of the cases they test for, before you release your implementation to other people...

Well, that's a mutual misunderstanding then. I meant quite literally neither assertions nor unit tests prevent you from breaking things. Of course they'll help you to catch those mistakes before release. I didn't think that counts as prevention, my bad. Assertions should trigger during system testing if any contracts are broken, so under your interpretation they do prevent breakage as much as units test (meaning before shipping).
Tests have the same effect right?