Skip to content

Commit

Permalink
Merge pull request #1667 from fengxx/feature/override_ini_option
Browse files Browse the repository at this point in the history
Add --overwrite-ini ININAME=INIVALUE cli option
  • Loading branch information
hpk42 authored Jun 25, 2016
2 parents 13a188f + 856e6ca commit 68bed00
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 8 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ Samuele Pedroni
Steffen Allner
Stephan Obermann
Tareq Alayan
Ted Xiao
Simon Gomizelj
Stefano Taschini
Stefan Farmbauer
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@
finalizer and has access to the fixture's result cache.
Thanks `@d6e`_, `@sallner`_

* New cli flag ``--override-ini`` or ``-o`` that overrides values from the ini file.
Example '-o xfail_strict=True'. A complete ini-options can be viewed
by py.test --help. Thanks `@blueyed`_ and `@fengxx`_ for the PR


**Changes**

Expand Down Expand Up @@ -155,6 +159,8 @@
.. _@nikratio: https://github.com/nikratio
.. _@RedBeardCode: https://github.com/RedBeardCode
.. _@Vogtinator: https://github.com/Vogtinator
.. _@blueyed: https://github.com/blueyed
.. _@fengxx: https://github.com/fengxx

* Fix `#1421`_: Exit tests if a collection error occurs and add
``--continue-on-collection-errors`` option to restore previous behaviour.
Expand Down
32 changes: 24 additions & 8 deletions _pytest/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -1003,14 +1003,16 @@ def _getini(self, name):
description, type, default = self._parser._inidict[name]
except KeyError:
raise ValueError("unknown configuration value: %r" %(name,))
try:
value = self.inicfg[name]
except KeyError:
if default is not None:
return default
if type is None:
return ''
return []
value = self._get_override_ini_value(name)
if value is None:
try:
value = self.inicfg[name]
except KeyError:
if default is not None:
return default
if type is None:
return ''
return []
if type == "pathlist":
dp = py.path.local(self.inicfg.config.path).dirpath()
l = []
Expand Down Expand Up @@ -1041,6 +1043,20 @@ def _getconftest_pathlist(self, name, path):
l.append(relroot)
return l

def _get_override_ini_value(self, name):
value = None
# override_ini is a list of list, to support both -o foo1=bar1 foo2=bar2 and
# and -o foo1=bar1 -o foo2=bar2 options
# always use the last item if multiple value set for same ini-name,
# e.g. -o foo=bar1 -o foo=bar2 will set foo to bar2
if self.getoption("override_ini", None):
for ini_config_list in self.option.override_ini:
for ini_config in ini_config_list:
(key, user_ini_value) = ini_config.split("=", 1)
if key == name:
value = user_ini_value
return value

def getoption(self, name, default=notset, skip=False):
""" return command line option value.
Expand Down
4 changes: 4 additions & 0 deletions _pytest/helpconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ def pytest_addoption(parser):
group.addoption('--debug',
action="store_true", dest="debug", default=False,
help="store internal tracing debug information in 'pytestdebug.log'.")
# support for "--overwrite-ini ININAME=INIVALUE" to override values from the ini file
# Example '-o xfail_strict=True'.
group._addoption('-o', '--override-ini', nargs='*', dest="override_ini", action="append",
help="overrides ini values which do not have a separate command-line flag")


@pytest.hookimpl(hookwrapper=True)
Expand Down
89 changes: 89 additions & 0 deletions testing/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -583,3 +583,92 @@ def test_with_specific_inifile(self, tmpdir):
inifile = tmpdir.ensure("pytest.ini")
rootdir, inifile, inicfg = determine_setup(inifile, [tmpdir])
assert rootdir == tmpdir

class TestOverrideIniArgs:
""" test --override-ini """
@pytest.mark.parametrize("name", "setup.cfg tox.ini pytest.ini".split())
def test_override_ini_names(self, testdir, name):
testdir.tmpdir.join(name).write(py.std.textwrap.dedent("""
[pytest]
custom = 1.0
"""))
testdir.makeconftest("""
def pytest_addoption(parser):
parser.addini("custom", "")
""")
testdir.makepyfile("""
def test_pass(pytestconfig):
ini_val = pytestconfig.getini("custom")
print('\\ncustom_option:%s\\n' % ini_val)
""")

result = testdir.runpytest("--override-ini", "custom=2.0", "-s")
assert result.ret == 0
result.stdout.fnmatch_lines([
"custom_option:2.0"
])

result = testdir.runpytest("--override-ini", "custom=2.0",
"--override-ini=custom=3.0", "-s")
assert result.ret == 0
result.stdout.fnmatch_lines([
"custom_option:3.0"
])


def test_override_ini_pathlist(self, testdir):
testdir.makeconftest("""
def pytest_addoption(parser):
parser.addini("paths", "my new ini value", type="pathlist")
""")
testdir.makeini("""
[pytest]
paths=blah.py
""")
testdir.makepyfile("""
import py.path
def test_pathlist(pytestconfig):
config_paths = pytestconfig.getini("paths")
print(config_paths)
for cpf in config_paths:
print('\\nuser_path:%s' % cpf.basename)
""")
result = testdir.runpytest("--override-ini", 'paths=foo/bar1.py foo/bar2.py', "-s")
result.stdout.fnmatch_lines([
"user_path:bar1.py",
"user_path:bar2.py"
])

def test_override_multiple_and_default(self, testdir):
testdir.makeconftest("""
def pytest_addoption(parser):
parser.addini("custom_option_1", "", default="o1")
parser.addini("custom_option_2", "", default="o2")
parser.addini("custom_option_3", "", default=False, type="bool")
parser.addini("custom_option_4", "", default=True, type="bool")
""")
testdir.makeini("""
[pytest]
custom_option_1=custom_option_1
custom_option_2=custom_option_2
""")
testdir.makepyfile("""
def test_multiple_options(pytestconfig):
prefix="custom_option"
for x in range(1,5):
ini_value=pytestconfig.getini("%s_%d" % (prefix, x))
print('\\nini%d:%s' % (x, ini_value))
""")
result = testdir.runpytest("--override-ini",
'custom_option_1=fulldir=/tmp/user1',
'custom_option_2=url=/tmp/user2?a=b&d=e',
"-o", 'custom_option_3=True',
"-o", 'custom_option_4=no',
"-s")
result.stdout.fnmatch_lines([
"ini1:fulldir=/tmp/user1",
"ini2:url=/tmp/user2?a=b&d=e",
"ini3:True",
"ini4:False"
])

0 comments on commit 68bed00

Please sign in to comment.