4 ms·
First time hearing about the 90/50 rule and it's something I've seen play out so many times. It's easy to get caught up in just getting the code work on a limit
by mtrovo 2y ago
First time hearing about the 90/50 rule and it's something I've seen play out so many times. It's easy to get caught up in just getting the code work on a limited case, but true quality comes from spending extra time on testing and handling edge cases. It's often those overlooked details that can take up more time than we expect. This is particularly crucial for junior developers to grasp as you need to understand that your task is not done when you send your first push to git.
I also agree wholeheartedly with automating best practices. Relying on manual reviews for everything is just not scalable. Setting up automated tests to enforce format, lints and testable code have the side-effect of creating a code base with clear expectations and minimal side effects.
- pydry 2y agoTrue quality comes from avoiding edge case traps. Some approaches/feature types create edge case explosions. For example, I'm often hell bent on the need for avoiding bidirectional syncing or writing mini parsers. If there is another, simpler way its always better.
- xmprt 2y agoI think the solution depends on the type of problem you have. If your problem is reliability then increased testing and handling edge cases (or avoiding code that even hits those edge cases) will help. But if the problem is uncertain requirements, then more testing will just add to the amount of code you're going to throw away and refactoring will only become harder. The problem is that often times in software engineering both problems happen in tandem - you're improving reliability while also trying to change how your system works as new feature requests come in. The solutions are almost diametrically opposed.
- IanCal 2y agoMore testing can help show the uncertain requirements in more concrete ways. What should happen in these cases? Now we have this list in one place does it seem unusual or inconsistent? Bonus points if you can have more general tests (like property based ones) that let you test broader statements. I always fall back to this example but I built a testing lib for a stack we had a UI framework in. It helped because we could write a test like: "For any UI, if the user moves right and the focus changes then when the user moves left the focus goes back to the original item" And then we found a bug in the spec with: For any series of API calls that build a UI, and any series of user interactions, one of the following is always true * There are no items in the UI * There is exactly one item with focus Being able to specify things at this level resulted in us being able to define the major behaviours succinctly and that made it easier to have them be consistent.
- Nemi 2y agoI see the parent commenters point as being more of the “can’t see the forest for the trees” type of uncertain requirements. To go into more detail, it is the type of uncertainty about whether you are actually solving the right problem or if it really is a problem. While what you suggest does help ferret this out, what you are suggesting can also prolong the process of getting the code in front of a real end user to see if they use or adopt it the way you are expecting. It allows you to quickly throw away ALL the code and get to solving the right problem. Another way to put it, the more the problem space is unknown, the faster you should get the code in front of someone and delay the edge-case discoveries.
- bluefirebrand 2y ago> It's easy to get caught up in just getting the code work on a limited case, but true quality comes from spending extra time on testing and handling edge cases The frustrating thing is how this feels so incompatible with the way most software companies work in two week sprints and judge productivity by tickets closed / story points completed You can't take your time to do it well
- perdomon 2y agoThe version of this quote I've heard the most is "The last 10% of a project takes 90% of the time." It's a bit different, but the idea is the same: the real work of implementing a feature comes in handling unexpected behavior and edge cases. It can look finished from the outside, but imagining and preparing for every conceivable outcome takes much of the time.