You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Command line parsing fails when path is a value for an option #906
On Mac OS X 10.10.4 using the latest homebrew Python 2.7.10, and py.test 2.7.2, if type on the command line: py.test --app ~/path/to/app --host http://localhost:4444 tests/mobile
The problem is how conftest files and command-line options interact. This section explains in detail how plugins and conftest files are loaded during startup, but relevant to this issue is this note:
Note that pytest does not find conftest.py files in deeper nested sub directories at tool startup. It is usually a good idea to keep your conftest.py file in the top level test or project root directory.
So pytest starts and loads the initial plugins (registered using setuptools) and conftest files (just those found in cwd), reads command line options defined by plugins and conftest files found, parses the command line supplied by the user and starts collecting tests and other conftest files. That's the reason you see the error about the unknown command line option if the conftest file is not at the cwd, as it would be loaded only later during test collection.
To fix this I suggest the following options:
Move your options to a "proper" setuptools plugin (docs here;
If the conftest is inside your application's package, you can move it to a separate module and ask pytest to treat it as a plugin by using the --addopts option in a pytest.ini file:
[pytest]addopts = -p automation.myplugin
This will ensure pytest will load your plugin before actually parsing the command-line supplied by the user.
Having said all that, I think we should add something to the docs about this issue, as I believe it is a common source of confusion.
I am not convinced your explanation is the reason why this fail. If I reverse the options to py.test --host http://localhost:4444 tests/mobile --app ~/path/to/app I have no issues.
@Dude-x I'm having trouble obtaining the same error using the conftest.py file you provided, on Windows and Ubuntu, pytest version 2.7.2 and master. Could you provide a minimal example which reproduces your problem?
I think I know what's going on. During initialization, pytest tries to parse the arguments from the command-line. At this stage only builtin and plugin options are known, so the unknown args are kept aside for later inspection. After this, it tries to determine the rootdir by looking at all unknown arguments which are clearly not options (don't start with -). At this point, it doesn't know your --host option takes a parameter (it could be a flag for all pytest knows at this point) so it looks at the next argument and seeing a directory, tries to use it to determinerootdir. Only later it will load the conftest files and parse the remaining arguments.
So, it all boils down to the fact that conftests are loaded at a later stage than builtin and plugin options, which can affect which command line options will actually be validated and used as this mechanism depends entirely from where you execute py.test, or which arguments are passed on the command line.
If you change your conftest file into a plugin, it should work consistently no matter where you call py.test from, or what you pass on the command-line.
It is unfortunate (but understandable) that there's this gotcha when working with pytest_addoption and conftest files, because conftest initialization being lazy as it is now can lead to surprising errors. Perhaps a note to pytest_addoption discouraging its use from conftest files would at least warn users of these pitfall?
That's a bit general, no? Using it in the top-level contest.py is generally fine IIRC.
I had trouble with this until recently at work, because we had a top-level conftest.py which defined a few options, but if a user was in a different directory other than the root directory the options would not be available from the command-line (this with pytest-2.7.0, not sure if this has changed since then).
I'm seeing this issue with pytest ≥ 2.8.0 with a plugin (not a conftest.py). The plugin I'm using is pytest-variables, but pytest-html is also affected. The argument values appear to be used for determining the root directory.
Activity
RonnyPfannschmidt commentedon Jul 30, 2015
can you please show your folder layout as well including where you run py.test
isaulv commentedon Jul 30, 2015
Running Python and Py.test in a virtualenv
I run py.test from at
.../automation/as my root folder.nicoddemus commentedon Aug 8, 2015
The problem is how
conftestfiles and command-line options interact. This section explains in detail how plugins andconftestfiles are loaded during startup, but relevant to this issue is this note:So pytest starts and loads the initial plugins (registered using setuptools) and
conftestfiles (just those found in cwd), reads command line options defined by plugins andconftestfiles found, parses the command line supplied by the user and starts collecting tests and otherconftestfiles. That's the reason you see the error about the unknown command line option if theconftestfile is not at the cwd, as it would be loaded only later during test collection.To fix this I suggest the following options:
Move your options to a "proper" setuptools plugin (docs here;
If the conftest is inside your application's package, you can move it to a separate module and ask pytest to treat it as a plugin by using the
--addoptsoption in apytest.inifile:This will ensure pytest will load your plugin before actually parsing the command-line supplied by the user.
Having said all that, I think we should add something to the docs about this issue, as I believe it is a common source of confusion.
isaulv commentedon Aug 11, 2015
I am not convinced your explanation is the reason why this fail. If I reverse the options to
py.test --host http://localhost:4444 tests/mobile --app ~/path/to/appI have no issues.nicoddemus commentedon Aug 11, 2015
Hmmm sorry, I missed your note at the end:
So, if you execute:
You get:
But if you execute:
or
It works?
isaulv commentedon Aug 11, 2015
That is correct.
nicoddemus commentedon Aug 11, 2015
Thanks, sorry I misunderstood the problem initially.
This certainly looks like a bug, thanks for the report!
nicoddemus commentedon Aug 26, 2015
@Dude-x I'm having trouble obtaining the same error using the
conftest.pyfile you provided, on Windows and Ubuntu, pytest version2.7.2andmaster. Could you provide a minimal example which reproduces your problem?isaulv commentedon Aug 26, 2015
It seems issue #949 is somewhat related. I'll whip up a minimum viable test case later.
nicoddemus commentedon Aug 26, 2015
Thanks!
isaulv commentedon Aug 27, 2015
Here's a simple test case, using the latest stable release of py.test (2.7.2)
Directory structure:
Content of conftest.py
Command line at /Users/dude-x/development/test-case
Output:
The thing to notice is that the rootdir is wrong, it should be /test-case, and not my parent.
Here's one where it fails to parse:
nicoddemus commentedon Aug 27, 2015
Hi @Dude-x, thanks for posting the example. 😄
I think I know what's going on. During initialization, pytest tries to parse the arguments from the command-line. At this stage only builtin and plugin options are known, so the unknown args are kept aside for later inspection. After this, it tries to determine the
rootdirby looking at all unknown arguments which are clearly not options (don't start with-). At this point, it doesn't know your--hostoption takes a parameter (it could be a flag for all pytest knows at this point) so it looks at the next argument and seeing a directory, tries to use it to determinerootdir. Only later it will load theconftestfiles and parse the remaining arguments.So, it all boils down to the fact that conftests are loaded at a later stage than builtin and plugin options, which can affect which command line options will actually be validated and used as this mechanism depends entirely from where you execute
py.test, or which arguments are passed on the command line.If you change your conftest file into a plugin, it should work consistently no matter where you call
py.testfrom, or what you pass on the command-line.It is unfortunate (but understandable) that there's this gotcha when working with
pytest_addoptionandconftestfiles, becauseconftestinitialization being lazy as it is now can lead to surprising errors. Perhaps a note topytest_addoptiondiscouraging its use fromconftestfiles would at least warn users of these pitfall?nicoddemus commentedon Aug 27, 2015
I went to update
pytest_addoptionand noticed that it already mentions something to this effect:<pluginorder>points to the aforementioned docs.I will add a warning to not use that from
conftestfiles.flub commentedon Aug 27, 2015
On 27 Aug 2015 23:09, "Bruno Oliveira" [email protected] wrote:
That's a bit general, no? Using it in the top-level contest.py is generally
fine IIRC.
nicoddemus commentedon Aug 27, 2015
I had trouble with this until recently at work, because we had a top-level
conftest.pywhich defined a few options, but if a user was in a different directory other than the root directory the options would not be available from the command-line (this withpytest-2.7.0, not sure if this has changed since then).jaraco commentedon Nov 3, 2015
Seems the aforementioned docs has moved
davehunt commentedon Dec 17, 2015
I'm seeing this issue with pytest ≥ 2.8.0 with a plugin (not a conftest.py). The plugin I'm using is pytest-variables, but pytest-html is also affected. The argument values appear to be used for determining the root directory.