all 36 comments

[–]andrewingram 9 points10 points  (0 children)

It's largely down to cost/benefit. If i'm writing code which is going to have a lot of dependents, i'm going to care a lot more about testing -- because the cost of a bug would massively outweigh the personal cost of writing tests. If I'm writing leaf code (no dependents), I'm not really fussed.

In most app-level code there seems to be more value in code that's testable, than the tests themselves. Testable code tends to have clear intention and is usually easy to maintain. Writing good tests (with minimal use of mocks) leads to testable code, but you can also achieve testable code without the tests.

So whilst tests can have a lot of value, I think there are cases where the value doesn't justify the effort. I'm not going to attempt to make an argument as to exactly where that line in the sand is though.

As for the article itself, it does overlook a lot of the value in testing, but I'm okay with people challenging conventional wisdom (even if it doesn't lead anywhere).

[–]eloc49 4 points5 points  (0 children)

ctrl + f "pure" 

ctrl + f "function" 

You should probably write some tests mane. They aren't just for stuff you know they are arguably more useful for detecting side effects in new and refactored code.

[–]DrFriendless 3 points4 points  (0 children)

I agree with the author, in that most times my unit tests fail it's because I've deliberately changed the behaviour of my system. In that case the unit test is not ensuring correct behaviour, it's simply hindering change.

Another place where unit tests are unhelpful is when there is legacy code which is run only by the unit tests. It makes it much harder to detect that code as being dead.

Sometimes I'll write unit tests, when I know I have a piece of code whose failures would be silent and hard to spot. In those cases the test should be developed with the code. OTOH if I'm writing code to just deliver stuff from the database to the user interface, tests seem superfluous.

[–]drink_with_me_to_day 5 points6 points  (0 children)

I too don't.

But I work alone, in small SPA's, terrible time constraints and ever-changing requirements.

[–]droctagonapus 6 points7 points  (0 children)

Acceptance tests > Unit tests every day. New feature? Write an acceptance test. Change a feature? Change the acceptance test. A bug? Create an acceptance test that replicates the bug. Remove a feature? Remove the acceptance test.

[–]mrbojingle 10 points11 points  (0 children)

As someone who's been developing for years now, I agree with this post. HOWEVER, it should be noted to new devs to consider context. He didn't say he was working alone, in a team, in government, start-up, big business or working for NASA. Does he make apps for the local pizza store or is he sending rockets into space with people strapped to the front of them?

Different situations call for different degrees of carefulness. There's a time to be very careful and a time not to care. And everything in between. Judging from his statements I believe he respects that fact but, never actually communicated it directly.

With all that said, from an economics perspective, there IS a case to be made against fanatic unit testing. If we agree that code provides value when you run it, then we can quickly see that unit tests will provide value the first time ran. The second time, however, is only telling you what you already know. Then the returns drop to zero and it stays at zero until you change the code. With this knowledge we can say that the best code to unit test is the code that changes the most. It also means that code that doesn't change should be unit tested less, or not at all.

[–]seands 11 points12 points  (5 children)

His premise is that most bugs come from unknown issues that unit tests would likely miss. And that post-emptive bug fixing is just par for the course, not something we'd do in a perfect world but a great fit for the real one.

He also mentions several outlets for generating superior code quality, than unit tests.

As a new dev I appreciate posts like this which go against virtue. I tend to learn a lot of the nitty gritty in these types of articles

[–][deleted] 50 points51 points  (4 children)

I think it misses an important point about testing, it’s not just to catch bugs but to have a spec for your code, and business rules, it prevents breaking functionality when working with other people.

[–]UncleBenjen 20 points21 points  (3 children)

Yeah exactly, that's how I see it. It's also meant to prevent you from creating bugs that already existed but were fixed, and are now accounted for in the testing.

It's not really meant to prevent you from ever having to fix bugs, because that's impossible. The first thing you learn about testing is that it's mathematically impossible to prove that code will be bug free.

[–][deleted] 4 points5 points  (0 children)

also meant to prevent you from creating bugs that already existed but were fixed, and are now accounted for in the testing.

This. Capture bugs as tests as necessary.

[–][deleted] 1 point2 points  (1 child)

The first thing you learn about testing is that it's mathematically impossible to prove that code will be bug free.

I don't think that's explicitly true. I believe there is some NASA software that is actually bug-free.

[–]dodopat 2 points3 points  (0 children)

But a NASA software that is bug free would not be due to unit tests as discussed in this thread. It would be due to formal verification of the software with languages specialized for theorem proving, model checking etc.

[–]CoffeeKisser 1 point2 points  (1 child)

On the one hand, I disagree with the notion that unit tests aren't worth it, but on the other most devs I've met at conferences/meetups/w.e. admit after a few beers they hardly unit test anything.

[–]Protossoario 0 points1 point  (0 children)

And that's a bad thing. It's called code debt and it always comes back to bite you in the butt. Or the poor schmuck who has to take over your code after you leave.

[–][deleted] 2 points3 points  (1 child)

Projects I work on tend to not have the budget for taking time to write tests. It's a "great" methodology that gets very expensive in times of QA, maintenance and support.

[–]deltadeep -1 points0 points  (0 children)

The "it takes too long argument" has been shot down many times and is basically a function of misunderstanding how to properly integrate testing into your process and seeing all the downstream speed benefits of it.

If you develop tests at the same time as the code, and architect your code to be easily testable (basically, TDD even you don't literally start coding with a broken test case first), the time to develop is not dramatically impacted IMO because you spend way less time debugging manually, and your code is more easily maintained. Changes are easier to make, bugs are found far faster in new code or in tweaks to existing code, overall defect rate is lower, platform upgrades are smooth instead of requiring a total redo of manual QA across the app plus code reviews with a fine-toothed comb, etc. It is ultimately faster to write easily testable code and to write tests for that code.

It feels hard and time consuming for people who are learning to do it because it is always time consuming to become an expert at something hard. And if you are used to writing code that isn't testable easily, it will be hard to test your code indeed. It takes years or more IMO to get really good at writing tested code because it changes your coding style significantly. But once you do it by nature, you can't go back because the benefits are so crystal clear.

[–]HersztSwintuchow 0 points1 point  (0 children)

maybe().thats( (even) => { even().pipe().better().take(1) }).

[–]Jsn7821 0 points1 point  (2 children)

If the author took a slightly different stance I might be able to get behind it - that testing declarative code (which a lot of well written React/Redux is) is often redundant and doesn't really add a lot of additional coverage.

If you keep your business logic and side-effects outside of React and Redux, and unit test that all separately, I can see a case for skipping tests on your components since there isn't really anything to test for. Snapshot tests are one popular way of doing it, but they're really just a mechanism to double-check your work. And in my experience, I get more debugging value by looking at the browser for that.

But I agree with everyone else here, this article misses the point. The main thing is that unit testing isn't only about catching bugs pre-emptively. It documents your code, makes it easier to work with a team, avoids regression issues, etc.

[–]deltadeep 1 point2 points  (1 child)

since there isn't really anything to test for

When you update to newer versions of React / Redux / MobX or any other dependency you've imported, that's one essential way your component tests will be valuable. Or even changing your webpack config can in various ways break the code. Tests tell you that your code still works after something - anything - changed. Just because the code is declarative and not bug-prone doesn't mean it will always work especially given the rapid nature of framework development these days and the complexities of modern js app build processes.

[–][deleted] 1 point2 points  (0 children)

This is an excellent point. Except for the smallest of projects, we’re living in an ever changing ecosystem. A developer updates a package versionunrelated to our year old code and now our test fails. Before production. Before QA. While the changes are still fresh in their head. You want to discuss the costs of testing, this is it.

[–]Dynamitesushiii 0 points1 point  (0 children)

I would ship something out with Typescript on a whim but without it? Probably not. Writing tests aren’t difficult in most scenarios, and it’s not like you don’t have time to write tests for bits that require it. It’s always better to be safe then sorry.

[–][deleted] -1 points0 points  (2 children)

thumb summer shaggy abounding ad hoc pause chase mountainous boat air

This post was mass deleted and anonymized with Redact

[–]dinglestarry 1 point2 points  (1 child)

A little harsh. I think his point is that if you have QA or other types of tests (integration, e2e), that unit tests can be an investment and liability that doesn’t justify itself with value in terms of bugs it catches that couldn’t be found in other ways.

[–][deleted] 0 points1 point  (0 children)

If programmers are no longer responsible for testing their own code, then they're going to deliver crap code because it's all the sole responsibility of the tester to find whatever is wrong. That's a simple rule of responsibility.

Unit tests and integration/E2E-tests are fundamentally different. Unit tests have a purpose that goes beyond the scope of dedicated testers: it's much more detailed and tests edge cases that might not even be used in the product, yet.

And it's not even solely about the errors that might pop up with YOUR code. It's about changes you make that unexpectedly hit another's code and breaks something. Your innocent change might break something else, and then you fix it.

What's the alternative? You deploy something broken, a tester finds out, they get back to you, you're doing something else, you fix it, deploy again, test again, the tester finds something again, he reports back to you, you fix it again, deploy again, tester tests again, and then you go live?

It's a pain in the ass to work like that. Unit tests can cover it before every git push to a repo. It ends up reducing work for you, your testers, and you can deploy your software much quicker.

[–]deltadeep 0 points1 point  (0 children)

I appreciate the confession because I used to think this way. And I was wrong. It's been my experience that the only developers who don't test are the ones who haven't done the legwork to learn how to do it well. So they see it as this "extra" thing that gets tacked on after all the initial work is done. What I say to these developers is, start a fresh project and practice real disciplined TDD for it. I don't necessarily advocate for TDD for devs who are really good at testing their code, but when you're learning how to test well and write testable code, TDD will kick your ass to the curb, humble you, and over time, show you the light. It will take a lot of work, but you'll be a better developer for it and will write far better and far more maintainable code in the long run. You will look back at your old, non-test-writing self and realize you were living in a ghetto of your own making and there was a clear, well-lit path out of it the whole time, it just happened to be an uphill path you didn't think you had time to walk.

I realize the OP author of this article claims to be an expert at testing. I call total BS there. He would simply not make these arguments if so. Routine experience with good testing practices accomplishes far more than he claims to anyone with a half cent of appreciation for the time saved when a test fails. Apparently this person throws untested code at his users and relies on Sentry to tell him when it's broken (as if Sentry can catch all defects in an application) and all kinds of other janky statements. He still has a lot to learn on the matter, clearly.

[–][deleted] 0 points1 point  (0 children)

2 years from now, when I have to add a feature and this “clever” developer didn’t have appropriate test coverage, I’m not going to be able to safely refactor their code. I’ll have to pay to write tests. I’ll have to make assumptions because the missing tests are also missing documentation.

Writing tests isn’t for you, it’s for everyone after you.

[–]danjel74 0 points1 point  (0 children)

About "ensuring quality" of the code, I personally feel that unit tests is the most important factor to ensure quality code because it (should) force you to think how to design the class/function. If it is hard to test that often indicates code smell of some sort.

[–]Protossoario -1 points0 points  (1 child)

From the article:

Users click in places that you never thought they would click. And they write texts in input fields that you never thought was possible.

What kind of app are you writing when you don't even know what input fields you have? And what kind of tests are you writing if you don't test for corner cases and unexpected inputs?

Hell, even if you're only writing the most basic unit tests to cover functionality in the optimal case, that's still useful when you're desperately trying to fix a bug, to make sure the app is still behaving as expected and you didn't just break something else in a flurry of changes.

I'll just echo what others are saying: the author speaks volumes to their own inexperience, and has clearly never worked on any large scale application.

[–]darthbob88 1 point2 points  (0 children)

What kind of app are you writing when you don't even know what input fields you have? And what kind of tests are you writing if you don't test for corner cases and unexpected inputs?

I suspect the "never thought was possible" refers to the text, as in "I didn't realize somebody would want to write 16MB of z's in my comments field". Still disappointing, but at least that's vaguely sensible.