{ "info": { "author": "Johannes Schriewer", "author_email": "hallo@dunkelstern.de", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Software Development :: Testing" ], "description": "=====================================================\n integrate - Testing framework for integration tests\n=====================================================\n\nThe usual testing frameworks you can find for Python are so-called unit-testing-frameworks. As this collides with some goals of integration testing this framework was built.\n\n---------\nChangelog\n---------\n\n1.0.0\n=====\n\n- First release, supports Python >= 3.3\n\n1.1.0\n=====\n\n- Backport to work on Python 2.7\n- If you want to use Python 3 use at least 3.3\n\n1.2.0\n=====\n\n- Bugfix: Python 2 issue (Re #4)\n- Ignore Test Base classes (Thanks withrocks: https://github.com/withrocks)\n- Testrunner.run() now returns stats (Thanks nooploop: https://github.com/nooploop)\n\n1.3.0\n=====\n\n- Add optional ``args=`` to ``run()`` - function (Thanks kensthilaire: https://github.com/kensthilaire)\n\n---------------------------------------------------------------------\n What's the difference between integration testing and unit-testing?\n---------------------------------------------------------------------\n\nIn unit testing you should only test the smallest possible thing in your application (or library) and all test should be independent and the ordering of tests is not of particular interest. To make that possible it is very common to stub or mock data models or other external dependencies and only test the functionality of your data transforms. You define fixtures and setup and teardown functions to prepare the environment for a unit test and destroy that environment immediately after running the test.\n\nIntegration testing tests the complete system and has no direct influence on the data in the system so naturally the ordering of tests matter and tests may have dependencies (one test creates a DB record which another one modifies, etc.)\n\nAs you should test one thing in an unit-test only, you should only use a single assert in a unit test. The default behaviour of most assert methods in unit-testing-frameworks is to raise an exception. This means everything after the failed assert is skipped and the test is marked as failed. In integration-testing you probably want to check multiple things at once and get a detailed error report which checks failed exactly.\n\n----------------------------------------------\n What does this framework better than others?\n----------------------------------------------\n\n1. You have full control over which tests run in what order (if you want)\n2. You can mark tests as dependent on others, so they will be skipped when a dependency fails\n3. You can log as many errors as you want in a single test. Every error saves a stack trace and the error message for further debugging\n4. The test runner is very flexible (Your python files that contain the tests do not need to be in python modules)\n\n------------------------------\n How to use it aka Quickstart\n------------------------------\n\n1. Install::\n\n\tpip install integrate\n\n2. Write a test case class::\n\n\tfrom integrate import TestCase, test\n\n\tclass Test(TestCase):\n\t\t\"Simple test case\"\n\n\t\t@test(skip_if_failed=[\"other_test\"])\n\t\tdef simple_test(self, check):\n\t\t\tcheck.equal(1,2)\n\n\t\t@test()\n\t\tdef other_test(self, check):\n\t\t\t\"Always failing test\"\n\t\t\tcheck.fail(\"Always fails\")\n\n3. Write a test-runner (we assume you put the test case into ``tests/test.py``)::\n\n\t#!/usr/bin/env python\n\n\tfrom integrate import TestRunner\n\tTestRunner(dirs=[\"tests\"], pattern=\"*.py\").run()\n\n4. Make it executable and run it (or run with ``python testrunner.py``)::\n\n\tchmod a+x testrunner.py\n\t./testrunner.py\n\n---------------------\n Short documentation\n---------------------\n\nAll tests have to be in a class that is derived from ``TestCase``, you may put anything in that class that you want, functions that should be called by the test runner have to be decorated with ``@test()``.\n\n``TestCase`` class\n==================\n\nThe ``TestCase`` class is the workhorse of the integrate framework. It has some functions you may override in a subclass in addition to adding test functions:\n\n- ``def setup_all(self):``\n This function is run at the beginning of the test case class before any test is started\n- ``def teardown_all(self):``\n This function is run at the end of the test case class after all tests have finished\n- ``def setup_test(self):``\n This function is run before each test in the test case\n- ``def teardown_test(self):``\n This function is run after each test in the test case\n\nYou can run the test case class by it's own by calling ``YourTestCase().run()`` or rely on the test runner\n\nThere are some interesting initialization parameters:\n\n- ``verbosity``, how verbose the test output should be (min: 0, max: 2, default: 2)\n- ``checker``, which ``Check`` subclass to use, usually you will use the default ``Check`` class, but you may extend that to add methods to the ``check`` object all tests receive\n\n\n``@test`` decorator\n===================\n\nAll functions that should be picked up by the ``TestCase`` class have to be decorated with ``@test()`` (notice the parentheses!), the decorator has some optional parameters:\n\n- ``skip`` boolean, defaults to ``False``, set to ``True`` to skip a test\n- ``skip_if_failed`` list of strings, names of test functions that have to succeed (not fail or be skipped) in order for this function to run, defaults to an empty list\n- ``depends`` list of strings, names of test functions that should be run before this function, defaults to an empty list\n- ``expect_fail`` boolean, set to true if you expect this test to fail (just for logging purposes)\n\nThe test functions have 2 parameters: ``self`` and ``check``, for the description of ``check`` read on.\n\n\n``Check`` class\n===============\n\nAll errors that surface in a test should be found and logged by an instance of the ``Check`` class. You may subclass this class to add additional checker functions and insert it into the ``TestCase`` or ``TestRunner`` initializer.\n\nThe assertion API looks like the following, if there is a ``message`` parameter it usually is optional and may be left out. User messages are prepended to an error message:\n\n- ``equal(a, b, message=None)``\n Check if two values are equal\n- ``not_equal(a, b, message=None)``\n Check if two values are not equal\n- ``is_none(a, message=None)``\n Check if a value is None\n- ``is_not_none(a, message=None)``\n Check if a value is not None\n- ``is_true(a, message=None)``\n Check if a value is True\n- ``is_false(a, message=None)``\n Check if a value is False\n- ``fail(message)``\n Just log an error message\n- ``raises(exception_type, function, *args, **kwargs)``\n Check if a function raises a specified exception type, args and kwargs are forwarded to the function\n- ``does_not_raise(function, *args, **kwargs)``\n Check if a function does not raise an exception, args and kwargs are forwarded to the function\n\nAll check functions should return ``True`` if the check succeeded and ``False`` if it failed if they don't have to return any other result (like the ``raises`` and ``does_not_raise`` functions which return the result of the function or ``None``)\n\nExceptions in test functions will still cancel the test function and log the exception to the error log if you don't wrap it with a ``raises()`` call. The traceback of an exception caught by the toplevel will be not of much use though if you can't pinpoint the location based on the exception type. If you just want to catch all exceptions use ``check.raises(Exception, myFunc, \"myParam\")``\n\nFor extending the ``Check`` class there is a, rather small, extension API:\n\n- ``log_error(error, message, detail=None, strip=4)``\n Use this function to add an error to the list, a corresponding stack trace is appended automatically. The ``error`` parameter is a textual one line description of the error, the ``message`` parameter is a user message. Use the ``detail`` parameter to give a detailed error description if needed. Only modify the ``strip`` parameter if your stacktrace gets entries after the error location in the test, by default it strips the last 4 stack frames as these are in the testing framework and just clobber the stack traces.\n- ``error_message()``\n Use this for debugging, this function joins all error messages into one string\n\n\n``TestRunner`` class\n====================\n\nThe ``TestRunner`` class is the entry point for automatically discovering tests in a project and running them. It has some initialization parameters:\n\n- ``verbosity`` verbosity of test output (min: 0, max: 2, default: 2)\n- ``dirs`` list of directories to scan for tests, defaults to current directory. Directories are scanned recursively.\n- ``pattern`` file name pattern to search (argument to ``fnmatch``) defaults to the python best practice ``*_test.py``\n- ``checker`` the ``Check`` subclass to send to the tests, if you have subclassed the ``Check`` class put your class here, defaults to the unmodified ``Check`` class\n\nTo start the tests instanciate the test runner and call the ``run()`` function::\n\n\tfrom integrate import TestRunner\n\tTestRunner().run()\n\nIf you want to run just some tests of your test suite you may either run the tests directly by calling ``run()`` on the ``TestCase`` subclass or by supplying a filter to the ``run()`` function of the test runner like so::\n\n\tTestRunner().run(only='special.')\n\nThis example would only run tests which have a module name that starts with ``special.`` the module names are generated by replacing all slashes of the python file path with a dot and removing the ``.py`` extension.\n\nA test file that is stored in the path ``special/tests/runme.py`` will get a module name of ``special.tests.runme``.\n\nIf you only want to look at what the Test runner would actually do use the ``plan()`` function, this just displays a list of test that would be executed and the order of execution instead of really running the tests. It has the same parameters as the ``run()`` function.", "description_content_type": "text/x-rst", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/anfema/integrate", "keywords": "integration test tests", "license": "BSD", "maintainer": "", "maintainer_email": "", "name": "integrate", "package_url": "https://pypi.org/project/integrate/", "platform": "", "project_url": "https://pypi.org/project/integrate/", "project_urls": { "Homepage": "https://github.com/anfema/integrate" }, "release_url": "https://pypi.org/project/integrate/1.3.0/", "requires_dist": null, "requires_python": "", "summary": "Test framework for integration tests with dependencies", "version": "1.3.0" }, "last_serial": 5983341, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "b1eb54aaaba9bd55fbe9cc051e6542d4", "sha256": "9b4666eb93ebc107d84da5bb94e73d7b08b97c3e9fdb07f6271b5bbf7e3ad503" }, "downloads": -1, "filename": "integrate-1.0.0.tar.gz", "has_sig": false, "md5_digest": "b1eb54aaaba9bd55fbe9cc051e6542d4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7537, "upload_time": "2016-04-15T14:20:03", "url": "https://files.pythonhosted.org/packages/fc/b3/0cdb5e82946205dd1ca9e63f90f6d872dbf628ad115f8066854844d7a081/integrate-1.0.0.tar.gz" } ], "1.0.0b1": [ { "comment_text": "", "digests": { "md5": "51b5df0fa8717d4ad91690ad7aa82292", "sha256": "5d083f760c8e4ec9d2dc3f430623a997588e6a220f35e12399c3289925e1980d" }, "downloads": -1, "filename": "integrate-1.0.0b1.tar.gz", "has_sig": false, "md5_digest": "51b5df0fa8717d4ad91690ad7aa82292", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6605, "upload_time": "2016-04-07T15:52:05", "url": "https://files.pythonhosted.org/packages/ef/fc/654acf103901608fc6f74eca21676ed404a0fe081f34dc08dbb8ce456e3e/integrate-1.0.0b1.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "4e93a129b0e0d11c669261cd3dd6e452", "sha256": "72dcc15834044b8902897f5d3cc29af9b4d284d5fdd824cb4563396c6fd31632" }, "downloads": -1, "filename": "integrate-1.1.0.tar.gz", "has_sig": false, "md5_digest": "4e93a129b0e0d11c669261cd3dd6e452", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7947, "upload_time": "2017-07-28T10:19:59", "url": "https://files.pythonhosted.org/packages/01/d7/5af4c3988b81c41ccb48651a3eac158f6108a9e316879cb8e886f3f927c3/integrate-1.1.0.tar.gz" } ], "1.1.1": [ { "comment_text": "", "digests": { "md5": "4c26fad73b7aa927e590271bb5807c96", "sha256": "c0f4b1fdd24848b12d391ff78f50a2f447ee1cf5eb2bda3da20b0292af9d9666" }, "downloads": -1, "filename": "integrate-1.1.1.tar.gz", "has_sig": false, "md5_digest": "4c26fad73b7aa927e590271bb5807c96", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7933, "upload_time": "2017-07-28T10:24:52", "url": "https://files.pythonhosted.org/packages/72/c1/34a12d1ad09ce76e565075c63da3df2f2a8c80768332e581c72a0f18916c/integrate-1.1.1.tar.gz" } ], "1.2.0": [ { "comment_text": "", "digests": { "md5": "06531af81d50bf66db23851ea816ac36", "sha256": "09e0920fa312b578bbbadb3931fd5016d712c4c1f0edc533f176d647c5960431" }, "downloads": -1, "filename": "integrate-1.2.0.tar.gz", "has_sig": false, "md5_digest": "06531af81d50bf66db23851ea816ac36", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8147, "upload_time": "2018-04-27T16:16:21", "url": "https://files.pythonhosted.org/packages/3f/32/b0dcbbc9e623cfc943d4e71a54509c7d5ce7576cf3e9c8ea6dc9cb630b15/integrate-1.2.0.tar.gz" } ], "1.2.1": [ { "comment_text": "", "digests": { "md5": "fce2036d6150842a3d51e512b12671bc", "sha256": "b31cc640d8b4c8878e51c7b2ff224c15606922fa7b2e9ec0d4dea5e5aae01c86" }, "downloads": -1, "filename": "integrate-1.2.1.tar.gz", "has_sig": false, "md5_digest": "fce2036d6150842a3d51e512b12671bc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8910, "upload_time": "2018-04-27T16:21:46", "url": "https://files.pythonhosted.org/packages/17/fe/69c5ac9f170a47c7c5701c2374baf68774b79be9418f68d719da8e90f407/integrate-1.2.1.tar.gz" } ], "1.3.0": [ { "comment_text": "", "digests": { "md5": "0b92800bb669e57fcf19e34260a145dd", "sha256": "29efb21ca5d7f27731ae9fbc7713a8903beca0795cff92546b1f4d1a9dd0371d" }, "downloads": -1, "filename": "integrate-1.3.0.tar.gz", "has_sig": false, "md5_digest": "0b92800bb669e57fcf19e34260a145dd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10880, "upload_time": "2019-10-16T13:12:54", "url": "https://files.pythonhosted.org/packages/94/c8/404d782010709dc502094f80b4b5801c25f3d0b4e6325413bf5d3bd54816/integrate-1.3.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "0b92800bb669e57fcf19e34260a145dd", "sha256": "29efb21ca5d7f27731ae9fbc7713a8903beca0795cff92546b1f4d1a9dd0371d" }, "downloads": -1, "filename": "integrate-1.3.0.tar.gz", "has_sig": false, "md5_digest": "0b92800bb669e57fcf19e34260a145dd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10880, "upload_time": "2019-10-16T13:12:54", "url": "https://files.pythonhosted.org/packages/94/c8/404d782010709dc502094f80b4b5801c25f3d0b4e6325413bf5d3bd54816/integrate-1.3.0.tar.gz" } ] }