![]() |
|
![]() |
| Yeah, especially when you're exploring new ground.
Unit tests are awesome for fleshing out APIs; but once the fundamentals are in place, the tests no longer add any value. |
![]() |
| I have two answers:
1. Yes. To the same extent that we are all bad people by definition, made of base material and unworthy urges. I'd love to have better programmers show me how I can make my tests better. The code is out there. 2. Even if I have good tests "by definition", a radical rewrite might make old tests look like "assert(2x1 == 2), assert (2x2 == 4)". Tests exist in a context, and radically changing the context can change the tests you need. --- This is not in OP, but I do also have a problem of brittle tests in my editor. In this case I need to test a word-wrapping algorithm. This depends intimately on pixel-precise details of the font. I'd love for better programmers than me to suggest how I can write tests that are robust and also self-evidently correct without magic constants that don't communicate anything to the reader. "Failure: 'x' started at x=67 rather than x=68." Reader's thought: "Why is this a problem?" etc. Comments appreciated on https://git.sr.ht/~akkartik/lines.love/tree/main/item/text_t.... The summary at https://git.sr.ht/~akkartik/lines.love/tree/main/item/text_t... might help orient readers. |
![]() |
| I watched a video by Russ Cox that was recommended in a recent thread, Go Testing By Example:
https://www.youtube.com/watch?v=X4rxi9jStLo There's _a lot_ of useful advice in there. But what I wanted to mention specifically is this: One of the things he's saying is that you can sometimes test against a simpler (let's say brute force) implementation that is easier to verify than what you want to test. There's a deeper wisdom implied in there: The usefulness of tests is dependent on the simplicity of their implementation relative to the simplicity of the implementation of what they are testing. Or said more strongly, tests are only useful if they are simpler than what they test. No matter how many tests are written, in the end we need to reason about code. Something being a "test", doesn't necessarily imply anything useful by itself. This is why I think a lot of programmers are wary of: - Splitting up functions into pieces, which don't represent a useful interface, just so the tests are easier to write. - Testing simple/trivial functions (helpers, small queries etc.) just for coverage. The tests are not any simpler than these functions. - Dependency inversion and mocking, especially if they introduce abstractions just in order to write those tests. I don't think of those things in absolute terms though, one can have reasons for each. The point is to not lose the plot. |
![]() |
| Not “strange,” in my opinion. Back in The Day, we called what people insist are “test harnesses,” “unit tests.”
But these days, the term “unit test” has morphed into a particular configuration. |
![]() |
| I think we're talking specifically test automation like unit tests, integration tests, and end to end tests. You can't write software without ever trying to run it, which is functional testing. A solo developer e.g. has to be doing these sorts of "QA"/functional manual testing.
Let's look at the source code for Doom: https://github.com/id-Software/DOOM How many _test files do you see? Millions of people played Doom for endless hours and the quality beats a lot of modern software with tests. Again, tests certainly have their place in modern software development, but the kind of thinking that if you have tests that means your quality is good is wrong and actually leads to worse software quality. Tests are just a part of an overall approach to quality software. EDIT: Re hiring. I would be looking for people that understand the nuances and the why vs. people that approach things through a religious lens. I.e. they understand the tradeoffs. If you're writing tests then your tests are code. Should you write tests for your tests? If not why not? How do you know that your tests are correct? If your religion says 100% unit test coverage for all code then it's pretty clear this is a religious belief not subject to reason (because otherwise you'd be also asking for 100% coverage for your unit test code by other unit tests). There are situations where unit tests have a ton of leverage. There are situations where they have less. Testing happens in other disciplines, e.g. mechanical engineering, where certain things get tested (including with automation) and others do not. The decisions depend on the function of the component, the impact of failure, preexisting knowledge about the technologies, etc. software engineering can learn something from some of those other engineering disciplines... |
![]() |
| You write the test to prevent the bug from being accidentally reintroduced in the future. I have seen showstopper bugs reintroduced into production multiple times after they were fixed. |
![]() |
| > There are no tests there, but for the non-tech types who created these monsters, spending time on writing a test suite has a very real cost - there's less time to do the actual job they were hired for!
Not spending time on writing tests has a very real cost - a lot of time is spent on figuring out why your forecast was way off, or your year end figures don't add up. Not to mention how big parts of the world are thrown into austerity, causing hundred of thousand dead, due to errors in your published research [0]. [0] https://en.wikipedia.org/wiki/Growth_in_a_Time_of_Debt#Metho... |
![]() |
| >> It's a trade-off.
>> spending time on writing a test suite has a very real cost > Not spending time on writing tests has a very real cost Yes. That's what "trade-off" means. |
![]() |
| I'm trying to build something small with a quickly frozen feature set. I've chosen to build on a foundation that changes infrequently. There is more background at https://akkartik.name/freewheeling.
You're absolutely right that this approach doesn't apply to most programs people build today, with large teams and constantly mutating requirements. I do still have source control. As I say in OP, I just stopped worrying about causing merge conflicts with other forks. (And I have over 2 dozen of them now; again, see the link above for details.) So I have version control for basic use cases like backups or "what did I just change?" or getting my software on new machines. I've just stopped thinking of version control, narrowly for this program, as a way to help _understand_ and track what changed. (More details on that: https://akkartik.name/post/wart-layers) One symptom of that, just as an example of what I mean: I care less about commit message hygiene. So version control still exists, but it's lower priority in my mind as a part of "good programming practice" for the narrow context of programs like this with frozen feature sets, intended to turn into durable artifacts that last decades. |
![]() |
| This context helps me understand more what you're getting at quite a bit. I dunno if I could manage the same approach but I at least appreciate how you're thinking about it. Thanks! |
![]() |
| The author is probably experiencing mental fatigue or even burnout about programming.
If version control bothers you that much I'd say it's a good sign that you need to take a break. |
![]() |
| This seems very far from my subjective experience. The little platform-independent programs I write for myself and publish are a source of spiritual rejuvenation that support my day job in a more conventional tech org with a large codebase, large team and constantly changing requirements.
I'm not "bothered" by version control. I've not even stopping using it. As I say in the post, I just don't think about it much, worrying about merge conflicts and so on, when I'm programming. I've stopped leaning on version history as a tool for codebase comprehension. (More details: https://akkartik.name/post/wart-layers) This comment may also help clarify what I mean: https://news.ycombinator.com/item?id=41158040 |
![]() |
| This is all in a professional environment requiring code review for actual submission. I need to follow this process to actually deliver |
![]() |
| Your quotes seem to reinforce parent's assertion he's not talking about version control in the form of tooling but some kind of versioning in the code itself: "...while tests and versions..." |
![]() |
| Yep, commit your code when it "works". Then I can safely go off on a hair brained experiment, knowing I can easily throw away the changes to get back to what worked. |
![]() |
| Author successfully drove engagement with psychological baits like bashing commonly accepted tools and practices and being intentionally obscure so a lot of people would comment about it. |
![]() |
| Making strong assertions without any evidence or data to back it up is not "wisdom". I agree with other people: the author is simply burnt out by software (which is fine) and is jut YOLOing his code. |
![]() |
| No one has claimed that.
It was simply suggested that in some situations, maybe they're not as important as we tend to assume. And it takes experience to see those patterns. |
![]() |
| > Most software out there is incurably infected by incentives to serve lots of people in the short term.
Great quote! You can even replace “software” with “businesses” and the quote still works. |
![]() |
| It's also a shame that Kartik explicitly states his goals and his problem domain, yet folks react as if he'd been making comments about their goals and their problem domain. |
![]() |
| If they are the only user or developer, sure. Otherwise they are the least qualified to say it's better -- like how I'd be the least qualified to declare myself winner of a handsome contest. |
![]() |
| Yes and no.
Shell scripting is incredibly powerful and omnipresent. So you want to know the basics about pipes, loops and the like. But the language itself is broken by design (error handling is a mess; whitespaces create headaches daily; sub-shells can be a pain; ...). So, creating reliable scripts can be a challenge, and you do not want to become an expert on how to write large programs with the shell. Other languages, e.g. Python, are much better at this. My favorite site in this context is https://shellhaters.org. It has a list of links to the POSIX standard so that you can easily look up functionality that is part of it (and should be present on all POSIX-compliant operating systems). If you know everything on https://learnxinyminutes.com/docs/bash/ you most likely know more than you need. |
![]() |
| I won't comment on which shell to learn, but you'll end up spending a lot of time in it, so learning your chosen shell well will pay off dividends for the rest of your life. |
![]() |
| You don’t know if your shit works just from “types”, and formal methods are not applicable to anything real. You’re arguing for the sake of argument, you know I’m right. |
![]() |
| Yes you can. C# has had anonymous types since language version 3.0, released nearly 20 years ago; everyone who has used .Select() at the end of a LINQ query has used this. |
![]() |
| It doesn't "explain" it at all (and indeed many of reject the idea that MS apps - in general - are worse. They've had a bad reputation for decades, and that isn't based on nothing). |
Never have I tested anything and NOT found a bug, and most things I tested I thought were already OK to ship.
Thus, when you delete your tests, the only person you are fooling is probably yourself :(
From reading your page I get the impression you are more burnt out from variation/configuration management which is completely relatable… I am too. This is a hard problem. But user volume is required to make $$. If the problem was easy then the market would be saturated with one size fits all solutions for everything.