Skip to content

Commit 77104d6

Browse files
committed
add --override-ini option to overrides ini values
Signed-off-by: Ted Xiao <xiao.xj@gmail.com>
1 parent f2bb3df commit 77104d6

File tree

6 files changed

+131
-8
lines changed

6 files changed

+131
-8
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ Ryan Wooden
9898
Samuele Pedroni
9999
Stephan Obermann
100100
Tareq Alayan
101+
Ted Xiao
101102
Simon Gomizelj
102103
Stefano Taschini
103104
Stefan Farmbauer

CHANGELOG.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@
4747
`#1629`_. Thanks `@obestwalter`_ and `@davehunt`_ for the complete PR
4848
(`#1633`_)
4949

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

5257
* Fixtures marked with ``@pytest.fixture`` can now use ``yield`` statements exactly like

_pytest/config.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,14 +1003,16 @@ def _getini(self, name):
10031003
description, type, default = self._parser._inidict[name]
10041004
except KeyError:
10051005
raise ValueError("unknown configuration value: %r" %(name,))
1006-
try:
1007-
value = self.inicfg[name]
1008-
except KeyError:
1009-
if default is not None:
1010-
return default
1011-
if type is None:
1012-
return ''
1013-
return []
1006+
value = self._get_override_ini_value(name)
1007+
if value is None:
1008+
try:
1009+
value = self.inicfg[name]
1010+
except KeyError:
1011+
if default is not None:
1012+
return default
1013+
if type is None:
1014+
return ''
1015+
return []
10141016
if type == "pathlist":
10151017
dp = py.path.local(self.inicfg.config.path).dirpath()
10161018
l = []
@@ -1041,6 +1043,14 @@ def _getconftest_pathlist(self, name, path):
10411043
l.append(relroot)
10421044
return l
10431045

1046+
def _get_override_ini_value(self, name):
1047+
if self.getoption("override_ini", None):
1048+
for ini_config in self.option.override_ini:
1049+
(key, user_ini_value) = ini_config.split("=", 1)
1050+
if key == name:
1051+
return user_ini_value
1052+
return None
1053+
10441054
def getoption(self, name, default=notset, skip=False):
10451055
""" return command line option value.
10461056

_pytest/helpconfig.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ def pytest_addoption(parser):
2020
group.addoption('--debug',
2121
action="store_true", dest="debug", default=False,
2222
help="store internal tracing debug information in 'pytestdebug.log'.")
23+
# support for "--overwrite-ini ININAME=INIVALUE" to override values from the ini file
24+
# Example '-o xfail_strict=True'.
25+
group._addoption('-o', '--override-ini', nargs='*', dest="override_ini",
26+
help="overrides ini values which do not have a separate command-line flag")
2327

2428

2529
@pytest.hookimpl(hookwrapper=True)

testing/test_config.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,3 +583,93 @@ def test_with_specific_inifile(self, tmpdir):
583583
inifile = tmpdir.ensure("pytest.ini")
584584
rootdir, inifile, inicfg = determine_setup(inifile, [tmpdir])
585585
assert rootdir == tmpdir
586+
587+
class TestOverrideIniArgs:
588+
""" test --override-ini """
589+
@pytest.mark.parametrize("name", "setup.cfg tox.ini pytest.ini".split())
590+
def test_override_ini_names(self, testdir, name):
591+
testdir.tmpdir.join(name).write(py.std.textwrap.dedent("""
592+
[pytest]
593+
custom = 1.0
594+
"""))
595+
testdir.makeconftest("""
596+
def pytest_addoption(parser):
597+
parser.addini("custom", "")
598+
""")
599+
testdir.makepyfile("""
600+
def test_pass(pytestconfig):
601+
ini_val = pytestconfig.getini("custom")
602+
print('\\ncustom_option:%s\\n' % ini_val)
603+
""")
604+
605+
result = testdir.runpytest("--override-ini", "custom=2.0", "-s")
606+
assert result.ret == 0
607+
result.stdout.fnmatch_lines([
608+
"custom_option:2.0"
609+
])
610+
611+
result = testdir.runpytest("--override-ini", "custom=2.0",
612+
"--override-ini=custom=3.0", "-s")
613+
assert result.ret == 0
614+
result.stdout.fnmatch_lines([
615+
"custom_option:3.0"
616+
])
617+
618+
619+
def test_override_ini_pathlist(self, testdir):
620+
testdir.makeconftest("""
621+
def pytest_addoption(parser):
622+
parser.addini("paths", "my new ini value", type="pathlist")
623+
""")
624+
testdir.makeini("""
625+
[pytest]
626+
paths=blah.py
627+
""")
628+
testdir.makepyfile("""
629+
import py.path
630+
def test_pathlist(pytestconfig):
631+
config_paths = pytestconfig.getini("paths")
632+
print(config_paths)
633+
for cpf in config_paths:
634+
print('\\nuser_path:%s' % cpf.basename)
635+
""")
636+
result = testdir.runpytest("--override-ini", 'paths=foo/bar1.py foo/bar2.py', "-s")
637+
result.stdout.fnmatch_lines([
638+
"user_path:bar1.py",
639+
"user_path:bar2.py"
640+
])
641+
642+
def test_override_multiple_and_default(self, testdir):
643+
testdir.makeconftest("""
644+
def pytest_addoption(parser):
645+
parser.addini("custom_option_1", "", default="o1")
646+
parser.addini("custom_option_2", "", default="o2")
647+
parser.addini("custom_option_3", "", default=False, type="bool")
648+
parser.addini("custom_option_4", "", default=True, type="bool")
649+
650+
""")
651+
testdir.makeini("""
652+
[pytest]
653+
custom_option_1=custom_option_1
654+
custom_option_2=custom_option_2
655+
""")
656+
testdir.makepyfile("""
657+
def test_multiple_options(pytestconfig):
658+
prefix="custom_option"
659+
for x in range(1,5):
660+
ini_value=pytestconfig.getini("%s_%d" % (prefix, x))
661+
print('\\nini%d:%s' % (x, ini_value))
662+
""")
663+
result = testdir.runpytest("-o",
664+
'custom_option_1=fulldir=/tmp/user1',
665+
'custom_option_2=url=/tmp/user2?a=b&d=e',
666+
'custom_option_3=True',
667+
'custom_option_4=no',
668+
"-s")
669+
print result.stderr
670+
result.stdout.fnmatch_lines([
671+
"ini1:fulldir=/tmp/user1",
672+
"ini2:url=/tmp/user2?a=b&d=e",
673+
"ini3:True",
674+
"ini4:False"
675+
])

testing/test_terminal_io.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import pytest
2+
def test_color_yes(testdir):
3+
testdir.makepyfile("""
4+
import pytest
5+
import py.path
6+
def test_pathlist():
7+
pytest.set_trace()
8+
""")
9+
pytest.set_trace()
10+
result = testdir.runpytest()
11+
12+
assert 'test session starts' in result.stdout.str()
13+
assert '\x1b[1m' in result.stdout.str()

0 commit comments

Comments
 (0)