Hacker News new | ask | show | jobs
by tjenkinsqs 2645 days ago
You make some valid points on DI, linting, etc. but your first point on Typescript itself not providing value is pure FUD. Typescript catches a TON of bugs and the ones that are the most frequent https://rollbar.com/blog/top-10-javascript-errors/.

That we as an industry ship code (Javascript) to production that still has bugs that are so easy to catch at compile time does not reflect well on us, and your comment really does not help in this regard. What is your recommendation to ensure we catch more bugs at compile time rather than letting users find out that their application doesn't work?

2 comments

I think the most effective way to find a bug in a program is to demo it in-front of a crowd. Or let grandpa use the program. Jokes aside, I think the most effective way to catch bugs is to have many people read (and understand) the code, and also have many users hit the code paths, most bugs will reveal themselves given enough time. Well used/tested code is often referred to as "hardened".

You wanted to find the bugs before shipping it to users, and that is also what I used to pursue, but when you let a ton of users hit your code, they will find the issues way faster then you could. It's however important to log, and debug all errors, and have a channel for users to submit issues. Sure it will be annoying for the user when he/she stumbles on a bug, but you will regain the goodwill when you fix his/her issue. In most software, even today, users are used to wait months, and even years, or infinitely, to have a bug/issue fixed. So it's a lot of "WOW! Thanks" And very little "I will sue your ass". Bugs, if you do actually fix them, will have a net positive effect.

Quality test coverage. I'm a big fan of having integration tests which cover all the main scenarios which are relevant to your users.

For example, one of my open source projects has about 120 integration test cases in total; these are enough to cover about 10K lines of code (not counting third-party dependencies); if I break any documented feature of the project, it's essentially guaranteed that many test cases will fail - They will catch the smallest issue or inconsistency; even things which are not being explicitly tested.

Integrations tests are great at detecting symptoms. They don't always point exactly at what the problem is, but they are great at letting your know that there is a problem and then you can debug it.

Integration tests are the best way to identify and fix issues in very complex systems. For example, when it comes to medicine and the human body; a thermometer reading is an example of a well-designed integration test case; if your temperature is high, then the doctor knows straight away that you have a problem which needs to be addressed. The doctor will probably not know exactly what the problem is immediately, but nonetheless, that simple thermometer reading (assertion) can allow them to detect the symptom of an essentially infinite range of possible underlying issues. One test case is not enough to cover all possible health problems, but the enormous amount of internal coverage that this single test case provides is unfathomable. We ought to try to come up with such test cases in our code.

If you have good integration tests, it doesn't really matter what language you use because (in terms of identifying issues) everything else pales in comparison.

Also it's important to note that integration testing doesn't necessarily mean end-to-end testing. You can still mock certain external components or engines in order to get more stability in your tests and you can still get that same kind of leverage.

How long does your integration test suite take to run? I have (many) typed interfaces and an editor running the language server. Typos, bad imports, etc are highlighted instantly and inline so they get fixed right away. Even better, autocomplete and refactoring tools know about these types, so typos and refactoring mistakes are vanishingly rare in the first place.

I agree that this does not replace integration tests or manual QA (dependencies can break and not every behavior can be checked). But as a lever for increasing productivity, a type system (even with the added complexity) is unbeatable.

Basically my point is that you aren’t actually catching errors at compile time, you’re catching them at build time. Your workflow might provide the same guarantees for the code that gets deployed to production, but writing that code is probably less enjoyable and you’re probably less productive than you could be.