Hacker News new | ask | show | jobs
by jpswade 1756 days ago
The code should explain what it's doing (self documenting code) and tests should explain why it's doing it.

Comments tend to just become a place for misinformation or get disconnected from the actual logic.

Adding more comments sometimes doesn't clarify the situation, it just acts as a second source of truth.

2 comments

> The code should explain what it's doing (self documenting code) and tests should explain why it's doing it.

I agree at a surface level, however:

  - this makes us assume that there are tests in the first place
  - this makes us assume that someone will read these tests instead of asking the developer
  - this makes us assume that these tests will be readable enough on their own to replace free form text
  - this makes us assume that these tests will even be able to contain a representation of why the code exists
  - personally, i have never seen a test that explains a business requirement with enough context not to miss out on details
  - i have also never seen code that encapsulates these requirements 1:1, without getting too mixed up in implementation details
I think that code definitely should describe what it's doing, tests should explain how it's doing it as far as possible (though this requires discipline to have loosely coupled and testable code, which isn't always the case) and that there still should be comments that explain the realities of needing technical solutions for people problems and all of the aspects that are carried with this.

Doing anything less feels like giving ourselves constraints that will lead to suboptimal results because the tooling and testing solutions aren't quite there yet. Maybe when frameworks and languages will become more expressive, we'll be able to live without comments. However, that day may not come anytime soon.

Nor will companies be interested in the overhead that writing extensive and good tests entail, nor will they want to wait for their engineers to figure out how to convey everything in computer code, as opposed to just dropping some comments into the codebase, right next to the actual code that they concern. Maybe when companies are ready for 50% of the development time to be spent on testing software, that won't be an issue. That day may also not come anytime soon.

As a possible counterpoint, look at RSpec, i think it's headed in the right direction: https://rspec.info/

> and tests should explain why it's doing it

I was going to say "So for performance "hacks" there should be a clean implementation that's benchmark against the current implementation for example?" as a way to disprove what you said, but while writing it I realized that it may actually be a pretty good idea.

Yes, there should pretty much always be this.

You've just written some messy unclear code for performance reasons, so it deserves more thorough tests than average.

And you've already written the clean version anyway, since you hopefully didn't write the optimized version until after you profiled the slow one. So it's not even significant extra work to turn that into your test suite.

This could also be a great way to check if your optimized version is still necessary with new versions of your language implementation. The more I think about it, the more it seems like a great idea.
I wouldn't generally throw benchmarking into the unit test process, because it can be brittle. What if something else clobbers the CPU on your test machine at just the wrong time. What you really want from your unit tests is for them to run quickly, so you run them as often as possible, and reliably, so any failure means something is wrong. I'd use the slow implementation just for checking correctness.

But separately, if you want to add a performance benchmarking process (great!), you have a reference baseline implementation for free.

Maybe not directly in the unit tests that you always run on your machine, but having them around could be a good idea.