Reflections on a Decade of Coding
scattered-thoughts.net
scattered-thoughts.net
I believe it's worth remembering that years of experience is at best a weak predictor of competency. Careers are non linear and someone might growth the same in 10 or 20 years than others in 2 or 3.
For the best deconstruction of career growth I've seen around (and one I personally identify a lot with) I recommend this blog post [1] from Carlos Arguelles.
[1] https://medium.com/geekculture/career-growth-speed-deconstru...
However 10 years is also enough time to explore the depth of one cave along with the openings of 5 other caves. That T-shaped skill set really gets wider in the next 10 years, at least it did for me.
The width is also what tells you what you haven't looked at. For me it's Haskell and LISP. Not sure if I've got the monads to go down that route, it might overturn my existing long learned wisdom, something that could be painful with 20 years of experience.
Mine was that at this mark I already started forgetting stuff which I knew by heart as a junior dev.
Most of the time, bugs are in the glue.
Critically, I don't mock our db, instead I focus on making setup and teardown fast.
It seems to get me the most bang for my buck.
Then I have a few end-to-end tests for more critical flows.
For example, I always try to write a "log in" test, and for systems that take payment, a "payment acceptance" test. Even if other parts of the system have bugs, I want to be able to have existing clients log in, and new clients sign up, no matter what.
* though I think integration testing is really "anything that tests more than one system" without necessarily being fully end to end
E2E tests are also useful for a smaller purpose - mostly as happy-path sanity checks rather than in guiding development. IMHO.
One technique he references that I find very effective is building "firewalls" between different parts of the codebase, and then unit testing those firewalls thoroughly. This means that you can isolate a bug to one part of the system or another, and drastically reduces the surface area to look at when trying to find why there is a bug or why a test is failing.
Edit: In fact, I've seen places in your D code that use similar techniques already - maybe just giving them a name makes a big difference?
The data structures that go in and out of the modules then get replaced by "mock" data structures.
I totally agree that, even then, wrangling ungroomed interdependencies are definitely the biggest headache. But I have yet to adopt this approach and not think to myself, "why didn't I start this sooner?"
https://github.com/DigitalMars/dmpp
Once it was all put together, nearly all the bugs were misunderstandings on my part, rather than detail bugs.
Why is that? In more functional oriented languages, they are great because they allow you to verify behavior of functions. Then in the broader application, you're just composing pieces that have already been validated, and the compositions can also be tested. If you're able to incorporate property-based testing, then that's even better.
* Writing tests has a cost, so I want to right as few as possible while ensuring functionality.
* rewriting tests has a cost. When I start writing, I know what functionality I want, but I may iterate significantly on implementation. This makes unit tests both an impediment, and providing me no safety to perform the refactor/reimplementation.
* the module, or it's equivalent structure in your language, is the optimal tradeoff between standalone functionality. Ideally, a module encompasses a small enough behaviour to fit in one's head. IMHO, an ideal single function should be small enough that it's behavior is readably obvious.
* module inputs and dependencies are easier to instrument in tests. I/O and hardware API dependencies can be injected/overridden. On the other hand, private variables and internal instantiations can be complex and hard to mock appropriately when unit testing, unless you are able to structure absolutely everything as a pure function - IMHO a platonic ideal, particularly in the workplace.
* Functional tests are easier for other coders (and even non-coders, in regards to feature files) to understand. "I wrote 100 unit tests" provides less information regarding actual functionality and productivity than "this feature's scenarios are all passing now."
The originators of unit tests and extreme programming explicitly stated that unit tests are not to be checked into source control, and deleted instead. They felt that unit tests would overly constrain subsequent programmers, and that higher level suites were more useful at providing refactoring safety. The only time to submit a smaller sized test is as part of a bug fix, where one would write a failing test, fix the code and check it in.
Fwiw, while I agree with them on this, I'm don't want to come across as appealing to authority. A lot of Agile/eXtreme/Scrum ideas reflect a simpler and very different time in coding, when code was, by necessity simpler and easier to reason about, and the culture of computers gave engineers much more power to push back on management demands and prioritize code quality. And some of the ideas are just hokey - like eXtreme programmings dislike for branches - encouraging all developers on a team to land their code on 'main' at the end of every day.
Besides, the very first Agile project -that birthed the movement - went over time and over budget :)
I agree that tests have costs, but they are part of the implementation. Just throwing them out means that the implementation is only partially there. It's just a fact of nature for code. One does have to be careful to avoid doing tests just for warm fuzzies though.
So imo it is all about definition of what is a unit: It can be your one complicated algorithm heavy function, it can be a whole module at its module interface, it can even be x modules together achieving together a functionality/behaviour.
I can only roll eyes at people who try to tell other people what a unit test is and what not, and what is "wrong" unit testing.. I would hope we'd more distinguish bad vs good testing instead discussing about what is unit and what is integration testing... and most of the time bad tests stem from the crowd wanting to tell what is a unit test and what is not, tbh.
Ironically, this is a lot easier if you unit test the non-deterministic parts. Once you can be sure it's easily testable[1], it also has the side effects of being easier to debug, read, more reliable (in terms of branch behaviors), and more readable. Writing longer functions (his leaning) makes these issues worse, so it's not surprising it's a pain point.
[1] Granted, this depends on language. Each language has different language features that make code more or less testable, from a unit testing perspective.
Reads more like a rant, diary with random analogies.
Too much noise in explaining their experiences and forethoughts which aren’t really helpful to the reader.
Perspective can be explained in one sentence and then move on to core pieces.
Apologies but get to the point.
Had to use ChatGPT to summarize the main points for one:
On Bad Advice
The programmer who wrote the post is cautioning other programmers about the dangers of taking advice from online sources without considering the context and details of their specific situation. They explain that much of the advice they have received over the years has been actively harmful to their programming abilities. They suggest that programming practices are mostly tacit knowledge, which is difficult to share and can vary depending on specific situations. The post argues that it is essential to consider the context and details of one's specific situation when seeking programming advice and not to rely too heavily on generalized advice.
Or click on "emotional management" and read "In keeping with the theme of the rest of this series, I don't claim to be very good at this or to have any deep or generalizable insight"?
Or where he says: "I've never had to maintain a codebase for more than 2 years. I've never been responsible for running a long-lived service. Any thing that I report having worked well for me has to be considered in that limited context."?