Description
Proposal to improve rez-test.
- Add run_on field for tests
- Add way to run 'all' tests (regardless of run_on)
- Add rez-test
--interactive
option - Add rez-test
--inplace
option - Pass custom arguments when running a test
- Add variant iteration options
Note: Some of these features clearly change rez-test into something a bit more general, so the name may have to change (to rez-task for eg). However we will consider this as a separate issue.
1. Add "run_on" field for tests.
This would define when the test gets run. Possible values:
- "default" (the default): Run when rez-test is run with no TEST arg(s).
- "pre-install": Run before a package install (not release); abort the install on failure.
- "pre-release": Run before package release, abort release on failure.
- "explicit": Only run if explicitly specified by rez-test, as a TEST arg.
The param would be a list, so a test can run on multiple of these events.
For pre-install/release, what would happen is:
- The package source is built;
- It is then installed to a temp dir.
- This temp installation is then used to run the test(s);
- If the tests pass, a second installation is performed to the correct location.
2. Run all tests defined by a package
I feel the need to be able to run all tests defined by a package, no matter what their run_on
is set to.
rez-test <package> all
That would introduce a "reserved" target name all
, but I think we should still let anyone refine its own all
target, hence the quotes around the reserved
word ;)
3. Pass custom arguments when running a test
It is common to have to modify the commands of the tests for a package while developing that said package. There is multiple reasons why we do so. For example, you might want to increase the verbosity of your tests only when developing and keep the verbosity lower in your CI tests. The other common reason is to choose a custom target inside a particular test so you can iterate faster and avoid running unnecessary tests.
For example, let's say we have:
tests = {
'unit': {
'command': 'pytest {root}/tests/unit_tests'
'requires': 'pytest'
}
}
where tests/unit_tests
contains multiple test files and each file contains tests with markers (pytest jargon. A marker is basically a way to group the tests so that you can selectively choose which one to run in the command line).
I propose to add a functionality to make rez-test package unit -- -v -m myMarker
valid and that would run pytest {root}/tests/unit_tests -v -m myMarker
.
The immediate benefit is that it's faster and more intuitive. The second is that it can avoid mistakenly committing the modifications to the tests
variable.
Note that passing custom arguments should only be possible if only one test is being run.
4. More execution options
Specifically:
- A
rez-test --interactive
option. Puts you into an interactive shell for the nominated test. From here you could then use... - A
rez-test --inplace
option. Ie, run the tests in the current env, if it provides all the required packages. If not, give an error.
5. Variant iteration options
Many times, it makes sense to run a test on all variants of a package. Currently that doesn't happen (variants aren't iterated over at all) because there's not currently a reliable way to resolve to an explicit variant in rez. However, until such time as we have the required feature to do this, we could get pretty close, and it's probably worth doing (the code needed to do this is minimal).
Some things to consider:
- Some tests won't make sense to run over multiple variants (eg linting).
- Some tests might only make sense to run on certain variants (eg just variants requiring "maya")
How to express this? Perhaps a new variant
tests field. For eg, with variant: True
, the test will be run on every variant. If False/not present, it will just run on one variant (matching current behaviour). If a dict containing "requires", it will run only on variants overlapping with the given request list; furthermore, if the requires list conflicts with a variant, that variant is skipped.
For example, given:
variants = [
["python-3"],
["python-3", "maya-2018"],
["python-3", "maya-2019"]
]
tests = {
"linter": {
"command": "pylint ...",
"variant": False
},
"core": {
"command": "python {root}/run_core_unit_tests.py",
"variant": {
"requires": ["!maya"]
}
}
}
- The linter test would run just once, not per variant;
- The 'core' test would run on every variant not containing maya