• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1.. _auto_patch:
2
3Automatically find and patch file functions and modules
4=======================================================
5The ``fake_filesystem_unittest`` module automatically finds all real file
6functions and modules, and stubs them out with the fake file system functions and modules.
7The pyfakefs source code contains files that demonstrate this usage model:
8
9- ``example.py`` is the software under test. In production, it uses the
10  real file system.
11- ``example_test.py`` tests ``example.py``. During testing, the pyfakefs fake
12  file system is used by ``example_test.py`` and ``example.py`` alike.
13
14Software Under Test
15-------------------
16``example.py`` contains a few functions that manipulate files.  For instance:
17
18.. code:: python
19
20    def create_file(path):
21        '''Create the specified file and add some content to it.  Use the open()
22        built in function.
23
24        For example, the following file operations occur in the fake file system.
25        In the real file system, we would not even have permission to write /test:
26
27        >>> os.path.isdir('/test')
28        False
29        >>> os.mkdir('/test')
30        >>> os.path.isdir('/test')
31        True
32        >>> os.path.exists('/test/file.txt')
33        False
34        >>> create_file('/test/file.txt')
35        >>> os.path.exists('/test/file.txt')
36        True
37        >>> with open('/test/file.txt') as f:
38        ...     f.readlines()
39        ["This is test file '/test/file.txt'.\\n", 'It was created using the open() function.\\n']
40        '''
41        with open(path, 'w') as f:
42            f.write("This is test file '{}'.\n".format(path))
43            f.write("It was created using the open() function.\n")
44
45No functional code in ``example.py`` even hints at a fake file system. In
46production, ``create_file()`` invokes the real file functions ``open()`` and
47``write()``.
48
49Unit Tests and Doctests
50-----------------------
51``example_test.py`` contains unit tests for ``example.py``. ``example.py``
52contains the doctests, as you can see above.
53
54The module ``fake_filesystem_unittest`` contains code that finds all real file
55functions and modules, and stubs these out with the fake file system functions
56and modules:
57
58.. code:: python
59
60    import os
61    import unittest
62    from pyfakefs import fake_filesystem_unittest
63    # The module under test is example:
64    import example
65
66Doctests
67~~~~~~~~
68``example_test.py`` defines ``load_tests()``, which runs the doctests in
69``example.py``:
70
71.. code:: python
72
73    def load_tests(loader, tests, ignore):
74        '''Load the pyfakefs/example.py doctest tests into unittest.'''
75        return fake_filesystem_unittest.load_doctests(loader, tests, ignore, example)
76
77
78Everything, including all imported modules and the test, is stubbed out
79with the fake filesystem. Thus you can use familiar file functions like
80``os.mkdir()`` as part of your test fixture and they too will operate on the
81fake file system.
82
83Unit Test Class
84~~~~~~~~~~~~~~~
85Next comes the ``unittest`` test class.  This class is derived from
86``fake_filesystem_unittest.TestCase``, which is in turn derived from
87``unittest.TestClass``:
88
89.. code:: python
90
91    class TestExample(fake_filesystem_unittest.TestCase):
92
93        def setUp(self):
94            self.setUpPyfakefs()
95
96        def tearDown(self):
97            # It is no longer necessary to add self.tearDownPyfakefs()
98            pass
99
100        def test_create_file(self):
101            '''Test example.create_file()'''
102            # The os module has been replaced with the fake os module so all of the
103            # following occurs in the fake filesystem.
104            self.assertFalse(os.path.isdir('/test'))
105            os.mkdir('/test')
106            self.assertTrue(os.path.isdir('/test'))
107
108            self.assertFalse(os.path.exists('/test/file.txt'))
109            example.create_file('/test/file.txt')
110            self.assertTrue(os.path.exists('/test/file.txt'))
111
112        ...
113
114
115Just add ``self.setUpPyfakefs()`` in ``setUp()``. You need add nothing to
116``tearDown()``.  Write your tests as usual.  From ``self.setUpPyfakefs()`` to
117the end of your ``tearDown()`` method, all file operations will use the fake
118file system.
119