Open
Description
I am preparing a huge workshop that I'll give next month on Good Scientific Code practices. (will upload to youtube and share here)
Unfortunately, our tests miss some good practices regarding a good unit test suite. Specifically:
- They are not "clean slate", which dictates that every test file should be runnable as-is, by itself, without depending on the global state, and without leaving something on the global state to be used later. Obviously, our test suite completely fails on that given the massive amount of definitions in
runtests.jl
and the lack ofusing
statements in the individual files. - They aren't organized into subfolders for better navigation. In fact, in general the organization of tests suffers with weird file names and content. E.g., what would you expect to be tested in the file
graph_tests.jl
? I'd expect all ofGraphSpace
features, but that's nowhere near the case. Each space should have its own test file. - They rely way too much on random numbers, where we should be writing analytic tests instead. Deterministic, analytically resolvable tests are the most accurate ones. The expected outcome of a test comes from pen and paper instead of running code. Right now we have a large amount of tests that were generated like "seed an rng, run some model code, write down the result as a test suite.". What we should be doing instead is "devise a distribution of agents. Analytically resolve their neighbors and actions given some rules and distances. Write tests that test again this analytically resolved output." I recall we had problems many times throught the lifespan of Agents.jl with random tests being broken etc. (obviously, random stuff like the RNG in the model should also be tested, but if you can avoid randomness in the tests, you should)
- They are not computationally minimal, which means that you should be doing the least amount of computer operations to confirm whether some functionality works. E.g., look at the start of
continuousSpace_tests.jl
. 8 spaces are initialized, but as far as the subsequent tests are concerned, you only need 3. In a similar vein, the test aren't also memory minimal. For the majority of the tests, we use agents that have extra fields likeweight
, even though we don't actually use these fields anywhere. E.g., see "mutable graphs" tests, which never uses the weight field yet assigns it anyways. - They don't use SafeTestsets. In the
runtests.jl
, the test files should be included likeand the only modules actually used in the@safetestset "Benchmark Tests" begin include("benchmark_tests.jl") end
runtests.jl
file should beTest, SafeTestsets
.