{ "info": { "author": "pwwang", "author_email": "pwwang@pwwang.com", "bugtrack_url": null, "classifiers": [], "description": "# testly - Enhanced unittest with data provider and more for python\n\n![Pypi][1] ![Github][2] ![Codacy][3] ![Codacy coverage][4] ![Travis building][5]\n\n## Features\n- Data provider\n- Compatible with `unittest`\n- Python2, 3 compatible\n- Command line argument to run a test set (by the same data provider)\n\n## Install\n```shell\n# install released version\npip install python-testly\n# install latest version\npip install git+git://github.com/pwwang/testly.git\n```\n\n## Get started\n### Write your test suite:\n```python\nimport testly\nclass Test(testly.TestCase):\n\n # your tests go here\n pass\n\nif __name__ == '__main__':\n testly.main(verbosity = 2)\n```\n\n### Python2,3 compatible asserts\n```python\nclass Test(testly.TestCase):\n\n def test(self):\n self.assertCountEqual([1,2], [2,1])\n self.assertRaisesRegex(ZeroDivisionError, \"(integer )?division (or modulo )?by zero\", lambda: 1/0)\n self.assertRegex('abcd', r'\\w+')\n```\n\n### Useful extended asserts\n```python\nclass Test(testly.TestCase):\n\n def test(self):\n self.assertDictContains({'a': 1}, {'a': 1, 'b': 2})\n self.assertDictNotContains({'a': 2}, {'a': 1, 'b': 2})\n self.assertSeqContains([1], [1, 2])\n self.assertSeqNotContains([3], [1, 2])\n self.assertInAny('dogs', ['one dog', 'two dogs'])\n self.assertNotInAny('cat', ['one dog', 'two dogs'])\n self.assertRegexAny(r'dogs?', ['one dog', 'two dogs'])\n self.assertNotRegexAny(r'cat', ['one dog', 'two dogs'])\n```\n\n### Use data provider\n```python\nclass TestTest(testly.TestCase):\n\n def dataProvider_test(self):\n # use tuple\n yield 1, 1\n # use dict\n yield dict(in_ = 2, out = 2)\n # use testly data composer\n yield testly.Data(4, out = 4)\n\n def test(self, in_, out):\n self.assertEqual(in_, out)\n```\n\n```shell\n> python test.py\ntest-0 (__main__.TestTest) ... ok\ntest-1 (__main__.TestTest) ... ok\ntest-2 (__main__.TestTest) ... ok\ntest-3 (__main__.TestTest) ... ok\n```\n\n### Colored diff output\n```python\nclass TestTest(testly.TestCase):\n\n def dataProvider_test(self):\n yield 1, 1\n yield 2, 3\n yield '\\n'.join(['oooooooone', 'two', 'aaa', 'tree', '1', '1', '1', '1', '1', '1', 'fourfourfourfourfourfourfourfourfour very very very very very very very very very very very very very very very very very very very very very very very very very very long line']), '\\n'.join(['oooooooore', 'emu', 'three', '1', '1', '1', '1', '1', '1', 'aaa', 'fivefivefivefivefivefivefivefivefive'])\n yield ['oooooooone', 'two', 'aaa', 'tree', '1', '1', '1', '1', '1', '1', 'fourfourfourfourfourfourfourfourfour very very very very very very very very very very very very very very very very very very very very very very very very very very long line'], ['oooooooore', 'emu', 'three', '1', '1', '1', '1', '1', '1', 'aaa', 'fivefivefivefivefivefivefivefivefive']\n yield {'a':1, 'b':2}, {'a':1, 'b':3, 'c': 8}\n\n def test(self, in_, out):\n self.diffColWidth = 160 # max columns of the diff region\n self.diffContext = 1 # number context lines to show\n if not isinstance(in_, (dict, list)):\n self.diffLineNo = False # line number\n if isinstance(in_, list):\n self.diffTheme = 'contrast' # the theme\n self.assertEqual(in_, out)\n```\n![colored-diff](images/colored-diff.gif)\n\nCompared to the original `unittest` output: \n![plain-diff](images/plain-diff.gif)\n\n### Run a specific test or test set\n```python\nimport sys, testly\n\nclass TestTest(testly.TestCase):\n\n def setUp(self):\n # setUp for test set\n if self.isFirst():\n sys.stderr.write('TestSet %s starts ... ' % self.setName())\n # setUp for regular tests\n elif not self.isOfSet():\n # regulator setUp for other tests\n sys.stderr.write('Test %s starts ...' % self._testMethodName)\n\n def tearDown(self):\n # tearDown for test set\n if self.isLast():\n sys.stderr.write('TestSet %s ends ... ' % self.setName())\n # tearDown for regular tests\n elif not self.isOfSet():\n # regulator setUp for other tests\n sys.stderr.write('Test %s ends ... ' % self._testMethodName)\n\n def dataProvider_test1(self):\n yield 1, 1\n yield 2, 2\n yield 3, 3\n\n def test1(self, in_, out):\n self.assertEqual(in_, out)\n\n # regular test\n def test2(self):\n self.assertEqual(1, 1)\n\nif __name__ == '__main__':\n testly.main(verbosity = 2)\n```\n\n#### Run all tests:\n```shell\n> python test.py\ntest1-0 (__main__.TestTest) ... TestSet test1 starts ... ok\ntest1-1 (__main__.TestTest) ... ok\ntest1-2 (__main__.TestTest) ... TestSet test1 ends ... ok\ntest2 (__main__.TestTest) ... Test test2 starts ...Test test2 ends ... ok\n\n----------------------------------------------------------------------\nRan 4 tests in 0.000s\n\nOK\n```\n\n#### Run a specific test (`setUp`, `tearDown` for test set also work):\n```shell\n> python test.py TestTest.test1-2\ntest1-2 (__main__.TestTest) ... TestSet test1 starts ... TestSet test1 ends ... ok\n\n----------------------------------------------------------------------\nRan 1 test in 0.000s\n\nOK\n```\n```shell\n> python test.py TestTest.test2\ntest2 (__main__.TestTest) ... Test test2 starts ...Test test2 ends ... ok\n\n----------------------------------------------------------------------\nRan 1 test in 0.000s\n\nOK\n```\n\n#### Run a specific test set:\n```shell\n> python test.py TestTest.test1\ntest1-0 (__main__.TestTest) ... TestSet test1 starts ... ok\ntest1-1 (__main__.TestTest) ... ok\ntest1-2 (__main__.TestTest) ... TestSet test1 ends ... ok\n\n----------------------------------------------------------------------\nRan 3 tests in 0.000s\n\nOK\n```\n\n[1]: https://img.shields.io/pypi/v/python-testly.svg?style=flat-square\n[2]: https://img.shields.io/github/tag/pwwang/testly.svg?style=flat-square\n[3]: https://img.shields.io/codacy/grade/47cf43d246ac4696a106ef4b4fd0c9ec.svg?style=flat-square\n[4]: https://img.shields.io/codacy/coverage/47cf43d246ac4696a106ef4b4fd0c9ec.svg?style=flat-square\n[5]: https://img.shields.io/travis/pwwang/testly.svg?style=flat-square\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/pwwang/testly", "keywords": "", "license": "Apache License Version 2.0", "maintainer": "", "maintainer_email": "", "name": "python-testly", "package_url": "https://pypi.org/project/python-testly/", "platform": "", "project_url": "https://pypi.org/project/python-testly/", "project_urls": { "Homepage": "https://github.com/pwwang/testly" }, "release_url": "https://pypi.org/project/python-testly/0.0.6/", "requires_dist": [ "six", "future" ], "requires_python": "", "summary": "Python unittest with data provider and more.", "version": "0.0.6" }, "last_serial": 4417239, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "f5920547a4f66284df29d757addb4d73", "sha256": "2f1060be25a25cac974c9b5df910b3f22c1b9d1d10128d0322144199e15896f3" }, "downloads": -1, "filename": "python-testly-0.0.1.tar.gz", "has_sig": false, "md5_digest": "f5920547a4f66284df29d757addb4d73", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8672, "upload_time": "2018-07-04T00:15:22", "url": "https://files.pythonhosted.org/packages/d0/59/e78ec212477a5cbe5e94a9f1d197212e52caeae99b1f96e4ecd440056149/python-testly-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "82fd3753468f8ea0a8d9f850c1b58e5a", "sha256": "71ceb7bad66681005eb7ef1073e741f114644fdd2da5350d181684355b142d60" }, "downloads": -1, "filename": "python-testly-0.0.2.tar.gz", "has_sig": false, "md5_digest": "82fd3753468f8ea0a8d9f850c1b58e5a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9804, "upload_time": "2018-07-09T21:17:39", "url": "https://files.pythonhosted.org/packages/06/e1/ee617aca4902191854e2f6a999b9a24f2055fe6e8e1a7f1a0da1e33bcced/python-testly-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "7703fb32c1b58172d62ae74b8fd410ac", "sha256": "fd3d5ed0dd73efd06ff91ff9e130b1cccd3e18c628a0a44bce07ebb4f188a50f" }, "downloads": -1, "filename": "python_testly-0.0.3-py2-none-any.whl", "has_sig": false, "md5_digest": "7703fb32c1b58172d62ae74b8fd410ac", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 13104, "upload_time": "2018-07-17T20:52:09", "url": "https://files.pythonhosted.org/packages/cd/e6/1ad67765a675299bbf054ce0a622035b587742c3438fdf8443e3207749b4/python_testly-0.0.3-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c4a926ed9913ce751ac72320facdd35a", "sha256": "aec7bac65564bf34d95c77325a2c3295925e164f8e019fc10eb98621ca714f25" }, "downloads": -1, "filename": "python_testly-0.0.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "c4a926ed9913ce751ac72320facdd35a", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 10768, "upload_time": "2018-07-17T21:04:34", "url": "https://files.pythonhosted.org/packages/4b/ff/f7c7a93b165ca0d027f47839685f51ffb87b2f7efae36b333416cc77f78c/python_testly-0.0.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9020ebb10c9df44b2aaa3e96468d60da", "sha256": "d706ef993e08a488879b62ac88864c21f5d7bb6189d37425ad6e768556651139" }, "downloads": -1, "filename": "python-testly-0.0.3.tar.gz", "has_sig": false, "md5_digest": "9020ebb10c9df44b2aaa3e96468d60da", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12144, "upload_time": "2018-07-17T21:04:35", "url": "https://files.pythonhosted.org/packages/b6/10/94885ad39ae585308b6ceef46c7f9de7438fa0e0525372053028b5fb518d/python-testly-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "6dcd56badcf6e12cdd4a7730a4bfedae", "sha256": "9d89f465b8cd0806a521a8a54ffcf2014793f9ce763525dbebc5a2d61e417c68" }, "downloads": -1, "filename": "python_testly-0.0.4-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "6dcd56badcf6e12cdd4a7730a4bfedae", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 13116, "upload_time": "2018-08-08T17:29:38", "url": "https://files.pythonhosted.org/packages/d1/f5/4ca56ce565356b0753b7dc585bd0c3e14fdfe0304138a88ae14fe348afb2/python_testly-0.0.4-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "2880a72d075dfef568f29f9c87405971", "sha256": "3277141012db8df77fa0b6d928e033efe6977ddb78609769a8dbc79a7ec9eb30" }, "downloads": -1, "filename": "python-testly-0.0.4.tar.gz", "has_sig": false, "md5_digest": "2880a72d075dfef568f29f9c87405971", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11633, "upload_time": "2018-08-08T17:29:40", "url": "https://files.pythonhosted.org/packages/5b/3a/1d925004d166e5aeb0a185f5ad261865e1ced97dcc71188ecfcb5363c1a5/python-testly-0.0.4.tar.gz" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "4093b8b011c2871544bccc86f59495ad", "sha256": "7f6a09acf1c0e274c8feb9c4bb6cdc1de0c7a6d9ed19a79ac7f0a35683588023" }, "downloads": -1, "filename": "python_testly-0.0.5-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "4093b8b011c2871544bccc86f59495ad", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 10779, "upload_time": "2018-10-03T21:16:48", "url": "https://files.pythonhosted.org/packages/d9/4e/f475c6c4952c43273c13259bb2ef61e11a07504b44532d906124417fe68a/python_testly-0.0.5-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "835cae79baac16026bc70917704222f0", "sha256": "2d04d53f7641f4fd3c0ac4ffef5571c553eddfbfa4a0321fbcc26b27ef4ecc5b" }, "downloads": -1, "filename": "python-testly-0.0.5.tar.gz", "has_sig": false, "md5_digest": "835cae79baac16026bc70917704222f0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12155, "upload_time": "2018-10-03T21:16:49", "url": "https://files.pythonhosted.org/packages/3b/04/d8dcc6f917f266d2dea1979319cf196e41fbfdf1bc250299ebd91c6dabd5/python-testly-0.0.5.tar.gz" } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "094512e636c19c12d7e9fe30425de522", "sha256": "cc10be9094e9cb454e35bf0248fbba36855702d8da71c42a92cc0da842cf3ec0" }, "downloads": -1, "filename": "python_testly-0.0.6-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "094512e636c19c12d7e9fe30425de522", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 10783, "upload_time": "2018-10-25T23:44:14", "url": "https://files.pythonhosted.org/packages/7a/63/e3aaa8abcae0306f43c52ed45198132aac49dfd08b3b0bdd2270f648bd29/python_testly-0.0.6-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f8d00fb140c9e5c8c2041146a8325b90", "sha256": "8c553f63bdc933b6ebf8aa408b2ffd05055f64df5eb8fdc2005317e8ecbadaf9" }, "downloads": -1, "filename": "python-testly-0.0.6.tar.gz", "has_sig": false, "md5_digest": "f8d00fb140c9e5c8c2041146a8325b90", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12155, "upload_time": "2018-10-25T23:44:16", "url": "https://files.pythonhosted.org/packages/29/eb/df188f2b42bb81c39c5b22ea8e89bdecf5024a412d219b1043514c18db95/python-testly-0.0.6.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "094512e636c19c12d7e9fe30425de522", "sha256": "cc10be9094e9cb454e35bf0248fbba36855702d8da71c42a92cc0da842cf3ec0" }, "downloads": -1, "filename": "python_testly-0.0.6-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "094512e636c19c12d7e9fe30425de522", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 10783, "upload_time": "2018-10-25T23:44:14", "url": "https://files.pythonhosted.org/packages/7a/63/e3aaa8abcae0306f43c52ed45198132aac49dfd08b3b0bdd2270f648bd29/python_testly-0.0.6-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f8d00fb140c9e5c8c2041146a8325b90", "sha256": "8c553f63bdc933b6ebf8aa408b2ffd05055f64df5eb8fdc2005317e8ecbadaf9" }, "downloads": -1, "filename": "python-testly-0.0.6.tar.gz", "has_sig": false, "md5_digest": "f8d00fb140c9e5c8c2041146a8325b90", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12155, "upload_time": "2018-10-25T23:44:16", "url": "https://files.pythonhosted.org/packages/29/eb/df188f2b42bb81c39c5b22ea8e89bdecf5024a412d219b1043514c18db95/python-testly-0.0.6.tar.gz" } ] }