-
Notifications
You must be signed in to change notification settings - Fork 220
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Test restructuring #2237
Test restructuring #2237
Conversation
For the record, optimally I would have liked the selective test running to be based on testset names rather than file paths. I tried a couple of designs for that, but ran into various limitations and complexities in how |
cc @willtebbutt @devmotion who might have thoughts. |
I'm in favour of these kinds of changes -- it's good to clean up the namespaces, and to remove these macros in favour of using standard functionality. Re parallelisation of tests: I've generally gone about this in a very slightly different way (see e.g. Tapir's tests and the associated action ), but it's not obvious to me that either approach is necessarily better than the other. |
There's a file called |
It should be included. |
I finished the restructuring described in the opening message. I also removed the code coverage part of CI, because it seems to have been broken for the last > 1 year. If we want to reintroduce it I would propose running it as a separate job outside the current test matrix, since it requires running all the tests in one go and only on a single platform. More work could be done harmonising the way we do imports and qualified references, but I think that could be a separate PR. In this one I avoided touching anything in the actual test code, and only modifying the "header" of each file. The longest test CI job now takes around 25 minutes, so more could perhaps be done to make tests faster. (EDIT: I did some further splitting, so now it's more like 20 minutes.) Either making them more lightweight or splitting some of the heavy test files into several files. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no particular comments on the functionality, just a couple of comments on style! I've commented on representative examples, rather than going through and commenting on each thing manually.
I appreciate the effort, it's good to clean up and improve the test structure a bit 🙂 My feeling is that we should neither implement nor use parsing of test args (and hence do not support something like |
Thanks for the comment @devmotion, happy to discuss this. Here are reasons why I went with
That's a fair point that I hadn't considered. At the same time, the
I would argue that using
You can have a similar user experience with |
I can see these points and I'm sure tests could be structured with IMO one of the main problems with the current Turing test setup is that it does not follow common practices in the ecosystem and defines its own macros for structuring the tests. My impression is that this makes it unnecessarily complicated for new contributors to read, modify, and add tests and adds additional maintenance burden on our side. My worry is that with an uncommon practice such as |
I like the |
I'm still not convinced (but also don't care too much if everyone else has a different opinion) - I think it's good to adopt improvements even if they are not common practice yet, but I don't see why/how |
For those who would prefer env vars, how would you like to implement being able to include and exclude multiple test files in a given run? In other words, what would be the env var equivalent of doing
I do see some benefits, the most important ones being
I commented on 1. more extensively above, but to expand on 2., giving command line arguments to include/exclude particular tests is the standard way to do things in for instance pytest and the standard unit testing frameworks of both Go and Rust. I haven't used all that many testing frameworks, but I haven't seen SciML's env var approach elsewhere. I presume this consistency with other languages and frameworks is also why Using environment variables for test selection also goes against my idea of what env vars are meant for. I view env vars as global flags that should set some state about the, well, the environment in which the process operates. Kinda like defining a global constant at the top your source code file that affects everything in that package/module. Selectively running tests is more like passing arguments to a function as you call it, where you might for instance call it back to back with different arguments, and that's exactly what command line arguments are for. |
This is a really good argument 👍 You could of course implement the same parsing of an
I that the the docs mention that this is a use-case for args, but does it specifically recommend that over ENV variables? I'm am genuinely quite keen on giving this pattern a go, but I'm also somewhat worried about doing this in Turing.jl 😕 Has there been a similar discussion elsewhere? I.e. what's the reasoning of the rest of the ecosystem going with |
Yeah, I think parsing complicated env vars gets awkward. You could define two env vars though,
No, I don't think it says anything about environment variables. |
The test failures seem unrelated to this PR. They seem to rather be about the recent ADTypes compat change interacting in funky ways with Optimization.jl version bounds when using Julia 1.7. I haven't gotten to the bottom of it yet. |
Probably something similar to Generally, I haven't encountered the need for such complex inclusion/exclusion of tests yet, so I'm a bit skeptic whether the additional complexity (both for users and developers) is worth it. Having the possibility to run all tests (typically the default but not used in CI) and pre-defined groups of tests has been sufficient in all packages I have worked with. For running even smaller chunks of tests or subsets of test files in local development in my experience typically the most convenient approach is to use TestEnv anyway. |
Can we parse/extract test options in both |
Yep, we could definitely have both available. Have e.g. the ARGS parsing implemented as in the current version of this PR and append to the list of included tests the value of an env var called Regardless of ARGS/env vars choice, I would still like to stick to tests being selected by file path rather than by manually grouping them. Benefits are
Consequently calling the env var |
So I've also done the same, but having had experience with testing in other languages, I also do sometimes miss the ability to simply filter tests based on their name or whatever. It's particularly nice to do when you're working on bugfixes, since then there's a particular sub-test-suite you want to run, which then usually requires copy-pasting to another file, using TestEnv.jl, etc.
Both also seems non-ideal, no? 😕 I'd rather have to do that (push onto |
* Restore compat with ADTypes v0.2. Make AutoTapir export conditional. * Fix AutoTapir export in Essential.jl
I'm happy only to support |
I'm also slowly coming to terms with the |
@mhauru, feel free to merge this PR when you are ready. |
Given @yebai and @torfjelde have come around to args and @devmotion said earlier that he's not too bothered if others are happy with this, I'll go and merge. Everyone seems to agree that this is regardless an improvement over the current situation, and if people miss having a SciML-style |
For other people who are lazy: you might find it useful to add a file called, say, using Pkg
Pkg.test("Turing", test_args=ARGS) then you can do julia --project test/testrunner.jl a b c -skip d e |
Even better, in general you can do: using Pkg
Pkg.test(Pkg.project().name, test_args=ARGS) though |
@torfjelde can you add this tip to the following docs page: https://turinglang.org/docs/tutorials/docs-01-contributing-guide/#tests |
Question is whether we should just have a small script |
This seems like a common problem for many Julia packages, is there no standard solution to this? It feels frustrating that |
I'd suggest running julia --project=. -e 'import Pkg; Pkg.test(; test_args=ARGS)' -- a b c --skip d e if you don't work in a Julia REPL and want to execute the tests. |
@devmotion, it looks very neat -- I added it to the docs: https://turinglang.org/docs/tutorials/docs-01-contributing-guide/#tests |
This PR makes two orthogonal changes to how tests are run and structured.
runtests.jl
are made into modules, and imports are moved into those modules.runtests.jl
now has minimal imports. This cleans up the namespaces in which the individual tests are run, and makes it clearer where various references in tests point to.Pkg.test("Turing", test_args=["optim", "hmc", "--skip", "ext", "nelder"])
then only test files that have the substring"optim"
or"hmc"
in their path will be run, unless they also have one of the substrings"ext"
or"nelder"
in their path, in which case they are skipped. By default all tests are run. Substring comparisons are case-insensitive.Point 2. makes the
@turing_testset
and@numerical_testset
macros unnecessary, and they will be removed.The selective running of tests is useful for both local development and splitting our CI to run tests for various parts of the Turing.jl in parallel (#2179). I'll try implementing the latter next to see that it goes smoothly.
This is an early draft, I'm opening it to get comments (@yebai, @torfjelde). I've only converted a couple of files to the submodule format, and the selective running lacks documentation. If this is deemed a good design I'll go and finish the implementation.