diff --git a/tests/doc.md b/tests/doc.md index 2ee31912..f3e3056b 100644 --- a/tests/doc.md +++ b/tests/doc.md @@ -381,6 +381,40 @@ Using the bytes encoding has the following limitations: valid `bytes` +### Setting and modifying environment variables + +The test suite supports setting or modifying environment variables for +individual test cases. This can be accomplished by adding a member dictionary +named `env` with the appropriate variable names and keys: +``` python +# -*- coding: utf-8 -*- + +from system_tests import CaseMeta, path + + +class AnInformativeName(metaclass=CaseMeta): + + env = { + "MYVAR": 26, + "USER": "foobar" + } + + # if you want a pristine environment, consisting only of MYVAR & USER, + # uncomment the following line: + # inherit_env = False + + # the rest of the test case follows +``` + +All commands belonging to this test case will be run with a modified environment +where the variables `MYVAR` and `USER` will be set to the specified +values. By default the environment is inherited from the user's environment and +the specified variables in `env` take precedence over the variables in the +user's environment (in the above example the variable `$USER` would be +overridden). If no variables should be inherited set `inherit_env` to `False` +and your test case will get only the specified environment variables. + + ### Creating file copies For tests that modify their input file it is useful to run these with a diff --git a/tests/system_tests.py b/tests/system_tests.py index ab5e615b..084f00c6 100644 --- a/tests/system_tests.py +++ b/tests/system_tests.py @@ -535,6 +535,7 @@ def test_run(self): _cmd_splitter(command), stdout=subprocess.PIPE, stderr=subprocess.PIPE, + env=self._get_env(), cwd=self.work_dir, shell=_SUBPROCESS_SHELL ) @@ -611,6 +612,8 @@ class Case(unittest.TestCase): #: the first encoding that does not raise a UnicodeError is used encodings = ['utf-8', 'iso-8859-1'] + inherit_env = True + @classmethod def setUpClass(cls): """ @@ -619,6 +622,27 @@ class Case(unittest.TestCase): """ cls.work_dir = os.path.dirname(inspect.getfile(cls)) + def _get_env(self): + """ Return an appropriate env value for subprocess.Popen. + + This function returns either an appropriately populated dictionary or + None (the latter if this class has no attribute env). If a dictionary + is returned, then it will be either exactly self.env (when inherit_env + is False) or a copy of the current environment merged with self.env + (the values from self.env take precedence). + """ + if not hasattr(self, "env"): + return None + + if not self.inherit_env: + return self.env + + env_copy = os.environ.copy() + for key in self.env: + env_copy[key] = self.env[key] + + return env_copy + def _compare_output(self, i, command, got, expected, msg=None): """ Compares the expected and actual output of a test case. """ if isinstance(got, bytes):