[HN Gopher] What I have changed my mind about in software develo...
___________________________________________________________________
What I have changed my mind about in software development
Author : henrik_w
Score : 52 points
Date : 2023-09-10 16:12 UTC (6 hours ago)
(HTM) web link (henrikwarne.com)
(TXT) w3m dump (henrikwarne.com)
| jcpst wrote:
| It would be interesting to know how long the author has been
| developing software.
|
| For me, this is the kind of stuff I questioned in my first few
| years. After I productionalized a few real world systems for a
| business, the whole "dev street cred" thing lost it's appeal. It
| wasn't about some imaginary "dev purity" thing anymore, it was
| about being efficient and making sure I was contributing to the
| bottom line.
| SoftTalker wrote:
| Maybe. I have been developing for over 30 years. I still use
| emacs, use logs and printf for debugging, and have never even
| looked at ChatGPT. I'm willing to admit I may be set in my ways
| but I get my work done.
| jiggawatts wrote:
| Nearly 40 years here -- I exclusively use IDEs and debuggers
| and have done so since the early 1990s.
|
| Computers aren't digital pencil and paper. They're levers for
| the mind. If the 3 GHz processor just sits there idling,
| waiting patiently to copy some bytes from one buffer to
| another, it's being wasted. It could be checking the syntax,
| looking up documentation, or chasing memory references in the
| debugger _so I don't have to._
| bsder wrote:
| Programmers had a very nice thing called "web search". Then
| advertising and spam ruined it.
|
| From my point of view, ChatGPT is simply an anti-spam
| algorithm which is finally restoring "web search" back to
| being useful.
|
| The problem is that _there is no money in that_. So,
| everybody is trying to apply all the ML /LLM/ChatGPT stuff to
| absolutely _anything_ in the hopes of making some money.
| jcpst wrote:
| Good point. They're all just tools and patterns. The actual
| tools used _could_ save some time, but experience plus the
| capacity to reason about software is a bigger deal.
|
| The article just made me think of some devs that I've worked
| with that were obsessed with particular tooling (insert
| comment about a hammer and everything being a nail).
|
| I do keep an eye on emacs. It turned into mainly my org-mode
| editor, but the v29 article that hit the HN front page
| recently has me curious about trying more dev work with it.
| mellosouls wrote:
| _It would be interesting to know how long the author has been
| developing software_
|
| It's on the About page:
|
| "I have been programming professionally for more than 30 years"
| 0x445442 wrote:
| Unit testing private methods via public interfaces is accidental
| testing and leads to overly complex and brittle test code. The
| author's first instincts were correct here.
| isityouyesitsme wrote:
| Exactly.
|
| I worked in a place that disallowed friend functions and
| classes generally, but explicitly for unit testing. I never
| wrote another private function. Instead, there was an explosion
| at the tiny-free-function-that-could-have-been-a-private-
| function factory, and the parts ended up everywhere.
| SoftTalker wrote:
| How is it accidental? The code can only do what its public
| interfaces expose. This indirectly (not accidentally) exercises
| the private methods.
|
| If all the public interface test cases pass, isn't that enough?
| isityouyesitsme wrote:
| Whether or not it is enough depends on the context. Some
| cases require 100% condition and decision coverage. In these
| cases, it gets to be very difficult to achieve that unless
| you are directly testing the functions you write, not through
| a caller.
|
| But even deeper, it is "accidental" because you are not
| testing contracts on the public APIs, you're testing the
| private functions through a layer higher. When the
| implementation changes, you have coupled your tests so
| tightly to the implementation that they are useless for
| regression testing. If not, then you actually aren't testing
| the private function at all, you're just hitting some parts
| by coincidence.
| mvdtnz wrote:
| I don't necessarily agree, I think it's situational but I
| think that the dev community as a group has swung too far to
| the "only test public interfaces" side lately. It ignores
| some important realities in favour of ideological purity.
|
| Sometimes there are well-defined processes for performing a
| task, and that task is performed in only one place in the
| system. Therefore the details of the process can be kept
| class private inside of the only consumer. That doesn't mean
| that the processes should never be tested. If the task is
| cumbersome to set up or runs slowly then there is good reason
| to test the internal parts of the process which can be tested
| with dozens, hundreds or even thousands of permutations of
| input data cheaply and efficiently. Always relying on the
| large-scale tests to hit every combination of inputs for a
| well understood subroutine can be inefficient.
|
| You could make the argument that this well-understood process
| could be broken out into its own class/package/module and
| tested with its own public interface, but if there really is
| only one consumer then that's kind of a strange trade-off to
| make in many cases.
| 0x445442 wrote:
| In the vast majority of cases, The Enterprise, private
| methods are little to no use anyway. Whenever I'm faced
| with updating a code base that has Draconian code coverage
| metrics in place I'm more apt to make a private method
| public than futz around trying to figure out mock magic to
| test the change
| Joky wrote:
| > You could make the argument that this well-understood
| process could be broken out into its own
| class/package/module and tested with its own public
| interface, but if there really is only one consumer then
| that's kind of a strange trade-off to make in many cases.
|
| That's how I develop in general: a "component" does not
| exist because it has multiple-clients, but because it is a
| conceptual piece of logic that makes sense to document and
| test in isolation. It allows to define what is the public
| API of this component and what isn't. This is how software
| scales and stays maintainable over time IMO.
| mvdtnz wrote:
| I don't disagree, I'm just saying it's situational. The
| trade-off doesn't always make sense. But I typically
| develop in much the same way as you do.
| 0x445442 wrote:
| There are a number of issues. First, the fundamental unit
| under test is the method/function, not the entire call stack.
| Second, complexity starts to grow when there are code
| coverage gates in place.
|
| When I see tests that are orders of magnitude larger than the
| units they're testing and contain mocked references that are
| used 7 stack frames deep I know the author had a fundamental
| misunderstanding of how to write helpful and maintainable
| tests.
| jcpst wrote:
| This perspective is really interesting to me. I'd be interested
| in knowing what people find problematic with it.
|
| I used to unit test all the components individually. But these
| days I test with most of the componentry wired up, only mocking
| the i/o layers. I end up writing fewer tests, they have been
| less brittle, and refactoring is easier.
| 0x445442 wrote:
| If you want to expose issues in a code base's architecture,
| don't allow mocking frameworks and see how complex and
| lengthy unit tests become.
| pc86 wrote:
| Yes if you eliminate an entire class of testing
| infrastructure, tests become harder to write because you
| end up poorly implementing that infrastructure in every
| class.
|
| How does this show you "issues in the code base's
| architecture?"
| waynesonfire wrote:
| if your private methods are complicated enough that you're not
| able to achieve sufficient coverage through public interfaces
| it's time to refactor. make the private code a library that you
| can test in isolation.
| IshKebab wrote:
| I agree. It's also _not_ always possible to sufficiently
| stimulate a private function using public methods.
|
| He was right to change his mind about the other things.
|
| I was also skeptical about remote working, and while I think it
| is worse in most ways than office working, it's not _a lot_
| worse, and the lack of commute is sooo big a benefit that
| overall it 's totally viable.
| 29athrowaway wrote:
| With IntelliJ, spellchecker + linter + static analysis +
| duplicate code detection + etc = basic quality as opt out feature
|
| VS Code and other setups make those opt in.
|
| Meaning, when you see a bunch of typos and really poorly written
| code you know it is from one of the DIY setup people.
|
| So then you have to move all those checks to the next stages like
| SCM hooks and CI.
| mplewis wrote:
| I wish that my programming languages had a "public for testing
| only" scope. Despite the rigorous arguments of the Properly
| Factor Your Public API crew, I still find myself in real-world
| situations with functions that should not reasonably be used
| outside of the module, but that I still find valuable to cover
| with unit tests.
| wavemode wrote:
| C++ has "friend" classes, a quirky feature I've never seen in
| another language. But which solves this very problem.
| MikeTheRocker wrote:
| Kotlin has the internal access modifier which can be useful for
| this
| mvdtnz wrote:
| This exists (in kind of a hacky way) in C# with the
| ExternalsVisibleTo attribute. It exposes methods and classes
| only to specified assemblies (like your unit test assemblies).
|
| https://learn.microsoft.com/en-us/dotnet/api/system.runtime....
| no_butterscotch wrote:
| This exists in many Java based languages, an annotation above
| a method: @VisibleForTesting or some such.
| gregoryl wrote:
| You can actually stick this in your csproj. I'm on a phone,
| so bear with me, but roughly
| <InternalsVisibleTo Include="assemblyname" />
|
| Which means you can do stuff with msbuild props, like auto
| including a `$(assemblyname).Tests` into your projects.
| zem wrote:
| yeah, that one stood out to me too. i would be tempted to make
| the stronger statement that it is always strictly better to
| have your private code unit tested, and it is only the
| limitations of languages and test frameworks that make people
| reach for ways to test them through the public API.
| pvorb wrote:
| But on the other hand: if it's worthwhile testing your
| private methods, shouldn't they maybe be refactored to a
| public/package-private scope, so they can be reused?
|
| If you disagree, maybe an illustrative example would help. I
| couldn't think of one where I want to test a private method
| in detail that is not worth exposing.
| deergomoo wrote:
| I've never understood why anyone would choose to debug by
| printing and logging if they have a good debugger available to
| them.
|
| My day job is mostly PHP (yeah yeah, I know) and the general
| attitude towards Xdebug in the community seems to lie somewhere
| between apathy and active avoidance.
|
| To me, a debugger is such an invaluable tool not only for
| identification of bugs but also for familiarising oneself with
| new code. The value of being able to not only trace execution
| from start to finish but also to _modify_ state in a running
| program is immense, and gives me a small taste of what Lisp folks
| rave about.
|
| Littering print statements everywhere feels like banging rocks
| together when there's a perfectly good lighter in your pocket.
| pc86 wrote:
| Overall a pretty good article, however I do feel like the author
| misses the mark on a couple points.
|
| > Unit testing private methods.
|
| As someone else pointed out this leads to accidental testing. I'm
| not a test zealot, I think 100% coverage is a fool's errand, and
| I think TDD is an abomination, but well-structured, well-thought-
| out tests can be a game changer when used appropriately. Testing
| things by accident has inevitably lead me to finishing some piece
| of work then spending half a day or more tracking down why some
| test failed inexplicably.
|
| > Using an IDE.
|
| I think a better point here is to get really good with whatever
| tool you use. If you know every incantation in vim you're going
| to be amazingly productive. If you know every keyboard shortcut
| in IntelliJ you'll be as effective, but probably not much more.
| The person who knows vim or emacs in and out will beat the person
| clicking around in an IDE every day of the week.
|
| That being said some of it is spot on in my admittedly limited
| experience (only about 13 years or so, in a handful of
| industries, never FAANG-level scale). The point about commenting
| problem areas in the _domain_ has really changed my approach to
| comments. I don 't write any comments about what the code is
| doing unless it's a "here be dragons, don't change $X unless
| you're free the rest of the week" kind of warnings. But I comment
| extensively why the business or regulation requires A or B to
| happen instead of the more straightforward C.
|
| The ChatGPT bit as well matches my experience. For well-defined
| things where it's hard for ChatGPT to make the answer up, and
| easy for you to verify if it does (or at least low-damage), it's
| worth the $20/mo IMO. I tried using it to learn CDK and while I'm
| not sure it saved me any time, it did save me from having to
| trawl through AWS documentation.
___________________________________________________________________
(page generated 2023-09-10 23:00 UTC)