turned out to be a semicolon
The tests wouldn’t even run of that was the issue, pretty sure (depends on the language I suppose)
fun situations can arise when you write , instead of ; For those not in the know, in c++ the comma operator evaluates the left expression, discards the value, then evaluates the right expression and returns the value. if you now have a a situation like this
int i = 0,
printf("some message");
i has a completely different value, since it actually uses the return value of printf instead
I’ll just write thousands of lines of code inside a global object… I’m sure I won’t put a semicolon where a comma should be…
now you have a group of very specific tests for later debugging
Who tests the tests
I’ve written some tests that got complex enough that I also wrote tests for the logic within the tests.
We do that for some of the more complex business logic. We wrote libraries, which are used by our tests, and we wrote tests which test the library functions to ensure they provide correct results.
What always worries me is that WE came up with that. It wasn’t some higher up, or business unit, or anything. Only because we cared to do our job correctly. If we didn’t - nobody would. Nobody is watching the testers (in my experience).
Mutation testing is quite cool. Basically it analyzes you code and makes changes that should break something. For example if you have if (foo) { ... }
it will remove the branch or make the branch run every time. It then runs your tests and sees if anything fails. If the tests don’t fail then either you should add another test, or that code was truly dead and should be removed.
Of course this has lots of “false positives”. For example you may be checking if an allocation succeeded and don’t need to test if every possible allocation in your code fails, you trust that you can write if (!mem) abort()
correctly.
If you use your type system to make invalid states impossible to represent & your functions are pure, there less—maybe nothing—to test, which will save you from this scenario.
Nothing toy-like about using ADTs to eliminate certain cases. When all cases are handled, your tests can move from a micro state to a macro state. Contraint types or linear types can be used to only allow certain sizes of inputs or require all file handles be closed when opened.
Naturally if your language’s type system is bad you can’t make these compile-time guarantees tho. Heck, a lot of developers are still using piss-poor languages with null
or the infernce sucks with any
.
Nothing to test? Lol what.
def add(a: int, b: int) -> int: return a * b
All types are correct. No side effects. Does the wrong thing.
Lmao, I just had something similar