-
-
Notifications
You must be signed in to change notification settings - Fork 310
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow override_config for pytest (#338)
* provides: base override class; unittest and pytest overrides * raise invalid config error earlier * update AUTHORS * avoid AttributeError * fix comment * add tests * fix tests, update docstring * update docs, improve tests * fix docs * fix markdown * refactor pytest override, use hidden fixture, refactor base and unittest classes * improve docstring and error * refactor pytest override to use hooks * set minimum pytest version * revert empty lines removal * introduce pytest test runner for package, refactoring * WIP * Finalize tox config, refactor docs, add global fixture * skip py35 * pytest command: remove unnecessary ignore * address comments * Update constance/test/pytest.py * address comments * add test for checking nested markers Co-authored-by: Camilo Nova <[email protected]> Co-authored-by: Paweł Zarębski <[email protected]>
- Loading branch information
1 parent
4de4114
commit bd8041c
Showing
10 changed files
with
247 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
[run] | ||
source = constance | ||
branch = 1 | ||
omit = | ||
*/pytest.py | ||
|
||
[report] | ||
omit = *tests*,*migrations* | ||
omit = *tests*,*migrations*,.tox/*,setup.py,*settings.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,6 +40,7 @@ saw2th <[email protected]> | |
trbs <[email protected]> | ||
vl <[email protected]> | ||
vl <vl@u64.(none)> | ||
Vladas Tamoshaitis <[email protected]> | ||
Dmitriy Tatarkin <[email protected]> | ||
Alexandr Artemyev <[email protected]> | ||
Elisey Zanko <[email protected]> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
from .utils import override_config | ||
from .unittest import override_config # pragma: no cover |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
""" | ||
Pytest constance override config plugin. | ||
Inspired by https://github.com/pytest-dev/pytest-django/. | ||
""" | ||
import pytest | ||
from contextlib import ContextDecorator | ||
from constance import config as constance_config | ||
|
||
|
||
@pytest.hookimpl(trylast=True) | ||
def pytest_configure(config): # pragma: no cover | ||
""" | ||
Register override_config marker. | ||
""" | ||
config.addinivalue_line( | ||
"markers", | ||
( | ||
"override_config(**kwargs): " | ||
"mark test to override django-constance config" | ||
) | ||
) | ||
|
||
|
||
@pytest.hookimpl(hookwrapper=True) | ||
def pytest_runtest_call(item): # pragma: no cover | ||
""" | ||
Validate constance override marker params. Run test with overrided config. | ||
""" | ||
marker = item.get_closest_marker("override_config") | ||
if marker is not None: | ||
if marker.args: | ||
pytest.fail( | ||
"Constance override can not not accept positional args" | ||
) | ||
with override_config(**marker.kwargs): | ||
yield | ||
else: | ||
yield | ||
|
||
|
||
class override_config(ContextDecorator): | ||
""" | ||
Override config while running test function. | ||
Act as context manager and decorator. | ||
""" | ||
def enable(self): | ||
""" | ||
Store original config values and set overridden values. | ||
""" | ||
for key, value in self._to_override.items(): | ||
self._original_values[key] = getattr(constance_config, key) | ||
setattr(constance_config, key, value) | ||
|
||
def disable(self): | ||
""" | ||
Set original values to the config. | ||
""" | ||
for key, value in self._original_values.items(): | ||
setattr(constance_config, key, value) | ||
|
||
def __init__(self, **kwargs): | ||
self._to_override = kwargs.copy() | ||
self._original_values = {} | ||
|
||
def __enter__(self): | ||
self.enable() | ||
|
||
def __exit__(self, exc_type, exc_val, exc_tb): | ||
self.disable() | ||
|
||
|
||
@pytest.fixture(name="override_config") | ||
def _override_config(): | ||
""" | ||
Make override_config available as a function fixture. | ||
""" | ||
return override_config |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import unittest | ||
|
||
|
||
try: | ||
import pytest | ||
|
||
from constance import config | ||
from constance.test.pytest import override_config | ||
|
||
|
||
class TestPytestOverrideConfigFunctionDecorator: | ||
"""Test that the override_config decorator works correctly for Pytest classes. | ||
Test usage of override_config on test method and as context manager. | ||
""" | ||
|
||
def test_default_value_is_true(self): | ||
"""Assert that the default value of config.BOOL_VALUE is True.""" | ||
assert config.BOOL_VALUE | ||
|
||
@pytest.mark.override_config(BOOL_VALUE=False) | ||
def test_override_config_on_method_changes_config_value(self): | ||
"""Assert that the pytest mark decorator changes config.BOOL_VALUE.""" | ||
assert not config.BOOL_VALUE | ||
|
||
def test_override_config_as_context_manager_changes_config_value(self): | ||
"""Assert that the context manager changes config.BOOL_VALUE.""" | ||
with override_config(BOOL_VALUE=False): | ||
assert not config.BOOL_VALUE | ||
|
||
assert config.BOOL_VALUE | ||
|
||
@override_config(BOOL_VALUE=False) | ||
def test_method_decorator(self): | ||
"""Ensure `override_config` can be used as test method decorator.""" | ||
assert not config.BOOL_VALUE | ||
|
||
|
||
@pytest.mark.override_config(BOOL_VALUE=False) | ||
class TestPytestOverrideConfigDecorator: | ||
"""Test that the override_config decorator works on classes.""" | ||
|
||
def test_override_config_on_class_changes_config_value(self): | ||
"""Asser that the class decorator changes config.BOOL_VALUE.""" | ||
assert not config.BOOL_VALUE | ||
|
||
@pytest.mark.override_config(BOOL_VALUE='True') | ||
def test_override_config_on_overrided_value(self): | ||
"""Ensure that method mark decorator changes already overrided value for class.""" | ||
assert config.BOOL_VALUE == 'True' | ||
|
||
|
||
def test_fixture_override_config(override_config): | ||
""" | ||
Ensure `override_config` fixture is available globally | ||
and can be used in test functions. | ||
""" | ||
with override_config(BOOL_VALUE=False): | ||
assert not config.BOOL_VALUE | ||
|
||
@override_config(BOOL_VALUE=False) | ||
def test_func_decorator(): | ||
"""Ensure `override_config` can be used as test function decorator.""" | ||
assert not config.BOOL_VALUE | ||
|
||
except ImportError: | ||
pass | ||
|
||
|
||
class PytestTests(unittest.TestCase): | ||
def setUp(self): | ||
self.skipTest('Skip all pytest tests when using unittest') | ||
|
||
def test_do_not_skip_silently(self): | ||
""" | ||
If no at least one test present, unittest silently skips module. | ||
""" | ||
pass |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters