Live data from Hacker News

The day I started believing in unit tests

mental-reverb.com

21–30 of 269 posts

Re: The day I started believing in unit tests

#21
I was ambivalent on unit tests until I discovered how much the mere act of writing them was finding bugs.

I very vividly remember writing a test for a ~40 loc class of pure functions. I started out thinking the exercise was a waste of time. This class is simple, has no mutable state, and should have no reason to change. Why bother testing it?

By the time I was done writing the test I had found three major bugs in that 40 loc, and it was a major aha moment. Truly enlightening.

Re: The day I started believing in unit tests

#22
post #10

Earlier quoted context omitted.

In reality, unit tests and integration tests are different names for the same thing. All attempts at post facto differentiation fall flat. For example, the first result on Google states that a unit test calls one function, while an integration test may call a set of functions. But as soon as you have a function that has side effects, then it will be necessary to call other functions to observe the change in state. Th…

No. Or maybe only if you also consider 'village' and 'city' to be the same thing.

There are only two kinds of tests: ones you need and ones you don't. Splitting hairs over names of types of tests is only useful if you're trying to pad a resume.

Re: The day I started believing in unit tests

#23
post #15
post #3

unfortunately legitimate use cases for unit tests (like this) are pretty rare in corporate codebases, overwhelmingly, unit tests are just mocked tests that enforce a certain implementation at the class or even individual method/function level and pretend that it works, making it impossible to refactor anything or even fix bugs without breaking tests such tests are not just useless, they're positively harmful https://…

Well-written breaking tests represent something changing in a code base. You can be intentional about breaking a test, but then at least you can be very explicit about what you are changing. Have seen all to many times I've broken a unit test in a code base that I did not intend to break, just to have an aha moment that I would have introduced a bug had that test not been present. Unit tests are a trade off between d…

Especially true if you get emergent side-effects from non-obvious shared state dependencies in large projects.

Nightmares... =)

Re: The day I started believing in unit tests

#24
post #3

unfortunately legitimate use cases for unit tests (like this) are pretty rare in corporate codebases, overwhelmingly, unit tests are just mocked tests that enforce a certain implementation at the class or even individual method/function level and pretend that it works, making it impossible to refactor anything or even fix bugs without breaking tests such tests are not just useless, they're positively harmful https://…

The point of unit tests is not to CYA during refactors, but to confirm that the implementation is consistent between small changes without weird side effects. A coworker once thought unit tests were dumb, and ended up writing code that repeated the call to an application 10x for the same info. This didn’t result in a changed UI because it was a read, but it’s not good to just suddenly 10x your reads for no good reaso…

Using mockserver etc. you can cover for these things in component-test cases even more easily through your whole application while being more flexible with bigger code changes than unit tests allow.

Re: The day I started believing in unit tests

#25
post #10

Earlier quoted context omitted.

In reality, unit tests and integration tests are different names for the same thing. All attempts at post facto differentiation fall flat. For example, the first result on Google states that a unit test calls one function, while an integration test may call a set of functions. But as soon as you have a function that has side effects, then it will be necessary to call other functions to observe the change in state. Th…

No. Or maybe only if you also consider 'village' and 'city' to be the same thing.

Implying that integration tests (or vice versa) are legally incorporated like cities, while unit tests are not? What value is there in recognizing a test as a legal entity? Does the, assuming US, legal system even allow incorporation of code? Frankly, I don't think your comparison works.

Re: The day I started believing in unit tests

#26
post #2

I still like one of the defining characteristics of Unit Tests (paraphrasing Michael Feathers from memory): they are fast and cheap to run. Sure, they might not perfectly simulate production like integration tests, but they also don’t take hours burning cash in cloud infrastructure while risking failure from unrelated races dealing with those dependencies. You can use Unit Tests to get to a place where you’re fairly…

That's exactly it; QA is a layered / tiered / pyramid shaped process, the more you catch lower down, the less reliance there is on the upper layers, and the faster the development iterations.

Re: The day I started believing in unit tests

#27
post #3

unfortunately legitimate use cases for unit tests (like this) are pretty rare in corporate codebases, overwhelmingly, unit tests are just mocked tests that enforce a certain implementation at the class or even individual method/function level and pretend that it works, making it impossible to refactor anything or even fix bugs without breaking tests such tests are not just useless, they're positively harmful https://…

I've been on several projects where we had a significant number of unit tests that would only fail when requirements would change and we had to change the code.

"Look, if it only fails with requirement changes, then maybe we're better off not having them."

This only made people uncomfortable. They just don't like walking down the mental path that leads them to the conclusion that their high coverage unit tests are not worth the tradeoff. Or even that there is a tradeoff present at all.

Meanwhile, PRs constantly ask for more coverage.

Not very often, but sometimes someone will mention: "but unit tests are the specification of the code"

  test ShouldReturnOutput {
    _mock1.setup( /* complicated setup code returning mock2 */ );
    _mock2.setup( /* even more complicated setup code */ );
    
    let output = _obj.Method( 23.5 );
    
    Assert( output == 0.7543213 );
  }

  /* hundreds of lines above this test case */
  setup {
    if ( _boolean ) {
      _obj = new obj(_mock1);
    }
    else {
      _obj = new obj(new mock());
    }
  }
I'm just not sure I can get there.

Re: The day I started believing in unit tests

#28
I think about unit tests being useful for getting more confidence that some deterministic, pure (mathematically speaking) and stateless piece of code that's data in data out actually works, particularly when you change it.

If any of those conditions doesn't hold the cost/benefit certainly and even sometimes the absolute utility goes way down.

If I have to mock anything, in particular, or more generally care at all about any implementation details (ie side effects) then I just think might as well make this a full on automated functional test then.

As soon as fake code is introduced into the test its utility rapidly decays in time as the things it fakes themselves change.

Re: The day I started believing in unit tests

#29

Good story. I for one do not believe in Unit Tests and try to get LLM tooling to write them for me as much as possible. Integration Tests however, (which I would argue is what this story is actually praising) are _critical components of professional software. Cypress has been my constant companion and better half these last few years.

You should try switching it up. Write the tests and then ask the LLM to write the code that makes them pass. I find I'm more likely to learn something in this mode.

Re: The day I started believing in unit tests

#30
post #2

I still like one of the defining characteristics of Unit Tests (paraphrasing Michael Feathers from memory): they are fast and cheap to run. Sure, they might not perfectly simulate production like integration tests, but they also don’t take hours burning cash in cloud infrastructure while risking failure from unrelated races dealing with those dependencies. You can use Unit Tests to get to a place where you’re fairly…

From Working Effectively With Legacy Code by Feathers, p. 14[0]:

Unit tests run fast. If they don’t run fast, they aren’t unit tests.

Other kinds of tests often masquerade as unit tests. A test is not a unit test if:

1. It talks to a database.

2. It communicates across a network.

3. It touches the file system.

4. You have to do special things to your environment (such as editing configuration files) to run it.

Tests that do these things aren’t bad. Often they are worth writing, and you generally will write them in unit test harnesses. However, it is important to be able to separate them from true unit tests so that you can keep a set of tests that you can run fast whenever you make changes.

[0]: https://www.google.com/books/edition/Working_Effectively_wit...

Post reply on HN