Skip to content

Commit 494ac28

Browse files
authored
Merge pull request #5250 from EvanKepner/master
Documentation: add setenv/delenv examples to monkeypatch docs
2 parents 58e6a09 + e668aaf commit 494ac28

File tree

3 files changed

+79
-3
lines changed

3 files changed

+79
-3
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ Endre Galaczi
8686
Eric Hunsberger
8787
Eric Siegerman
8888
Erik M. Bray
89+
Evan Kepner
8990
Fabien Zarifian
9091
Fabio Zadrozny
9192
Feng Ma

changelog/5250.doc.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Expand docs on use of ``setenv`` and ``delenv`` with ``monkeypatch``.

doc/en/monkeypatch.rst

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ and a discussion of its motivation.
1616

1717

1818
Simple example: monkeypatching functions
19-
---------------------------------------------------
19+
----------------------------------------
2020

2121
If you want to pretend that ``os.expanduser`` returns a certain
2222
directory, you can use the :py:meth:`monkeypatch.setattr` method to
@@ -38,8 +38,8 @@ Here our test function monkeypatches ``os.path.expanduser`` and
3838
then calls into a function that calls it. After the test function
3939
finishes the ``os.path.expanduser`` modification will be undone.
4040

41-
example: preventing "requests" from remote operations
42-
------------------------------------------------------
41+
Global patch example: preventing "requests" from remote operations
42+
------------------------------------------------------------------
4343

4444
If you want to prevent the "requests" library from performing http
4545
requests in all your tests, you can do::
@@ -81,6 +81,80 @@ so that any attempts within tests to create http requests will fail.
8181
See issue `#3290 <https://github.com/pytest-dev/pytest/issues/3290>`_ for details.
8282

8383

84+
Monkeypatching environment variables
85+
------------------------------------
86+
87+
If you are working with environment variables you often need to safely change the values
88+
or delete them from the system for testing purposes. ``Monkeypatch`` provides a mechanism
89+
to do this using the ``setenv`` and ``delenv`` method. Our example code to test:
90+
91+
.. code-block:: python
92+
93+
# contents of our original code file e.g. code.py
94+
import os
95+
96+
97+
def get_os_user_lower():
98+
"""Simple retrieval function.
99+
Returns lowercase USER or raises EnvironmentError."""
100+
username = os.getenv("USER")
101+
102+
if username is None:
103+
raise EnvironmentError("USER environment is not set.")
104+
105+
return username.lower()
106+
107+
There are two potential paths. First, the ``USER`` environment variable is set to a
108+
value. Second, the ``USER`` environment variable does not exist. Using ``monkeypatch``
109+
both paths can be safely tested without impacting the running environment:
110+
111+
.. code-block:: python
112+
113+
# contents of our test file e.g. test_code.py
114+
import pytest
115+
116+
117+
def test_upper_to_lower(monkeypatch):
118+
"""Set the USER env var to assert the behavior."""
119+
monkeypatch.setenv("USER", "TestingUser")
120+
assert get_os_user_lower() == "testinguser"
121+
122+
123+
def test_raise_exception(monkeypatch):
124+
"""Remove the USER env var and assert EnvironmentError is raised."""
125+
monkeypatch.delenv("USER", raising=False)
126+
127+
with pytest.raises(EnvironmentError):
128+
_ = get_os_user_lower()
129+
130+
This behavior can be be moved into ``fixture`` structures and shared across tests:
131+
132+
.. code-block:: python
133+
134+
import pytest
135+
136+
137+
@pytest.fixture
138+
def mock_env_user(monkeypatch):
139+
monkeypatch.setenv("USER", "TestingUser")
140+
141+
142+
@pytest.fixture
143+
def mock_env_missing(monkeypatch):
144+
monkeypatch.delenv("USER", raising=False)
145+
146+
147+
# Notice the tests reference the fixtures for mocks
148+
def test_upper_to_lower(mock_env_user):
149+
assert get_os_user_lower() == "testinguser"
150+
151+
152+
def test_raise_exception(mock_env_missing):
153+
with pytest.raises(EnvironmentError):
154+
_ = get_os_user_lower()
155+
156+
157+
84158
.. currentmodule:: _pytest.monkeypatch
85159

86160
API Reference

0 commit comments

Comments
 (0)