-
-
Notifications
You must be signed in to change notification settings - Fork 642
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
Merge pytest addopts #16614
Merge pytest addopts #16614
Conversation
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
@@ -311,14 +313,32 @@ async def setup_pytest_for_target( | |||
f"--cov-config={coverage_config.path}", | |||
*cov_args, | |||
] | |||
pants_add_opts.extend(["--cov-report", "--cov-config"]) # --cov not there as multi-allowed. | |||
|
|||
# Get extra PYTEST_ADDOPTS env var from each possible sources. |
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.
This was all starting to feel a bit like too much work / too brittle / etc. so I asked why are we doing things this way / is there another way?
As to why, I traced history and can find no specific justification for choosing env var vs directly using args:
- origin of PYTEST_ADDOPTS: Use color in v2 pytest #8901
- use of PYTEST_ADDOPTS to deal with junit xml: Add the ability to write junit test results file for pytest runs. #9594
Here's why pytest has to say about PYTEST_ADDOPTS:
https://docs.pytest.org/en/7.1.x/reference/reference.html?highlight=pytest_addopts#envvar-PYTEST_ADDOPTS
The pre-pend bit made me want to know how multiple instance of a flag works then:
python3.9 -mvenv pytest.venv
pytest.venv/bin/pip -q install -U pip
pytest.venv/bin/pip install pytest==7.0.1
touch test.py
$ PYTEST_ADDOPTS="--junit-xml fred.xml" ./pytest.venv/bin/pytest --junit-xml george.xml --junitxml=betty.xml --collect-only -q test.py
------------------------------------------------------------------------------------------------------------------ generated xml file: /home/jsirois/betty.xml ------------------------------------------------------------------------------------------------------------------
no tests collected in 0.00s
So it looks like CLI trumps env var and right-most CLI arg trumps leftmost. Since we completely control the CLI args passed to pytest below, it seems we could just insert the args we require there. Our communication channel then becomes fully robust and looking for duplicates in PYTEST_ADDOPTS to warn is just a nicety at that point. In fact, reading about the -o
option, it turns out its a very difficult nicety to unfailingly present! We only check env vars but we could be stomping a setting in config. We've been doing that all along it turns out! So maybe even the dup warnings checking is going to far, or at least we should only be checking for the --junitxml
dup, since, FWICT, you cannot specify that option in config.
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'm not sure I follow. There are so many options that the user can pass via PYTEST_ADDOPTS
that it becomes difficult to check them all. That's why I simply put a warning and let pytest handle the duplicate options. And what if the user really wants to override an option used/set by pants?
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.
At least, if there is weird behavior like the one I experienced, the user will have a little hint. In my case, I was completely in the dark.
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.
My main point is - can we use argv to pass the args we must have never be over-ridden instead of using the current PYTEST_ADDOPTS
mechanism for our own necessary options. That would fully solve robustness.
Then warning about collisions for those options we must pass via the argv stomping user options is just a nicety. I was further pointing out its a nicety we do not extend to junitfamily today since that requires reading all potential config files where users might have set it. Further, doing so would be fragile - we'd be re-implementing the pytest config logic. As such, maybe warning should be jettisoned or at least restricted to just --junit-xml, which, FWICT, cannot be set via config file like junitfamily can.
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.
At least, if there is weird behavior like the one I experienced, the user will have a little hint. In my case, I was completely in the dark.
And you'll still be completely in the dark if you use pytest config files in your repo to set junitfamily. We'll still stomp that silently.
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.
Ok, I see... I'll wait for others to chime in before removing the warnings completely or restricting to only --junit-xml
/--junitxml
. Thank you for your feedback.
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.
Confirming that I looked at those older PRs and I see no strong reason they used the env var instead of the cli ags, other than the author's personal preference (or them being unware of the args possibility).
for popt in pants_add_opts: | ||
if any(popt in eopt for eopt in extra_add_opts): | ||
logger.warning( | ||
f"The option '{popt}' is set by Pants but also in PYTEST_ADDOPTS environment variable. This can cause unexpected behavior." |
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.
So, I played around with pytest 7.0.1 which is what main currently ships with by default:
pants/src/python/pants/backend/python/subsystems/pytest.py
Lines 60 to 72 in 9449f42
class PyTest(PythonToolBase): | |
options_scope = "pytest" | |
name = "Pytest" | |
help = "The pytest Python test framework (https://docs.pytest.org/)." | |
# This should be compatible with requirements.txt, although it can be more precise. | |
# TODO: To fix this, we should allow using a `target_option` referring to a | |
# `python_requirement` to override the version. | |
# Pytest 7.1.0 introduced a significant bug that is apparently not fixed as of 7.1.1 (the most | |
# recent release at the time of writing). see https://github.com/pantsbuild/pants/issues/14990. | |
# TODO: Once this issue is fixed, loosen this to allow the version to float above the bad ones. | |
# E.g., as default_version = "pytest>=7,<8,!=7.1.0,!=7.1.1" | |
default_version = "pytest==7.0.1" |
It has much more variety in what it accepts. FWICT, there are these variants:
--junit-xml
or--junitxml
=
or-o
or--override-ini
For the last, you currently ignore the -o
prefix to junit_family
and that's probably fine; so probably this can be ignored. Likewise for 2 you can ignore the introduction of the value separator and you do; so things are still good. For the 1st though, that would need to be checked too.
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.
--junitxml
added to the list.
@asherf I added you since you introduced the use of |
Do you think this feature will make its way to 2.12.x (or 2.13)? I don't want to put any pressure, but we are blocked by this bug because it prevents us from properly testing our Django/Nautobot apps. I suggest to remove the warnings completely and just merge the PYTEST_ADDOPTS environment variables. It would resolve this issue and we can open another ticket to improve the communcation mechanism. What do you think? |
It would be good to get additional reviewer feedback, but before requiring that I want to verify your blocked status. Is it not true that for each test where you use |
How can I determine the resulting filename? |
Two ways:
Once you've figured the answer out for 1 target via one of the techniques above, the rest should be obvious by pattern. |
Sorry, my question is poorly worded. I know what the name of the xml files will be, but how/where do I specify them? In my case, I only have one If I understand correctly, I would have to create a |
Ok, so then you do have the issue of "Maybe the problem is you have hundreds of such targets instead of 10s or just a handful?". I'd really like to avoid ramming this through without proper review / thrashing later to get things right. Currently most Pants maintainers and all the reviewers on this PR are engrossed in a sprint to ship local Pants process execution via docker containers; so I'm trying hard to unblock you elsewise. Towards that end, see here: https://www.pantsbuild.org/docs/reference-pytest#section-config-discovery Does that work for you? |
I only have one target, but if a want to specify the
Thank you for that, it is very appreciated! Concerning pytest config discovery, I don't think it will work because I have many non-Nautoboty tests. |
It should work. If the pytest.ini file is in the root of your repo it should automatically apply to all tests. Please give it a quick try and report back. |
Yes, it works for my Nautobot tests, but now all my other tests are failing, because they are not able to load the |
Ok, instead of using You can add the plugin requirement globally using https://www.pantsbuild.org/docs/reference-pytest#section-extra-requirements That will force you to use a custom lock file for pytest. The complete setup should be: [pytest]
# TODO: Remove all this configuration once https://github.com/pantsbuild/pants/pull/16614
# lands and we can upgrade to a Pants version that contains that fix.
args = "-p pytest_nautobot --reuse-db"
# N.B.: You probably want to use a requirement that matches your repo requirement.
# for example "pynautobot==1.1.2".
extra_requirements = ["pynautobot"]
lockfile = "any/path/you/choose/pytest.lock" You'll need to then run |
Well, Anyway, I did not have a lot of of test deps to change. Thanks again for your help! |
In that case can you not just install the hook in an appropriately scoped conftest.py file?: https://docs.pytest.org/en/7.1.x/how-to/plugins.html#requiring-loading-plugins-in-a-test-module-or-conftest-file |
Unfortunately no. I use the |
Folks, this has been lingering too long. I enjoined Eric to include / wait on other reviewers to avoid thrashing and I'm hoping @asherf, @Eric-Arellano or @benjyw can review and comment on #16614 (comment) - It is unclear to me why we use PYTEST_ADDOPTS as our internal mechanism of controlling pytest vs just passing args. If one of you could check me on my logic or provide any background on the history, I'd be grateful. |
Sorry this has been lingering! I think it makes total sense to: A) switch the internal use of PYTEST_ADDOPTS to use CLI args. That seems a lot less brittle than attempting to dedup and merge our own PYTEST_ADDOPTS and the user's. |
Thanks @erjac77, that sounds great! |
# Rust tests and lints will be skipped. Delete if not intended. [ci skip-rust] # Building wheels and fs_util will be skipped. Delete if not intended. [ci skip-build-wheels]
Sorry for the delay. I finally found the time to work on this issue.
Done. But I was wondering why
I put the documentation in
I worked on this one but eventually gave up because there are so many permutations and I couldn't find an elegant way to do these checks. |
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.
Thanks for sticking with this @erjac77. This looks great to me. A few nits to discuss in documentation. Let me know what you think and then this is ready for merge.
) | ||
``` | ||
|
||
Take note that Pants uses some CLI args for its internal mechanism of controlling Pytest (`--color`, `--junit-xml`, `junit_family`, `--cov`, `--cov-report` and `--cov-config`). In order to preserve the communication channel with Pytest, `PYTEST_ADDOPTS` is not allowed to override these hardwired CLI args. |
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.
Well, you are allowed, it's just at your own peril. Since Pants caching is robust, if you tromp one of these that's important (--color
is not that important), you'll get a weird failure or unexpected result and you solve by backing out that BUILD change.
So, I think 1st sentence is great, but last should be something like: "Set these at your own peril." or "If these options are overridden, Pants pytest handling may not work correctly."
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 made the change, but I thought that CLI args took precedence over env vars.
So it looks like CLI trumps env var and right-most CLI arg trumps leftmost.
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.
Ah, that is right. I did that experiment already: #16614 (comment)
The PR thread is long and my memory is short. That said, your warning verbiage as-is does no real harm I can see. We can always retract it later or re-word to say something more definitive like your customization of these options will be ignored!
@@ -499,3 +499,21 @@ report = true | |||
``` | |||
|
|||
This will default to writing test reports to `dist/test/reports`. You may also want to set the option `[pytest].junit_family` to change the format. Run `./pants help-advanced pytest` for more information. | |||
|
|||
PYTEST_ADDOPTS environment variable |
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.
The title is not too searchable, it assumes you know about this pytest special env var in the 1st place. How about more topical?: "Customize pytest command line options per target"
Thanks again for sticking with this @erjac77. This will naturally flow out into the 2.16.0 release series. |
Thanks @erjac77 ! Great improvement :) |
Closes #16601