Skip to content

Commit

Permalink
Merge pull request #5250 from EvanKepner/master
Browse files Browse the repository at this point in the history
Documentation: add setenv/delenv examples to monkeypatch docs
  • Loading branch information
nicoddemus authored May 15, 2019
2 parents 58e6a09 + e668aaf commit 494ac28
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 3 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ Endre Galaczi
Eric Hunsberger
Eric Siegerman
Erik M. Bray
Evan Kepner
Fabien Zarifian
Fabio Zadrozny
Feng Ma
Expand Down
1 change: 1 addition & 0 deletions changelog/5250.doc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Expand docs on use of ``setenv`` and ``delenv`` with ``monkeypatch``.
80 changes: 77 additions & 3 deletions doc/en/monkeypatch.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ and a discussion of its motivation.


Simple example: monkeypatching functions
---------------------------------------------------
----------------------------------------

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

example: preventing "requests" from remote operations
------------------------------------------------------
Global patch example: preventing "requests" from remote operations
------------------------------------------------------------------

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


Monkeypatching environment variables
------------------------------------

If you are working with environment variables you often need to safely change the values
or delete them from the system for testing purposes. ``Monkeypatch`` provides a mechanism
to do this using the ``setenv`` and ``delenv`` method. Our example code to test:

.. code-block:: python
# contents of our original code file e.g. code.py
import os
def get_os_user_lower():
"""Simple retrieval function.
Returns lowercase USER or raises EnvironmentError."""
username = os.getenv("USER")
if username is None:
raise EnvironmentError("USER environment is not set.")
return username.lower()
There are two potential paths. First, the ``USER`` environment variable is set to a
value. Second, the ``USER`` environment variable does not exist. Using ``monkeypatch``
both paths can be safely tested without impacting the running environment:

.. code-block:: python
# contents of our test file e.g. test_code.py
import pytest
def test_upper_to_lower(monkeypatch):
"""Set the USER env var to assert the behavior."""
monkeypatch.setenv("USER", "TestingUser")
assert get_os_user_lower() == "testinguser"
def test_raise_exception(monkeypatch):
"""Remove the USER env var and assert EnvironmentError is raised."""
monkeypatch.delenv("USER", raising=False)
with pytest.raises(EnvironmentError):
_ = get_os_user_lower()
This behavior can be be moved into ``fixture`` structures and shared across tests:

.. code-block:: python
import pytest
@pytest.fixture
def mock_env_user(monkeypatch):
monkeypatch.setenv("USER", "TestingUser")
@pytest.fixture
def mock_env_missing(monkeypatch):
monkeypatch.delenv("USER", raising=False)
# Notice the tests reference the fixtures for mocks
def test_upper_to_lower(mock_env_user):
assert get_os_user_lower() == "testinguser"
def test_raise_exception(mock_env_missing):
with pytest.raises(EnvironmentError):
_ = get_os_user_lower()
.. currentmodule:: _pytest.monkeypatch

API Reference
Expand Down

0 comments on commit 494ac28

Please sign in to comment.