gocept.testing


Namegocept.testing JSON
Version 4.0 PyPI version JSON
download
home_pagehttps://github.com/minddistrict/gocept.testing
SummaryA collection of test helpers, additional assertions, and the like.
upload_time2024-05-21 13:03:02
maintainerNone
docs_urlNone
authorminddistrict <mail at minddistrict dot com>
requires_python>=3.9
licenseMIT
keywords testing unittest assertions
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            ==============
gocept.testing
==============

.. image:: https://github.com/minddistrict/gocept.testing/workflows/tests/badge.svg
    :target: https://github.com/minddistrict/gocept.testing/actions?query=workflow%3Atests

.. image:: https://coveralls.io/repos/github/minddistrict/gocept.testing/badge.svg
    :target: https://coveralls.io/github/minddistrict/gocept.testing


This package collects various helpers for writing tests.

.. contents::


assertEllipsis
==============

An assertion which is very helpful when using Testbrowser with
``unittest.TestCase`` (instead of ``doctest``).

Some examples::

    class MyTest(unittest.TestCase, gocept.testing.assertion.Ellipsis):
    # [...]


    self.assertEllipsis('...bar...', 'foo bar qux')
    # -> nothing happens

    self.assertEllipsis('foo', 'bar')
    # -> AssertionError: Differences (ndiff with -expected +actual):
         - foo
         + bar

    self.assertNotEllipsis('foo', 'foo')
    # -> AssertionError: "Value unexpectedly matches expression 'foo'."

To use, inherit from ``gocept.testing.assertion.Ellipsis`` in addition to
``unittest.TestCase``.


assertStartsWith, assertEndsWith
================================

::

    class MyTest(unittest.TestCase, gocept.testing.assertion.String):

        def test_something(self):
            self.assertStartsWith('foo', 'foobar') # --> pass
            self.assertEndsWith('bar', 'foobar') # --> pass
            self.assertStartsWith('qux', 'foobar') # --> fail
            self.assertEndsWith('qux', 'foobar') # --> fail


assertNothingRaised
===================

The opposite of assertRaises(), this is an assertion that makes some tests more
readable. As assertRaises(), it can be used as as context manager, too::

    class MyTest(unittest.TestCase, gocept.testing.assertion.Exceptions):
    # [...]

    self.assertNothingRaised(do_something, 1, 2, 3)

    with self.assertNothingRaised():
        do_something(1, 2, 3)


mock patch context
==================

``gocept.testing.mock.Patches`` collects `mock`_ patches that are valid for the
whole TestCase, and resets them all in one go in tearDown (this is pending
inclusion upstream as ``mock.patcher()``, see `issue 30`_)::

    class MyTest(unittest.TestCase):

        def setUp(self):
            self.patches = gocept.testing.mock.Patches()

        def tearDown(self):
            self.patches.reset()

        def test_something(self):
            compile = self.patches.add('re.compile')

It offers three methods:

:add: wraps ``mock.patch()``
:add_object: wraps ``mock.patch.object``
:add_dict: wraps ``mock.patch.dict``

Note that ``gocept.testing`` does not declare a dependency on ``mock`` to be as
lightweight as possible, so clients need to do that themselves.

If you want to save typing, you can mix ``gocept.testing.mock.PatchHelper``
into your TestCase, it defines a setUp method that instantiates ``Patches`` and
a tearDown that calls ``reset()`` on it.


.. _`mock`: http://www.voidspace.org.uk/python/mock/
.. _`issue 30`: http://code.google.com/p/mock/issues/detail?id=30


assertCalledWith
================

This is syntactic sugar around ``mock.assert_called_with``, so you can write::

    class MyTest(unittest.TestCase, gocept.testing.mock.Assertions):

        def test_something(self):
            dummy = mock.Mock()
            dummy(True)
            self.assertCalledWith(dummy, True)

instead of::

    dummy.assert_called_with(True)


Mocking properties
==================

``gocept.testing.mock.Property`` is syntactic sugar directly lifted from the
`mock documentation`_ that allows you to patch properties like this::

    class Dummy(object):

        @property
        def foo(self):
            return False


    with mock.patch('Dummy.foo', gocept.testing.mock.Property()) as foo:
        foo.return_value = 'something else'


.. _`mock documentation`: http://www.voidspace.org.uk/python/mock/examples.html


Attribute patch context
=======================

This has nothing to do with mocks, it's a convenience helper for setting and
automatically resetting attributes of objects::

    class MyTest(unittest.TestCase):

        def setUp(self):
            self.patches = gocept.testing.patch.Patches()
            self.subject = MyClass()

        def tearDown(self):
            self.patches.reset()

        def test_something(self):
            self.assertEqual('one', self.subject.foo)
            self.patches.set(self.subject, 'foo', 'two')
            self.assertEqual('two', self.subject.foo)


Method call patch context
=========================

This allows to call a method and reset it later on automatically. At the
moment, only methods that take a single parameter are supported, by passing in
both the old value (to which it should be reset) and the new value::

    class MyTest(unittest.TestCase):

        def setUp(self):
            self.patches = gocept.testing.patch.Patches()

        def tearDown(self):
            self.patches.reset()

        def test_something(self):
            self.patches.call(
                zope.component.hooks, 'setSite',
                zope.component.hooks.getSite(), new_site)


Dict patching context manager
=============================

``gocept.testing.patch.Dict`` is a context manager allowing to change values
in a dict. It restores the original dict at exit. E. g. it can be used to
temporarily change values in ``os.environ``::

    >>> with gocept.testing.patch.Dict(os.environ, foo='bar', qwe='asdf'):
            print os.environ.get('foo')
    bar
    >>> print os.environ.get('foo')
    None


Temporary directory
===================

``gocept.testing.fixture.TempDir`` encapsulates the common pattern to create a
temporary directory and delete it after the test has run. The name of the
directory is avaliable as ``self.tmpdir``. Note that since
``unittest.TestCase`` does not call `super`, you need to mix in ``TempDir``
first::

    class MyTest(gocept.testing.fixture.TempDir, unittest.TestCase):

        def test_something(self):
            self.assertTrue(os.path.isdir(self.tmpdir))


Comparing mtimes
================

``gocept.testing.mtime.Newer`` checks that generated files are at least as new
as their source counterparts (similar like ``make`` works)::

    class MyTest(gocept.testing.mtime.Newer, unittest.TestCase):

        source_ext = '.js'
        target_ext = '.min.js'
        message = 'run jsmin to correct this'

        def test_minified_js_files_are_younger_than_non_minified_ones(self):
            self.check_files(pkg_resources.resource_filename(
                'my.package', 'resources/js'))


Development
===========

The git repository of the source code as well as the issue tracker are
available at https://github.com/minddistrict/gocept.testing.


Changelog
=========

4.0 (2024-05-21)
----------------

Backwards incompatible changes
++++++++++++++++++++++++++++++

- Drop support for Python 3.7, 3.8.

Features
++++++++

- Add support for Python 3.11, 3.12 and 3.13 (as of beta 1).


3.0 (2021-08-26)
----------------

Backwards incompatible changes
++++++++++++++++++++++++++++++

- Change license form ZPL to MIT.

- Drop support for Python 2, 3.4, 3.5 and 3.6

Features
++++++++

- Add support for Python 3.8, 3.9 and 3.10 (as of rc.1).


2.0.post1 (2018-11-22)
----------------------

- Fix PyPI page rendering.


2.0 (2018-11-22)
----------------

- Drop Python 2.6 an 3.3 support.

- Add support for Python 3.6, 3.7, PyPy and PyPy3.

- Choose explicit ``[mock]`` extra to use ``gocept.testing.mock`` on Python <
  3.3.


1.11 (2016-01-18)
-----------------

- Fix homepage URL.

- Declare Python 3.4 and Python 3.5 support.

- Drop Python 3.2 support.


1.10.1 (2014-04-28)
-------------------

- Make ``assertNotEllipsis()`` compatible with `py.test`.

- Declare Python 3.3 support.


1.10 (2014-02-13)
-----------------

- Remove ``retry`` decorator, it is rather useless since it does not take
  setUp/tearDown into account.


1.9 (2013-12-20)
----------------

- Add ``retry`` decorator that runs flaky tests several times and only fails
  when they fail each time.

- Use py.test instead of zope.testrunner for this package's own tests.


1.8 (2013-07-17)
----------------

- Python 3 compatibility.
- Depend on setuptools rather than distribute now that the projects have
  merged.
- Use current buildout and recipes for development.


1.7 (2013-04-18)
----------------

- Fix Python-2.6 compatibility of our own test suite.
- Introduce ``PatchHelper``.


1.6.0 (2013-01-07)
------------------

- Add newer mtime check.


1.5.2 (2012-09-14)
------------------

- ``.patch.Dict`` did not restore the keys if an exception occured while the
  `with` call.


1.5.1 (2012-09-12)
------------------

- Fixed documentation and faulty 1.5 release.


1.5 (2012-07-10)
----------------

- Add ``.patch.Dict``, a dict patching context manager.


1.4 (2012-06-04)
----------------

- Add ``TempDir`` fixture.
- Add ``assertStartsWith``, ``assertEndsWith``.


1.3.2 (2012-05-09)
------------------

- Allow ``assertEllipsis`` to work with mixed unicode/bytes argument
  (assuming the bytes are UTF-8, as they are with zope.testbrowser).


1.3.1 (2012-02-03)
------------------

- Display original traceback in ``assertNothingRaised``.


1.3 (2011-12-16)
----------------

- Add patch helper for attributes and simple callables.


1.2.1 (2011-12-09)
------------------

- Make Python-3 compatible (at least syntactically).


1.2 (2011-12-09)
----------------

- Add Patches context for mock (upstream implementation pending,
  see <http://code.google.com/p/mock/issues/detail?id=30>)
- Add ``assertCalledWith``.
- Add ``mock.Property``.


1.1 (2011-11-10)
----------------

- Add ``assertNothingRaised``.


1.0 (2011-11-02)
----------------

- first release: ``assertEllipsis``

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/minddistrict/gocept.testing",
    "name": "gocept.testing",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "testing unittest assertions",
    "author": "minddistrict <mail at minddistrict dot com>",
    "author_email": "mail@minddistrict.com",
    "download_url": "https://files.pythonhosted.org/packages/3a/a5/c6ef2ae0e96fcecb40dc24247726e8ec3a1cfcbc12a9e4713c5274529e59/gocept.testing-4.0.tar.gz",
    "platform": null,
    "description": "==============\ngocept.testing\n==============\n\n.. image:: https://github.com/minddistrict/gocept.testing/workflows/tests/badge.svg\n    :target: https://github.com/minddistrict/gocept.testing/actions?query=workflow%3Atests\n\n.. image:: https://coveralls.io/repos/github/minddistrict/gocept.testing/badge.svg\n    :target: https://coveralls.io/github/minddistrict/gocept.testing\n\n\nThis package collects various helpers for writing tests.\n\n.. contents::\n\n\nassertEllipsis\n==============\n\nAn assertion which is very helpful when using Testbrowser with\n``unittest.TestCase`` (instead of ``doctest``).\n\nSome examples::\n\n    class MyTest(unittest.TestCase, gocept.testing.assertion.Ellipsis):\n    # [...]\n\n\n    self.assertEllipsis('...bar...', 'foo bar qux')\n    # -> nothing happens\n\n    self.assertEllipsis('foo', 'bar')\n    # -> AssertionError: Differences (ndiff with -expected +actual):\n         - foo\n         + bar\n\n    self.assertNotEllipsis('foo', 'foo')\n    # -> AssertionError: \"Value unexpectedly matches expression 'foo'.\"\n\nTo use, inherit from ``gocept.testing.assertion.Ellipsis`` in addition to\n``unittest.TestCase``.\n\n\nassertStartsWith, assertEndsWith\n================================\n\n::\n\n    class MyTest(unittest.TestCase, gocept.testing.assertion.String):\n\n        def test_something(self):\n            self.assertStartsWith('foo', 'foobar') # --> pass\n            self.assertEndsWith('bar', 'foobar') # --> pass\n            self.assertStartsWith('qux', 'foobar') # --> fail\n            self.assertEndsWith('qux', 'foobar') # --> fail\n\n\nassertNothingRaised\n===================\n\nThe opposite of assertRaises(), this is an assertion that makes some tests more\nreadable. As assertRaises(), it can be used as as context manager, too::\n\n    class MyTest(unittest.TestCase, gocept.testing.assertion.Exceptions):\n    # [...]\n\n    self.assertNothingRaised(do_something, 1, 2, 3)\n\n    with self.assertNothingRaised():\n        do_something(1, 2, 3)\n\n\nmock patch context\n==================\n\n``gocept.testing.mock.Patches`` collects `mock`_ patches that are valid for the\nwhole TestCase, and resets them all in one go in tearDown (this is pending\ninclusion upstream as ``mock.patcher()``, see `issue 30`_)::\n\n    class MyTest(unittest.TestCase):\n\n        def setUp(self):\n            self.patches = gocept.testing.mock.Patches()\n\n        def tearDown(self):\n            self.patches.reset()\n\n        def test_something(self):\n            compile = self.patches.add('re.compile')\n\nIt offers three methods:\n\n:add: wraps ``mock.patch()``\n:add_object: wraps ``mock.patch.object``\n:add_dict: wraps ``mock.patch.dict``\n\nNote that ``gocept.testing`` does not declare a dependency on ``mock`` to be as\nlightweight as possible, so clients need to do that themselves.\n\nIf you want to save typing, you can mix ``gocept.testing.mock.PatchHelper``\ninto your TestCase, it defines a setUp method that instantiates ``Patches`` and\na tearDown that calls ``reset()`` on it.\n\n\n.. _`mock`: http://www.voidspace.org.uk/python/mock/\n.. _`issue 30`: http://code.google.com/p/mock/issues/detail?id=30\n\n\nassertCalledWith\n================\n\nThis is syntactic sugar around ``mock.assert_called_with``, so you can write::\n\n    class MyTest(unittest.TestCase, gocept.testing.mock.Assertions):\n\n        def test_something(self):\n            dummy = mock.Mock()\n            dummy(True)\n            self.assertCalledWith(dummy, True)\n\ninstead of::\n\n    dummy.assert_called_with(True)\n\n\nMocking properties\n==================\n\n``gocept.testing.mock.Property`` is syntactic sugar directly lifted from the\n`mock documentation`_ that allows you to patch properties like this::\n\n    class Dummy(object):\n\n        @property\n        def foo(self):\n            return False\n\n\n    with mock.patch('Dummy.foo', gocept.testing.mock.Property()) as foo:\n        foo.return_value = 'something else'\n\n\n.. _`mock documentation`: http://www.voidspace.org.uk/python/mock/examples.html\n\n\nAttribute patch context\n=======================\n\nThis has nothing to do with mocks, it's a convenience helper for setting and\nautomatically resetting attributes of objects::\n\n    class MyTest(unittest.TestCase):\n\n        def setUp(self):\n            self.patches = gocept.testing.patch.Patches()\n            self.subject = MyClass()\n\n        def tearDown(self):\n            self.patches.reset()\n\n        def test_something(self):\n            self.assertEqual('one', self.subject.foo)\n            self.patches.set(self.subject, 'foo', 'two')\n            self.assertEqual('two', self.subject.foo)\n\n\nMethod call patch context\n=========================\n\nThis allows to call a method and reset it later on automatically. At the\nmoment, only methods that take a single parameter are supported, by passing in\nboth the old value (to which it should be reset) and the new value::\n\n    class MyTest(unittest.TestCase):\n\n        def setUp(self):\n            self.patches = gocept.testing.patch.Patches()\n\n        def tearDown(self):\n            self.patches.reset()\n\n        def test_something(self):\n            self.patches.call(\n                zope.component.hooks, 'setSite',\n                zope.component.hooks.getSite(), new_site)\n\n\nDict patching context manager\n=============================\n\n``gocept.testing.patch.Dict`` is a context manager allowing to change values\nin a dict. It restores the original dict at exit. E. g. it can be used to\ntemporarily change values in ``os.environ``::\n\n    >>> with gocept.testing.patch.Dict(os.environ, foo='bar', qwe='asdf'):\n            print os.environ.get('foo')\n    bar\n    >>> print os.environ.get('foo')\n    None\n\n\nTemporary directory\n===================\n\n``gocept.testing.fixture.TempDir`` encapsulates the common pattern to create a\ntemporary directory and delete it after the test has run. The name of the\ndirectory is avaliable as ``self.tmpdir``. Note that since\n``unittest.TestCase`` does not call `super`, you need to mix in ``TempDir``\nfirst::\n\n    class MyTest(gocept.testing.fixture.TempDir, unittest.TestCase):\n\n        def test_something(self):\n            self.assertTrue(os.path.isdir(self.tmpdir))\n\n\nComparing mtimes\n================\n\n``gocept.testing.mtime.Newer`` checks that generated files are at least as new\nas their source counterparts (similar like ``make`` works)::\n\n    class MyTest(gocept.testing.mtime.Newer, unittest.TestCase):\n\n        source_ext = '.js'\n        target_ext = '.min.js'\n        message = 'run jsmin to correct this'\n\n        def test_minified_js_files_are_younger_than_non_minified_ones(self):\n            self.check_files(pkg_resources.resource_filename(\n                'my.package', 'resources/js'))\n\n\nDevelopment\n===========\n\nThe git repository of the source code as well as the issue tracker are\navailable at https://github.com/minddistrict/gocept.testing.\n\n\nChangelog\n=========\n\n4.0 (2024-05-21)\n----------------\n\nBackwards incompatible changes\n++++++++++++++++++++++++++++++\n\n- Drop support for Python 3.7, 3.8.\n\nFeatures\n++++++++\n\n- Add support for Python 3.11, 3.12 and 3.13 (as of beta 1).\n\n\n3.0 (2021-08-26)\n----------------\n\nBackwards incompatible changes\n++++++++++++++++++++++++++++++\n\n- Change license form ZPL to MIT.\n\n- Drop support for Python 2, 3.4, 3.5 and 3.6\n\nFeatures\n++++++++\n\n- Add support for Python 3.8, 3.9 and 3.10 (as of rc.1).\n\n\n2.0.post1 (2018-11-22)\n----------------------\n\n- Fix PyPI page rendering.\n\n\n2.0 (2018-11-22)\n----------------\n\n- Drop Python 2.6 an 3.3 support.\n\n- Add support for Python 3.6, 3.7, PyPy and PyPy3.\n\n- Choose explicit ``[mock]`` extra to use ``gocept.testing.mock`` on Python <\n  3.3.\n\n\n1.11 (2016-01-18)\n-----------------\n\n- Fix homepage URL.\n\n- Declare Python 3.4 and Python 3.5 support.\n\n- Drop Python 3.2 support.\n\n\n1.10.1 (2014-04-28)\n-------------------\n\n- Make ``assertNotEllipsis()`` compatible with `py.test`.\n\n- Declare Python 3.3 support.\n\n\n1.10 (2014-02-13)\n-----------------\n\n- Remove ``retry`` decorator, it is rather useless since it does not take\n  setUp/tearDown into account.\n\n\n1.9 (2013-12-20)\n----------------\n\n- Add ``retry`` decorator that runs flaky tests several times and only fails\n  when they fail each time.\n\n- Use py.test instead of zope.testrunner for this package's own tests.\n\n\n1.8 (2013-07-17)\n----------------\n\n- Python 3 compatibility.\n- Depend on setuptools rather than distribute now that the projects have\n  merged.\n- Use current buildout and recipes for development.\n\n\n1.7 (2013-04-18)\n----------------\n\n- Fix Python-2.6 compatibility of our own test suite.\n- Introduce ``PatchHelper``.\n\n\n1.6.0 (2013-01-07)\n------------------\n\n- Add newer mtime check.\n\n\n1.5.2 (2012-09-14)\n------------------\n\n- ``.patch.Dict`` did not restore the keys if an exception occured while the\n  `with` call.\n\n\n1.5.1 (2012-09-12)\n------------------\n\n- Fixed documentation and faulty 1.5 release.\n\n\n1.5 (2012-07-10)\n----------------\n\n- Add ``.patch.Dict``, a dict patching context manager.\n\n\n1.4 (2012-06-04)\n----------------\n\n- Add ``TempDir`` fixture.\n- Add ``assertStartsWith``, ``assertEndsWith``.\n\n\n1.3.2 (2012-05-09)\n------------------\n\n- Allow ``assertEllipsis`` to work with mixed unicode/bytes argument\n  (assuming the bytes are UTF-8, as they are with zope.testbrowser).\n\n\n1.3.1 (2012-02-03)\n------------------\n\n- Display original traceback in ``assertNothingRaised``.\n\n\n1.3 (2011-12-16)\n----------------\n\n- Add patch helper for attributes and simple callables.\n\n\n1.2.1 (2011-12-09)\n------------------\n\n- Make Python-3 compatible (at least syntactically).\n\n\n1.2 (2011-12-09)\n----------------\n\n- Add Patches context for mock (upstream implementation pending,\n  see <http://code.google.com/p/mock/issues/detail?id=30>)\n- Add ``assertCalledWith``.\n- Add ``mock.Property``.\n\n\n1.1 (2011-11-10)\n----------------\n\n- Add ``assertNothingRaised``.\n\n\n1.0 (2011-11-02)\n----------------\n\n- first release: ``assertEllipsis``\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A collection of test helpers, additional assertions, and the like.",
    "version": "4.0",
    "project_urls": {
        "Homepage": "https://github.com/minddistrict/gocept.testing"
    },
    "split_keywords": [
        "testing",
        "unittest",
        "assertions"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "945c1d6c92a0f173b2f2456a6de6e389844f13e7c261c31510706c224b4fd528",
                "md5": "2fdc4abb46f8571a57416eb0032debc5",
                "sha256": "8c5c55f2bce21897e08710fec0b5ae4aa5b46794f783e1f2013cd1bc423c4b8f"
            },
            "downloads": -1,
            "filename": "gocept.testing-4.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "2fdc4abb46f8571a57416eb0032debc5",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 13576,
            "upload_time": "2024-05-21T13:03:00",
            "upload_time_iso_8601": "2024-05-21T13:03:00.275014Z",
            "url": "https://files.pythonhosted.org/packages/94/5c/1d6c92a0f173b2f2456a6de6e389844f13e7c261c31510706c224b4fd528/gocept.testing-4.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "3aa5c6ef2ae0e96fcecb40dc24247726e8ec3a1cfcbc12a9e4713c5274529e59",
                "md5": "ce0abe6b9f6bb7302ed7bf1e735f26e9",
                "sha256": "6f2ca03a7c17b133380caceb387584be1f48b8cacf0217f2560561850bfed5bc"
            },
            "downloads": -1,
            "filename": "gocept.testing-4.0.tar.gz",
            "has_sig": false,
            "md5_digest": "ce0abe6b9f6bb7302ed7bf1e735f26e9",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 15046,
            "upload_time": "2024-05-21T13:03:02",
            "upload_time_iso_8601": "2024-05-21T13:03:02.387353Z",
            "url": "https://files.pythonhosted.org/packages/3a/a5/c6ef2ae0e96fcecb40dc24247726e8ec3a1cfcbc12a9e4713c5274529e59/gocept.testing-4.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-05-21 13:03:02",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "minddistrict",
    "github_project": "gocept.testing",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "tox": true,
    "lcname": "gocept.testing"
}
        
Elapsed time: 0.24581s