4 ms·
They are not diametrically opposed, but rather they’re non-overlapping with a strong type system. In a dynamic language you end up writing a number of tests th
by ashtonkem 5y ago
They are not diametrically opposed, but rather they’re non-overlapping with a strong type system.
In a dynamic language you end up writing a number of tests that would be covered by a static type system and writing a number of tests that would not be covered by that. Going from dynamic to static typing is a replacement for some of the former, and none of the latter.
- pydry 5y ago>In a dynamic language you end up writing a number of tests that would be covered by a static type system Not once have I done this. I've written plenty of invariants that would have been covered by a static type system but no tests. As far as I'm concerned if you had to write an extra test to "cover for a dynamic type system" that test is a bad smell that should be deleted. A test validates that a method raises an exception when being fed a null is pointless if it's just testing a one line assertion that does the same thing. It's a waste of keystrokes. It doesnt catch bugs. There may be some exceptions to this rule but they would be under very obscure circumstances, I think.
- camdenreslink 5y agoOne reason to have tests like that, is to cover regressions. Say somebody changes that method in the future and it doesn’t raise an exception anymore when passed a null (but it is still supposed to, the change introduced a bug). If you have that “pointless” test, you’ll find out about it. If not, you’ll probably only encounter it at runtime with a program that is subtly wrong.
- pydry 5y agoNo, you won't. If somebody removes that line they had a reason. That reason will make them remove the test that makes it fail as well. Whether it's a good or a bad decision is another matter and not something the test will help with. Tests that exist to check for the presence of a single line of code are deadweight.
- shadowgovt 5y agoThis story doesn't match with my observation programming. Failure to sanity-check a null almost never stemmed from someone deleting the non-null assertion intentionally. It stemmed from someone rewiring the control flow in such a way as to bypass the non-null assertion without intending to (such as early-returning because they think they can shortcut the computation, but the shortcut isn't actually valid if the argument in question is null). The tests have value precisely because they aren't in the regular control flow of the unit under test and will fail when the code flow is changed and the author didn't realize the change modified the expected behavior of the function.
- duped 5y agoThey're deadweight until someone pushes a change that makes some assumption about that line of code the author didn't mention were invalid.
- camdenreslink 5y agoIt’s possible that the code was modified in a way that bypasses the null-check. It isn’t necessarily true that anybody removed code. Unit tests that test the contract of a method (if you put in this argument, then you’ll get this return or side effect) are a good idea in both dynamic and static languages.
- dragonwriter 5y ago> If somebody removes that line they had a reason. That reason will be one of two things: (1) They replaced it with something they thought would handle the same functionality (along with possibly some other functionality) in a beter way, or (2) The requirement changed. > That reason will make them remove the test that makes it fail as well. If it was #2, sure (and in a test-first workflow, they would take out the test first). In case #1, they won’t take out the test, and if their implementation is wrong, the test will let them know. > Tests that exist to check for the presence of a single line of code are deadweight. Unless you have a very weird framework, tests don’t check the existence of lines of code, they check the behavior of units. The fact that the first-pass implementation in the same iteration in which the test was added is trivial doesn’t mean the function isn’t part of the contract that needs verified, and doesn’t mean that no one will ever change the intended implementation to a less direct one.
- kd0amg 5y ago> I've written plenty of invariants that would have been covered by a static type system but no tests. Do these invariants have some language-level support?
- tablespoon 5y ago>> In a dynamic language you end up writing a number of tests that would be covered by a static type system > There may be some exceptions to this rule but they would be under very obscure circumstances, I think. Maybe it depends highly on the specific dynamic and static languages under comparison. My main experience with dynamic languages has been with Groovy (all inherited codebases), and it's an annoyingly frequent occurrence that I've had to deal with PROD issues for things that would have been compile errors in Java. I believe my favorite is when someone used a String for the counter in a for loop, and it worked...until one day the counter had to go past 9. IIRC, Groovy would convert the String to a char, increment it, then convert that into an Integer. That actually works for 0-9, but incrementing "9" in this way gives you ":" which would then get a NumberFormatException in the last conversion.
- dragonwriter 5y ago> A test validates that a method raises an exception when being fed a null is pointless if it’s just testing a one line assertion that does the same thing. It’s a waste of keystrokes. It doesnt catch bugs. It catches the bug that gets created when someone does a later refactor, replaces the assertion and some other code with a call to another function that they think throws an exception on null as well as doing some computation needed in the current function, but they are wrong. Tests validating the contract of the unit are useful even when the trivially pass in the first-pass implementation, because implementations evolve, and the thing people will forget to add tests for with changes are the pre-existing, unmodified expected behavior. (Also, for workflows where tests are written before the first-pass implementation.)
- bwship 5y agoYea, I mean the problem is. If you have a function that expects a number parameter. In Typescript, the compiler won't let you do this someFunction('a'), so you never have to worry about handling this. But, if it is in javascript, then someone can call the function like that. So in javascript, you might have a test that ensures that the function handles this gracefully. You obviously don't have to have that test, but you will have your app blow up later down the line, if someone adds a call like that. So, testing does occur at times for these types of things. You might not have done it ever, but there are certainly devs who have, myself included.