Skip to content

Commit

Permalink
Merge pull request #7 from zopefoundation/doctestcase-__file__
Browse files Browse the repository at this point in the history
Make sure Doctestcase   __file__  attributes start with 'test'
  • Loading branch information
jimfulton committed Aug 31, 2015
2 parents 48015fe + eb38c30 commit 8a25562
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 17 deletions.
3 changes: 2 additions & 1 deletion CHANGES.rst
Expand Up @@ -4,7 +4,8 @@ Changes
- Added meta data for test case methods created with
``zope.testing.doctestcase``.

- Reasonable values for __name__
- Reasonable values for ``__name__``, making sure that ``__name__``
starts with ``test``.

- For ``doctestfile`` methods, provide ``filename`` and ``filepath``
attributes.
Expand Down
16 changes: 11 additions & 5 deletions src/zope/testing/doctestcase.py
Expand Up @@ -108,6 +108,11 @@ def test4(self):

_parser = doctest.DocTestParser()

def _testify(name):
if not name.startswith('test'):
name = 'test_' + name
return name

def doctestmethod(test=None, optionflags=0, checker=None):
"""Define a doctest from a method within a unittest.TestCase.
Expand Down Expand Up @@ -146,7 +151,7 @@ def test_method(self):
_run_test(self, doc, fglobs.copy(), name, path,
optionflags, checker, lineno=lineno)

test_method.__name__ = name
test_method.__name__ = _testify(name)

return test_method

Expand All @@ -168,12 +173,13 @@ def test_string(self):
_run_test(self, test, fglobs.copy(), '<string>', '<string>',
optionflags, checker)
if name:
test_string.__name__ = name
test_string.__name__ = _testify(name)

return test_string

string = docteststring

_not_word = re.compile('\W')
def doctestfile(path, optionflags=0, checker=None):
"""Define a doctest from a test file within a unittest.TestCase.
Expand Down Expand Up @@ -207,15 +213,15 @@ def test_file_w_setup(self):
setup(self)
_run_test(self, test, {}, name, path, optionflags, checker,
'test')
test_file_w_setup.__name__ = setup.__name__
test_file_w_setup.__name__ = _testify(setup.__name__)
test_file_w_setup.filepath = path
test_file_w_setup.filename = os.path.basename(path)
return test_file_w_setup

_run_test(self, test, {}, name, path, optionflags, checker, 'test')

test_file.__name__ = os.path.splitext(
os.path.basename(path))[0].replace('-', '_')
test_file.__name__ = _testify(
_not_word.sub('_', os.path.splitext(os.path.basename(path))[0]))
test_file.filepath = path
test_file.filename = os.path.basename(path)

Expand Down
50 changes: 43 additions & 7 deletions src/zope/testing/doctestcase.txt
Expand Up @@ -137,22 +137,32 @@ The constructors accept standard doctest ``optionflags`` and
Note that the doctest IGNORE_EXCEPTION_DETAIL option flag is
added to optionflags.

When using ``doctestfile``, ``filename`` and ``filepath`` attributes
are available that contain the test file name and full path.

``__name__`` attributes of class members
----------------------------------------

Class members have ``__name__`` attributes set as follows:

- When using ``doctestmethod`` or ``doctestfile`` with a setup
function, ``__name__`` attribute is set to the name of the function.
A ``test_`` prefix is added, if the name doesn't start with ``test``.

- When doctestfile is used without a setup function, ``__name__`` is
set to the last part of the file path with the extension removed and
hyphens converted to underscores. For example, with a test path of
``'/foo/bar/test-it.rst'``, the ``__name__`` attribute is set to
``'test_it'``.
non-word characters converted to underscores. For example, with a
test path of ``'/foo/bar/test-it.rst'``, the ``__name__`` attribute
is set to ``'test_it'``. A ``test_`` prefix is added, if the name
doesn't start with ``test``.

- when using ``docteststring``, a ``name`` option can be passed in
to set ``__name__``.
- when using ``docteststring``, a ``name`` option can be passed in to
set ``__name__``. A ``test_`` prefix is added, if the name doesn't
start with ``test``.

When using ``doctestfile``, ``filename`` and ``filepath`` attributes
are available that contain the test file name and full path.
The ``__name__`` attribute is important when using nose, because nose
discovers tests as class members using their ``__name__`` attributes,
whereas the unittest and py.test test runners use class dictionary keys.

.. Let's look at some failure cases:

Expand Down Expand Up @@ -266,3 +276,29 @@ are available that contain the test file name and full path.
test2 (tests.MyTest) ... ok
test3 (tests.MyTest) ... ok
test4 (tests.MyTest) ... ok

.. test __name__ variations

>>> class MyTest(unittest.TestCase):
...
... foo = doctestcase.string('''>>> 1''', name='foo')
...
... @doctestcase.method
... def bar(self):
... '''
... >>> self.x
... 3
... '''
... @doctestcase.file('test4f.txt')
... def baz(self):
... pass
... wait = doctestcase.file('wait.txt')

>>> MyTest.foo.__name__
'test_foo'
>>> MyTest.bar.__name__
'test_bar'
>>> MyTest.baz.__name__
'test_baz'
>>> MyTest.wait.__name__
'test_wait'
8 changes: 4 additions & 4 deletions src/zope/testing/setupstack.txt
Expand Up @@ -206,16 +206,16 @@ A TestCase class is provided that:

In addition to a tearDown method, the class provides methods:

setupDirectory()
``setupDirectory()``
Creates a temporary directory, runs the test, and cleans it up.

register(func)
``register(func)``
Register a tear-down function.

context_manager(manager)
``context_manager(manager)``
Enters a context manager and exits it on tearDown.

mock(*args, **kw)
``mock(*args, **kw)``
Enters ``mock.patch`` with the given arguments.

This is syntactic sugur for::
Expand Down

0 comments on commit 8a25562

Please sign in to comment.