{ "info": { "author": "Dave Shawley", "author_email": "daveshawley@gmail.com", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python" ], "description": "Fluent Unit Testing\n===================\n\n*\"When a failing test makes us read 20+ lines of test code,\nwe die inside.\"* - C.J. Gaconnet\n\n|Version| |Downloads| |Status| |License|\n\nWhy?\n~~~~\n\nThis is an attempt to make Python testing more readable while maintaining a\nPythonic look and feel. As powerful and useful as the `unittest`_ module is,\nI've always disliked the Java-esque naming convention amongst other things.\n\nWhile truly awesome, attempts to bring BDD to Python never feel *Pythonic*.\nMost of the frameworks that I have seen rely on duplicated information between\nthe specification and the test cases. My belief is that we need something\ncloser to what `RSpec`_ offers but one that feels like Python.\n\nWhere?\n~~~~~~\n\n- Source Code: https://github.com/dave-shawley/fluent-test\n- CI: https://travis-ci.org/dave-shawley/fluent-test\n- Documentation: https://fluent-test.readthedocs.org/\n\nHow?\n~~~~\n\n`fluenttest.test_case.TestCase` implements the Arrange, Act, Assert method\nof testing. The configuration for the test case and the execution of the\nsingle action under test is run precisely once per test case instance.\nThe test case contains multiple assertions each in its own method. The\nimplementation leverages existing test case runners such as `nose`_ and\n`py.test`_. In order to run the arrange and act steps once per test,\nfluenttest calls ``arrange`` and ``act`` from within the ``setUpClass``\nclass method. Each assertion is then written in its own test method.\nThe following snippet rewrites the simple example from the Python Standard\nlibrary unittest documentation::\n\n import random\n import unittest\n\n class TestSequenceFunctions(unittest.TestCase):\n def setUp(self):\n self.seq = list(range(10))\n\n def test_shuffle(self):\n # make sure the shuffled sequence does not lose any elements\n random.shuffle(self.seq)\n self.seq.sort()\n self.assertEqual(self.seq, list(range(10)))\n\n # should raise an exception for an immutable sequence\n self.assertRaises(TypeError, random.shuffle, (1, 2, 3))\n\nThis very simple test looks like the following when written using\n``fluenttest``. Notice that the comments in the original test really\npointed out that there were multiple assertions buried in the test\nmethod. This is much more explicit with ``fluenttest``::\n\n import random\n import unittest\n\n from fluenttest import test_case\n\n class WhenShufflingSequence(test_case.TestCase, unittest.TestCase):\n @classmethod\n def arrange(cls):\n super(WhenShufflingSequence, cls).arrange()\n cls.input_sequence = list(range(10))\n cls.result_sequence = cls.input_sequence[:]\n\n @classmethod\n def act(cls):\n random.shuffle(cls.result_sequence)\n\n def test_should_not_loose_elements(self):\n self.assertEqual(sorted(self.result_sequence),\n sorted(self.input_sequence))\n\n class WhenShufflingImmutableSequence(test_case.TestCase, unittest.TestCase):\n allowed_exceptions = TypeError\n\n @classmethod\n def act(cls):\n random.shuffle((1, 2, 3))\n\n def test_should_raise_type_error(self):\n self.assertIsInstance(self.exception, TypeError)\n\nThe ``fluenttest`` version is almost twice the length of the original so\nbrevity is not a quality to expect from this style of testing. The first\nthing that you gain is that the comments that explained what each test is\ndoing is replace with very explicit code. In this simplistic example, the\ngain isn't very notable. Look at the *tests* directory for a realistic\nexample of tests written in this style.\n\nContributing\n~~~~~~~~~~~~\n\nContributions are welcome as long as they follow a few basic rules:\n\n1. They start out life by forking the central repo and creating a new\n branch off of *master*.\n2. All tests pass and coverage is at 100% - **make test**\n3. All quality checks pass - **make lint**\n4. Issue a pull-request through github.\n\nDevelopment Environment\n-----------------------\n\nLike many other projects, the development environment is contained in a\nvirtual environment and controlled by a Makefile. The inclusion of make is\nless than perfect, but it is the easiest way to bootstrap a project on just\nabout any platform. Start out by cloning the repository with git and\nbuilding a virtual environment to work with::\n\n $ git clone https://github.com/my-org/fluent-test.git\n $ cd fluent-test\n $ make environment\n\nThis will create a Python 3 environment in the *env* directory using *mkvenv*\nand install the various prerequisites such as *pip* and *nose*. You can\nactivate the environment source ``source env/bin/activate``, launch a Python\ninterpreter with ``env/bin/python``, and run the test suite with\n``env/bin/nosetests``.\n\nThe Makefile exports a few other useful targets:\n\n- **make test**: run the tests\n- **make lint**: run various static analysis tools\n- **make clean**: remove cache files\n- **make mostly-clean**: remove built and cached eggs\n- **make dist-clean**: remove generated distributions\n- **make maintainer-clean**: remove virtual environment\n- **make sdist**: create a distribution tarball\n- **make docs**: build the HTML documentation\n\n.. _unittest: http://docs.python.org/2/library/unittest.html\n.. _RSpec: http://rspec.info/\n.. _gitflow: https://github.com/nvie/gitflow\n.. _nose: http://nose.readthedocs.org\n.. _py.test: http://pytest.org\n\n.. |Version| image:: https://badge.fury.io/py/fluent-test.svg\n.. |Downloads| image:: https://pypip.in/d/fluent-test/badge.svg\n.. |Status| image:: https://travis-ci.org/dave-shawley/fluent-test.svg\n.. |License| image:: https://pypip.in/license/fluent-test/badge.svg", "description_content_type": null, "docs_url": "https://pythonhosted.org/Fluent-Test/", "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/dave-shawley/fluent-test/", "keywords": null, "license": "BSD", "maintainer": null, "maintainer_email": null, "name": "Fluent-Test", "package_url": "https://pypi.org/project/Fluent-Test/", "platform": "any", "project_url": "https://pypi.org/project/Fluent-Test/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://github.com/dave-shawley/fluent-test/" }, "release_url": "https://pypi.org/project/Fluent-Test/3.0.0/", "requires_dist": null, "requires_python": null, "summary": "Fluent testing for Python", "version": "3.0.0" }, "last_serial": 1215991, "releases": { "1": [ { "comment_text": "", "digests": { "md5": "794538a78ff8b097a84b44a17be82b2d", "sha256": "ffd809d9634e2afa65d262cc5c2ee9dbeb15d2690788f0bf515b01d175872850" }, "downloads": -1, "filename": "Fluent-Test-1.tar.gz", "has_sig": false, "md5_digest": "794538a78ff8b097a84b44a17be82b2d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11330, "upload_time": "2014-01-19T17:08:32", "url": "https://files.pythonhosted.org/packages/57/69/b6f18f967f1792646d5ed092fb540850b67c9d20b8c5ae843152a6b73b4e/Fluent-Test-1.tar.gz" } ], "2.0.0": [ { "comment_text": "", "digests": { "md5": "6bc54db41581d3621d5710c1088dec5d", "sha256": "d643867e35a590e9b94811daaaf3f8a94af528461f51d8ea8caad05be59b1bfc" }, "downloads": -1, "filename": "Fluent-Test-2.0.0.tar.gz", "has_sig": false, "md5_digest": "6bc54db41581d3621d5710c1088dec5d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13314, "upload_time": "2014-02-15T19:29:10", "url": "https://files.pythonhosted.org/packages/e0/7e/8a340a6aa38afb6ce59bbc5ca18ee809d515ed758b802835af6fae295b62/Fluent-Test-2.0.0.tar.gz" } ], "2.0.1": [ { "comment_text": "", "digests": { "md5": "c6db4a63b41ef5815ece476d08dfa3df", "sha256": "fe8a674dd9e7b9931c727151e096821ccff89cc19f6d75a4db5665e493650a52" }, "downloads": -1, "filename": "Fluent-Test-2.0.1.tar.gz", "has_sig": false, "md5_digest": "c6db4a63b41ef5815ece476d08dfa3df", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13463, "upload_time": "2014-02-15T22:24:31", "url": "https://files.pythonhosted.org/packages/f9/9e/e3f139b1d60378d9a5244d548246705a603b153f90b4e334dd99a6e64407/Fluent-Test-2.0.1.tar.gz" } ], "3.0.0": [ { "comment_text": "", "digests": { "md5": "36f1fa5e56caf8d78f530f37fe862ed3", "sha256": "850a8ebce195d7bac545cf693e4affca96eedb5f70833eb35bcbaf464daf9b75" }, "downloads": -1, "filename": "Fluent_Test-3.0.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "36f1fa5e56caf8d78f530f37fe862ed3", "packagetype": "bdist_wheel", "python_version": "3.4", "requires_python": null, "size": 8428, "upload_time": "2014-09-07T13:29:33", "url": "https://files.pythonhosted.org/packages/59/a6/ebaa54a84615df79052d0fb465962f16762939caa6630af20e664be9a40b/Fluent_Test-3.0.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9f57ebdcd5d36eb1268d093f67e00131", "sha256": "d94e284feced4d7cf7366314f5e3c5a453c5e3318e239082e26a468874bb907f" }, "downloads": -1, "filename": "Fluent-Test-3.0.0.tar.gz", "has_sig": false, "md5_digest": "9f57ebdcd5d36eb1268d093f67e00131", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13370, "upload_time": "2014-09-07T13:29:30", "url": "https://files.pythonhosted.org/packages/66/42/45b65aed20e6a19864c3266b35ca61433d48199d12e473a03b8e45e6462b/Fluent-Test-3.0.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "36f1fa5e56caf8d78f530f37fe862ed3", "sha256": "850a8ebce195d7bac545cf693e4affca96eedb5f70833eb35bcbaf464daf9b75" }, "downloads": -1, "filename": "Fluent_Test-3.0.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "36f1fa5e56caf8d78f530f37fe862ed3", "packagetype": "bdist_wheel", "python_version": "3.4", "requires_python": null, "size": 8428, "upload_time": "2014-09-07T13:29:33", "url": "https://files.pythonhosted.org/packages/59/a6/ebaa54a84615df79052d0fb465962f16762939caa6630af20e664be9a40b/Fluent_Test-3.0.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9f57ebdcd5d36eb1268d093f67e00131", "sha256": "d94e284feced4d7cf7366314f5e3c5a453c5e3318e239082e26a468874bb907f" }, "downloads": -1, "filename": "Fluent-Test-3.0.0.tar.gz", "has_sig": false, "md5_digest": "9f57ebdcd5d36eb1268d093f67e00131", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13370, "upload_time": "2014-09-07T13:29:30", "url": "https://files.pythonhosted.org/packages/66/42/45b65aed20e6a19864c3266b35ca61433d48199d12e473a03b8e45e6462b/Fluent-Test-3.0.0.tar.gz" } ] }