Live data from Hacker News

The tragedy of 100% code coverage (2016)

labs.ig.com

261–270 of 346 posts

Re: The tragedy of 100% code coverage (2016)

#261
You don't need to test that. ... The code is obvious. There are no conditionals, no loops, no transformations, nothing. The code is just a little bit of plain old glue code.

Here's the code:

  @Override
  public void initialize(WatchlistDao watchlistDao) {
    watchlistDao.loadAll(watchListRow -> watchlists.add(watchListRow));
  }
Maybe I'm dense, but this code raises at least one question that I would prefer to see answered by tests.

The parameter watchlists appears to be defined in a scope above the one under test. What happens if watchlists is null for some reason? What should be the behavior?

Then there's the tricky question of what to do as this method evolves. Next month, a watchListRow might need to be updated with a value before being added to watchlists. Later, a check might be added to ensure some property exists on watchListRow. At what point will a test be written for this method?

Re: The tragedy of 100% code coverage (2016)

#262

I wish people cared more about the craft of an amazing plugin architecture or an advanced integration between a machine learning system and a UI, but no, more and more of our collective development departments care more about TDD and making sure things look perfect. Don't worry about the fact that there are no integration tests and we keep breaking larger systems, and while there might be 100% code coverage, no devel…

Yes, unit tests have their place, but you have to understand why they are needed.

To me, it's secondary and has tones of bike shedding in it. Writing tests is easy, mentally. Getting a good, simple, YAGNI/DRY architecture is more challenging and requires several iterations, something that is resisted if you have to rewrite all your unit tests. Let me put it this way, if you write an architecture that you later don't like, you would be more hesitant to scrap it and start over because all the additional work of the unit tests (especially if you're on a deadline). That's bad. To write a good architecture, a developer must be willing to realize he could have done it better and be willing to tear it down instead of build around the bad architecture. That's how you write 20 year code, which should be almost everyone's goal.

Re: The tragedy of 100% code coverage (2016)

#263
post #18

I've had to work on mission critical projects with 100% code coverage (or people striving for it). The real tragedy isn't mentioned though - even if you do all the work, and cover every line in a test, unless you cover 100% of your underlying dependencies, and cover all your inputs, you're still not covering all the cases. Just because you ran a function or ran a line doesn't mean it will work for the range of inputs…

> even if you do all the work, and cover every line in a test, unless you cover 100% of your underlying dependencies, and cover all your inputs, you're still not covering all the cases.

On the other hand, if you do cover all your inputs, you've covered all the cases regardless of what % code coverage or path coverage you have.

Re: The tragedy of 100% code coverage (2016)

#264
post #234

Earlier quoted context omitted.

Generalization is at the heart of science. The lack of generalization is one of the most frustrating attacks you can launch on a scientist's empiricism.

We are talking about software testing here. To a first approximation, nobody is being empirical, and there is no science being done.

When you are writing tests, that's an empirical, rather than a theoretical approach to software correctness.

When programmers change a factor to "see what breaks", that is very much an empirical activity, and it is part of the programmer's theory-building of a phenomena.

If a young child takes a gear from a watch and observes its breaking, that is very much an empirical activity. It is also the beginning of theory-building.

You don't need MANOVA to engage in empiricism.

Re: The tragedy of 100% code coverage (2016)

#265
post #221
post #96

Earlier quoted context omitted.

I agree that test coverage does not ensure that the code is really tested. But not covered code is not tested code. So i use coverage in this way, to spot not tested code.

You can test stuff manually.

You really shouldn't, or if you do it should be an extreme minority of tests and automated tests should do the heavy lifting.

Automated tests can do so much more than manual tests that shops still living by manual tests either have a damn good reason or are just as wrong as people who argued against Revision Control Systems (or people who argued for gotos instead of functions).

Automated tests will be executed identically each time, so no missing test cases because someone slacked off or made a typo. Automated test can serve as examples for how to use the code. Automated tests can aid in porting to new platforms, once it builds you can find all the bugs your care about swiftly. Automated test can be integrated with documentation, tools like doxyegn and mdbook make this easier.

Automated tests enable Continuous Integration. Are you familiar with Travis CI or Jenkins? If not, imagine a computer that a team commits their code to, instead of directly to the mainline Revision Control (Git master, svn head, etc...). That computer builds the software, runs all the tests, perhaps on every supported platform or in an environment very close to production, then only merges commits that appear to fully work. This doesn't completely eliminate bugs and broken builds, but the change is so large that teams without it are at a clear competitive disadvantage.

When integrated into process tests can be used to protect code from changes. If a test exercises an API and the team knows that is the purpose then when they change things in a way that break the test they shouldn't... This sounds vague or obvious, but consider this: At Facebook and Google they have a rule that if it is not tested new code doesn't have to care if it breaks. Both companies have team that make broad Sweeping changes. Facebook wrote a new std::string and Google use clangtools to make automated changes in thousands of places at once. Even if code breaks or APIs change as long as tests pass these people can be sure that they negatively impacted the product and are following their team's rules.

Automated Tests can... This list could go on for a very long time.

Re: The tragedy of 100% code coverage (2016)

#266

Earlier quoted context omitted.

If we're being pedantic, a tragedy is _a drama or literary work in which the main character is brought to ruin or suffers extreme sorrow, especially as a consequence of a tragic flaw, moral weakness, or inability to cope with unfavorable circumstances_. Definitely not a tragedy.

If we're being pedantic, there's a second common definition of the word tragedy that does not refer to a drama or literary work, but "an event causing great suffering, destruction, and distress, such as a serious accident, crime, or natural catastrophe." I think when you take all of the time wasted on useless tests written merely for the sake of having tests, that waste is tragic. You could be doing anything else wit…

I am curious if there is any good way to measure that amount of waste. I agree that waste from extra and useless tests exists, but I am not convinced that waste is entirely bad.

It seems to me that waste is unavoidable with teams newer to automated testing and may simply be part of the cost of using automated tests. If that is the case then it seems better to compare the cost of bugs with no automated to cost of superfluous tests. In that comparison extra tests definitely seems like the lesser of two evils, even without hard numbers. I would prefer hard numbers because my intuition could be wrong.

Re: The tragedy of 100% code coverage (2016)

#267
post #138

Earlier quoted context omitted.

> even private ones. You don't test private API, that's why they are declared private, it makes absolutely no sense to test private members. Now the use of the private member might lead to a different code path : it has to be tested. Unit Testing : test one unit ( a class for instance ) in isolation, which means all collaborators (the classes the tested class depends on) have to be stubbed or mocked. Functional Testi…

> it makes absolutely no sense to test private members Don't agree. I think this is something that people tell themselves to justify the anti-pattern that is private members being nearly impossible to test directly in a variety of languages, but it seems like nonsense. I've never seen a real case for excluding private methods as a testable unit.

> I've never seen a real case for excluding private methods as a testable unit.

Here's the reason:

We're not writing tests; we're writing SPECIFICATIONS.

Private methods are implementation details; they're not part of the specification.

Re: The tragedy of 100% code coverage (2016)

#268

The worse the developer, the more tests he'll write. Instead of writing clean code that makes sense and is easy to reason about, he will write long-winded, poorly abstracted, weird code that is prone to breaking without an extensive "test suite" to hold the madness together and god forbid raise an alert when some unexpected file over here breaks a function over there. Tests will be poorly written, pointless, and give…

I inherited a code base with LOTS of test coverage. Made one small change and everything broke. Looked into the tests, oh the humanity!!! Dropped the test suite entirely, haven't had any issues since. We have VERY good logging and notifications though so anything goes wrong we know all about it.

Why not write tests that make sense then?

It would definitely help in maintaining the code (not to mention not having to go through the entire code base when debugging a production issue).

Re: The tragedy of 100% code coverage (2016)

#269

/me raises hand on the pro-testing side I've been programming for a living since 1996, and only recently started to do TDD in the normal sense of writing unit tests before writing code. I've found to it to be an enormous help with keeping my code simple - the tests or the mocking getting difficult is a great indicator that my code can be simplified or generalised somehow I argued for functional instead of unit testin…

I agree that TDD and unit tests can help you when writing code. But once your code has been written, are all those unit tests still useful? Or do they get in your way when you do large scale refactoring? I have seen quite a few codebases with loads of unit tests that might once have been useful, but now were just slowing down development. Many of them should have been thrown away and replaced by a couple of functiona…

> But once your code has been written, are all those unit tests still useful?

The reason for this question is the naming mistake that was made in the beginning. They are not TESTS, they are SPECIFICATIONS.

Once your code has been written, are the specifications still useful? Well, duh... unless the business has changed them then yes, they're still useful.

Re: The tragedy of 100% code coverage (2016)

#270

There are a few relevant facts that should be known to everyone (including managers) involved in software development, but which probably are not: 1) 100% path coverage is not even close to exhaustively checking the full set of states and state transitions of any usefully large program. 2) If, furthermore, you have concurrency, the possible interleavings of thread execution blow up the already-huge number of cases fr…

Also: the fundamental undecidability of the Halting Problem
Post reply on HN