3 ms·
> Always include some randomness in test values. If this isn't a joke, I'd be very interested in the reasoning behind that statement, and whether or not there
by CoastalCoder 6mo ago
> Always include some randomness in test values.
If this isn't a joke, I'd be very interested in the reasoning behind that statement, and whether or not there are some qualifications on when it applies.
- whynotmaybe 6mo agoMust be some Mandela effect about some TDD documentation I read a long time ago. If you test math_add(1,2) and it returns 3, you don't know if the code does `return 3` or `return x+y`. It seems I might need to revise my view.
- Izkata 6mo agoI vaguely remember the same advice, it's pretty old. How you use the randomness is test specific, for example in math_add() it'd be something like: jitter = random(5) assertEqual(3 + jitter, math_add(1, 2 + jitter)) If it was math_multiply(), then adding the jitter would fail - that would have to be multiplied in. Nowadays I think this would be done with fuzzing/constraint tests, where you define "this relation must hold true" in a more structured way so the framework can choose random values, test more at once, and give better failure messages.
- whynotmaybe 6mo ago> it's pretty old. Damn, must be why only white hair is growing on my head now. >Nowadays I think this would be done with fuzzing/constraint tests, where you define "this relation must hold true" in a more structured way so the framework can choose random values, test more at once, and give better failure messages. So the concept of random is still there but expressed differently ? (= Am I partially right ?)
- Izkata 6mo agoYes, the randomness is still there but less manually specified by the developer. But also I haven't actually used it myself but had seen stuff on it before, so I had the wrong term: it's "property-based testing" you want to look for. Here's an example with a python library: https://hypothesis.readthedocs.io/en/latest/tutorial/introduction.html#testing-a-sorting-algorithm https://hypothesis.readthedocs.io/en/latest/tutorial/introdu... The strategy "st.lists(st.integers())" generates a random list of integers that get passed into the test function. And also this page says by default tests would be run (up to) 100 times: https://hypothesis.readthedocs.io/en/latest/tutorial/settings.html https://hypothesis.readthedocs.io/en/latest/tutorial/setting... So I'm thinking... (not tested) @given(st.integers(), st.integers()) def test_math_add(a, b): assert a + b == math_add(a, b) ...which is of course a little silly, but math_add() is a bit of a silly function anyway.
- ajs1998 6mo agoRandomness is useful if you expect your code to do the correct thing with some probability. You test lots of different samples and if they fail more than you expect then you should review the code. You wouldn't test dynamic random samples of add(x, y) because you wouldn't expect it to always return 3, but in this case it wouldn't hurt.
- brewmarche 6mo agoThis sounds like the idea behind mutation testing
- dathinab 6mo agohumans are very good at overlooking edge cases, off by one errors etc. so if you generate test data randomly you have a higher chance of "accidentally" running into overlooked edge cases you could say there is a "adding more random -> cost" ladder like - no randomness, no cost, nothing gained - a bit of randomness, very small cost, very rarely beneficial (<- doable in unit tests) - (limited) prop testing, high cost (test runs multiple times with many random values), decent chance to find incorrect edge cases (<- can be barely doable in unit tests, if limited enough, often feature gates as too expensive) - (full) prop testing/fuzzing, very very high cost, very high chance incorrect edge cases are found IFF the domain isn't too large (<- a full test run might need days to complete)
- ssdspoimdsjvv 6mo agoI've learnt that if a test only fails sometimes, it can take a long time for somebody to actually investigate the cause,in the meantime it's written off as just another flaky test. If there really is a bug, it will probably surface sooner in production than it gets fixed.
- dathinab 6mo agosadly yes people often take flaky test way less serious then they should I had multiple bigger production issues which had been caught by tests >1 month before they happened in production, but where written off as flaky tests (ironically this was also not related to any random test data but more load/race condition related things which failed when too many tests which created full separate tenants for isolation happened to run at the same time). And in some CI environments flaky test are too painful, so using "actual" random data isn't viable and a fixed seed has to be used on CI (that is if you can, because too much libs/tools/etc. do not allow that). At least for "merge approval" runs. That many CI systems suck badly the moment you project and team size isn't around the size of a toy project doesn't help either.
- tomjakubowski 6mo agoFlaky tests are a very strong signal of a bug, somewhere. Problem is it's not always easy to tell if the bug's in the test or in the code under test. The developer who would rather re-run the test to make it pass than investigate probably thinks it's the test which is buggy.
- j1mr10rd4n 6mo agoThere's another good reason that hasn't been detailed in the comments so far: expressing intent. A test should communicate its reason for testing the subject, and when an input is generated or random, it clearly communicates that this test doesn't care about the specific _value_ of that input, it's focussed on something else. This has other beneficial effects on test suites, especially as they change over the lifetime of their subjects: * keeping test data isolated, avoiding coupling across tests * avoiding magic strings * and as mentioned in this thread, any "flakiness" is probably a signal of an edge-case that should be handled deterministically and * it's more fun [1] [1] https://arxiv.org/pdf/2312.01680 https://arxiv.org/pdf/2312.01680