{ "info": { "author": "Pierre Tardy", "author_email": "tardyp@gmail.com", "bugtrack_url": null, "classifiers": [], "description": "cctrial\n=======\n\ncctrial is a tool for using twisted trial in a continuous manner.\n\ncctrial will re-run failed tests until all succeed.\n\ncctrial is designed for a specific workflow, which helps doing big refactors that break lots of tests.\n\ncctrial smart mode can run only the tests that import the modified file.\n\ncctrial is not designed to replace trial, for all other usecases.\n\nInstallation\n------------\n\nInstall cctrial in your virtualenv:\n\n.. code-block:: bash\n\n pip install cctrial\n\nLinux specific setup\n--------------------\n\nAs cctrial is making big use of inotify via the watchdog library, you may need to increase the quotas for inotify\n\n.. code-block:: bash\n\n sudo sysctl fs.inotify.max_user_watches=100000\n sudo sh -c 'echo fs.inotify.max_user_watches=100000>>/etc/sysctl.conf'\n\nWorkflow description\n--------------------\n\nRun:\n\n.. code-block:: bash\n\n cctrial -j2 -f my.package\n\nIt will monitor all the directories where packages are installed with ``pip install -e`` or ``./setup.py develop``.\nThe re-runs will only happen after a file has been modified in one of the watched directories.\n\n- Run the full unit test suite.\n\n- Gather all the broken tests, if any.\n\n- Re-run the test which failure appears the most.\n In cctrial workflow, you always fix tests one by one, starting by the tests whose resolution will probably fix the most errors.\n\n- When current test finally pass, will re-run all tests that originally failed.\n\n- After all tests pass, will re-run the full test suite\n\nAdditional features\n-------------------\n\n- Custom reporter designed to concentrate information as much as possible in the terminal screen.\n\n- During the run, always updating one line status, tells you the current test, number of failures, etc.\n\n- After the run, summarized issues are printed\n\n- Only during the fix test loop, logs for the current testcase are printed, as well as the failure details, and stdout/stderr of testcase.\n\n- Desktop notification support.\n This one requires ``terminal-notifier`` on OSX or ``notify-send`` on freedesktop capable systems (e.g linux, xBSD).\n\n- Hook mode for running just the appropriate tests in a git post commit hook.\n\nScreenshots\n-----------\n\n.. code-block:: text\n\n % cctrial buildbot.test.regressions\n Running 38 tests.\n\n\n -------------------------------------------------------------------------------\n Ran 38 tests in 1.400s\n\n PASSED (successes=38)\n buildbot.test.regressions.test_unpickling.StatusPickles.test_upgrade 38/ 38 0F 0E 0S 0T 0!\n waiting for filesystem change...\n\n\nAfter introducing a bug:\n\n.. code-block:: text\n\n Running 38 tests.\n\n\n =============================================================================== 4 cases: [ERROR]\n Traceback (most recent call last):\n File \"/Users/ptardy/dev/bb/buildbot-heroku/buildbot/master/buildbot/test/regressions/test_import_unicode_changes.py\", line 31, in make_dbc\n self.db = DBConnector(master, self.basedir)\n exceptions.TypeError: __init__() takes exactly 2 arguments (3 given)\n\n -------------------------------------------------------------------------------\n Ran 38 tests in 0.272s\n\n FAILED (errors=4, successes=34)\n buildbot.test.regressions.test_unpickling.StatusPickles.test_upgrade 38/ 38 0F 4E 0S 0T 0!\n re-run: testAsciiChange (buildbot.test.regressions.test_import_unicode_changes.TestUnicodeChanges)\n Running 1 tests.\n\n\n =============================================================================== 1 case: [ERROR]\n Traceback (most recent call last):\n File \"/Users/ptardy/dev/bb/buildbot-heroku/buildbot/master/buildbot/test/regressions/test_import_unicode_changes.py\", line 31, in make_dbc\n self.db = DBConnector(master, self.basedir)\n exceptions.TypeError: __init__() takes exactly 2 arguments (3 given)\n\n -------------------------------------------------------------------------------\n Ran 1 tests in 0.001s\n\n FAILED (errors=1)\n\n Logs: Log opened.\n --> buildbot.test.regressions.test_import_unicode_changes.TestUnicodeChanges.testAsciiChange <--\n cleaning database sqlite://\n Main loop terminated.\n\n\n\n please fix: testAsciiChange (buildbot.test.regressions.test_import_unicode_changes.TestUnicodeChanges)\n waiting for filesystem change...\n\nAfter fixing the bug:\n\n.. code-block:: text\n\n re-run: testAsciiChange (buildbot.test.regressions.test_import_unicode_changes.TestUnicodeChanges)\n Running 1 tests.\n\n\n -------------------------------------------------------------------------------\n Ran 1 tests in 0.001s\n\n PASSED (successes=1)\n\n Running 4 tests.\n\n\n -------------------------------------------------------------------------------\n Ran 4 tests in 0.610s\n\n PASSED (successes=4)\n buildbot.test.regressions.test_import_unicode_changes 4/ 4 0F 0E 0S 0T 0!\n\n Running 38 tests.\n\n\n -------------------------------------------------------------------------------\n Ran 38 tests in 1.400s\n\n PASSED (successes=38)\n buildbot.test.regressions.test_unpickling.StatusPickles.test_upgrade 38/ 38 0F 0E 0S 0T 0!\n waiting for filesystem change...\n\n\nDesign Notes\n------------\n\nProblem with re-running tests is that you cannot reuse the same python environment.\nUsing builtin 'reload' is really something you want to avoid.\n\ncctrial uses DistTrialRunner in order to implement the reload.\nThe workers leave in a separate python environment and are re-spawn between runs.\n\nIn order to optimize startup time:\n\n- We prepare the workers while waiting for the filesystem change.\n ``import twisted.internet.reactor`` takes 600ms.\n\n- We discover the tests only once\n test discovery for buildbot takes 2160ms\n\nSmart mode tries to be smart..\n\n- Best option would be to run all tests in coverage mode, and see which file the tests exercices.\n This would require a lot of overhead in the beginning.\n\n- We choose simpler option: For all the test cases, we look at its module imports statements.\n For all the module imported by the testcase, we decide that the testcase exercices the files defining those modules.", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "UNKNOWN", "keywords": null, "license": "MIT", "maintainer": null, "maintainer_email": null, "name": "cctrial", "package_url": "https://pypi.org/project/cctrial/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/cctrial/", "project_urls": { "Download": "UNKNOWN", "Homepage": "UNKNOWN" }, "release_url": "https://pypi.org/project/cctrial/1.2.7/", "requires_dist": null, "requires_python": null, "summary": "continous trial runner", "version": "1.2.7" }, "last_serial": 1980651, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "c750ce759b65020400a46d79c32183ab", "sha256": "059668c868071e66a6814e85e31f3da8d1b3118e8265defffca0699b3fdda2a3" }, "downloads": -1, "filename": "cctrial-1.0.0-py2-none-any.whl", "has_sig": false, "md5_digest": "c750ce759b65020400a46d79c32183ab", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 6413, "upload_time": "2015-08-09T15:58:15", "url": "https://files.pythonhosted.org/packages/32/c1/b1688f9f278ae4ad5e4e4e5f757b9f4a5db8daa3f475c79990bf3e498552/cctrial-1.0.0-py2-none-any.whl" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "afaf4b966421fcaf6ba88f4e114ebefe", "sha256": "641515b16a03ea027f0a59fb08b5edf2147fc45a8267646c7a59a65b62e68a42" }, "downloads": -1, "filename": "cctrial-1.0.1-py2-none-any.whl", "has_sig": false, "md5_digest": "afaf4b966421fcaf6ba88f4e114ebefe", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 9244, "upload_time": "2015-08-09T16:36:52", "url": "https://files.pythonhosted.org/packages/5f/75/aeb1e51affb4bacc3ee35575b20a587016e97cb99e3f86ce9c536e2f0312/cctrial-1.0.1-py2-none-any.whl" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "cdb664ce75a5f2427fce3519c2be91e4", "sha256": "5b5cbdf1b686c0f2829abe58b6a8228733953ee40990ccc10385acb4863b9ad9" }, "downloads": -1, "filename": "cctrial-1.0.2-py2-none-any.whl", "has_sig": false, "md5_digest": "cdb664ce75a5f2427fce3519c2be91e4", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 9272, "upload_time": "2015-08-09T16:47:32", "url": "https://files.pythonhosted.org/packages/c1/61/8c7b7efc646c79e72cc230b60cb1cdb9475855c4e00eb62a5adefaacc18f/cctrial-1.0.2-py2-none-any.whl" } ], "1.2.0": [ { "comment_text": "", "digests": { "md5": "23f68d9b65c95c262f81b56f51fe3163", "sha256": "b87b0333c6c44a3fa3284d094561e2b55bd70e05292f0fd98ae075d533d92c7d" }, "downloads": -1, "filename": "cctrial-1.2.0-py2-none-any.whl", "has_sig": false, "md5_digest": "23f68d9b65c95c262f81b56f51fe3163", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 13512, "upload_time": "2015-08-14T17:55:58", "url": "https://files.pythonhosted.org/packages/b5/99/0ebb5d558ac4a9f5139bbcce41d332baa4dfd81a36f7d7559d678bc6c6b7/cctrial-1.2.0-py2-none-any.whl" } ], "1.2.1": [ { "comment_text": "", "digests": { "md5": "1b3d34cbb0fb2efb859a06f15491b4c2", "sha256": "8879abd65b82697b7af080c08658a797d089211f5202f3ceda4a7d3334e495c1" }, "downloads": -1, "filename": "cctrial-1.2.1-py2-none-any.whl", "has_sig": false, "md5_digest": "1b3d34cbb0fb2efb859a06f15491b4c2", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 13585, "upload_time": "2015-08-24T12:52:33", "url": "https://files.pythonhosted.org/packages/db/10/52394f441ec9ffe090cf2b09453f8598e74235fec1ae6671b30d2106e428/cctrial-1.2.1-py2-none-any.whl" } ], "1.2.2": [ { "comment_text": "", "digests": { "md5": "dd9c5339c890b470e133788011fd7d25", "sha256": "6592a06c3a493457017848ecf10d0a4944d6f2598e4c892ad96d4b6754d17023" }, "downloads": -1, "filename": "cctrial-1.2.2-py2-none-any.whl", "has_sig": false, "md5_digest": "dd9c5339c890b470e133788011fd7d25", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 14031, "upload_time": "2015-09-06T10:24:30", "url": "https://files.pythonhosted.org/packages/9d/c3/d688c6f53ec0b69c7a60ee3ddd81816e1d9c2d2c476e146144559fdc8049/cctrial-1.2.2-py2-none-any.whl" } ], "1.2.3": [ { "comment_text": "", "digests": { "md5": "7a27444a7aaeb5805dbca59d1376505f", "sha256": "c01a11045bc4ebca2df5c9511ad46db38b2fbbe2e283fea0081683b42b405221" }, "downloads": -1, "filename": "cctrial-1.2.3-py2-none-any.whl", "has_sig": false, "md5_digest": "7a27444a7aaeb5805dbca59d1376505f", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 14106, "upload_time": "2015-09-29T11:28:35", "url": "https://files.pythonhosted.org/packages/5d/39/cd8973af6a4daee1053a087be1cdef49b8cd59124c3463ae9d7ef4b014e8/cctrial-1.2.3-py2-none-any.whl" } ], "1.2.4": [ { "comment_text": "", "digests": { "md5": "ec01bc8fafd5b6b7870df5e5b701bd75", "sha256": "a288276bcf521fe169c5d9cb3967f30fa7603b882c60fa7fabd6c631f62f6083" }, "downloads": -1, "filename": "cctrial-1.2.4-py2-none-any.whl", "has_sig": false, "md5_digest": "ec01bc8fafd5b6b7870df5e5b701bd75", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 14148, "upload_time": "2016-01-09T16:17:43", "url": "https://files.pythonhosted.org/packages/4f/22/193149987d6d25ae254006f738afb5500844f382de95b1657cf8f7ed6715/cctrial-1.2.4-py2-none-any.whl" } ], "1.2.5": [ { "comment_text": "", "digests": { "md5": "205f7f596a89247b5c3310f96340a4c5", "sha256": "4f888ab2ea41755749bc6723dfc8bb030570dc901ef627f68695dc28b34e1cec" }, "downloads": -1, "filename": "cctrial-1.2.5-py2-none-any.whl", "has_sig": false, "md5_digest": "205f7f596a89247b5c3310f96340a4c5", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 14162, "upload_time": "2016-01-10T12:23:33", "url": "https://files.pythonhosted.org/packages/84/c3/efa6f5e18ae9f144ba31b051d270e49ee9792f4b37f7707d92e84485d215/cctrial-1.2.5-py2-none-any.whl" } ], "1.2.6": [ { "comment_text": "", "digests": { "md5": "a57f7845e16d941f91c48f92dddd9df2", "sha256": "e982dabc463c936b663122d82df0bad318b20b6be4502d38f0fc06adb61d3ff6" }, "downloads": -1, "filename": "cctrial-1.2.6-py2-none-any.whl", "has_sig": false, "md5_digest": "a57f7845e16d941f91c48f92dddd9df2", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 14167, "upload_time": "2016-02-28T10:59:35", "url": "https://files.pythonhosted.org/packages/e1/49/247c8fd711196e1d408a38c9d6bc960a83379e22b24edada5b4d27db722e/cctrial-1.2.6-py2-none-any.whl" } ], "1.2.7": [ { "comment_text": "", "digests": { "md5": "11fd8e1c764eb66804f02b18ef2c5a68", "sha256": "a12be9f949ee336175498c39a0907327c97db8cdd4bdcb3437b93de87a8d433e" }, "downloads": -1, "filename": "cctrial-1.2.7-py2-none-any.whl", "has_sig": false, "md5_digest": "11fd8e1c764eb66804f02b18ef2c5a68", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 14352, "upload_time": "2016-02-28T15:29:10", "url": "https://files.pythonhosted.org/packages/39/06/b9e5199d7e1d92aa654f0b1fb2b8d71510c057c7456e9fcb26727c7afbf4/cctrial-1.2.7-py2-none-any.whl" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "11fd8e1c764eb66804f02b18ef2c5a68", "sha256": "a12be9f949ee336175498c39a0907327c97db8cdd4bdcb3437b93de87a8d433e" }, "downloads": -1, "filename": "cctrial-1.2.7-py2-none-any.whl", "has_sig": false, "md5_digest": "11fd8e1c764eb66804f02b18ef2c5a68", "packagetype": "bdist_wheel", "python_version": "2.7", "requires_python": null, "size": 14352, "upload_time": "2016-02-28T15:29:10", "url": "https://files.pythonhosted.org/packages/39/06/b9e5199d7e1d92aa654f0b1fb2b8d71510c057c7456e9fcb26727c7afbf4/cctrial-1.2.7-py2-none-any.whl" } ] }