{"id":23722659,"url":"https://github.com/remko/pycotap","last_synced_at":"2025-06-22T16:35:22.905Z","repository":{"id":26104075,"uuid":"29548255","full_name":"remko/pycotap","owner":"remko","description":"Tiny Python TAP Test Runner","archived":false,"fork":false,"pushed_at":"2023-04-29T15:55:35.000Z","size":47,"stargazers_count":5,"open_issues_count":3,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-13T09:47:39.470Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/remko.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-01-20T19:39:27.000Z","updated_at":"2022-08-01T02:16:25.000Z","dependencies_parsed_at":"2022-07-29T13:09:16.481Z","dependency_job_id":null,"html_url":"https://github.com/remko/pycotap","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remko%2Fpycotap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remko%2Fpycotap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remko%2Fpycotap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remko%2Fpycotap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/remko","download_url":"https://codeload.github.com/remko/pycotap/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":231926369,"owners_count":18447052,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-30T23:55:16.771Z","updated_at":"2024-12-30T23:55:17.288Z","avatar_url":"https://github.com/remko.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pycotap: Tiny Python TAP Test Runner\n\n[![Build](https://github.com/remko/pycotap/actions/workflows/build.yml/badge.svg)](https://github.com/remko/pycotap/actions/workflows/build.yml)\n[![Coverage](https://remko.github.io/pycotap/ci/coverage/coverage.svg)](https://remko.github.io/pycotap/ci/coverage)\n[![PyPI\nversion](https://badge.fury.io/py/pycotap.svg)](https://badge.fury.io/py/pycotap)\n\n`pycotap` is a simple Python test runner for `unittest` that outputs\n[Test Anything Protocol](http://testanything.org) results to standard\noutput (similar to what [`tape`](https://www.npmjs.com/package/tape)\ndoes for JavaScript).\n\nContrary to other TAP runners for Python, `pycotap` ...\n\n- ... prints TAP (and *only* TAP) to standard output instead of to a\n  separate file, allowing you to pipe it directly to TAP pretty printers\n  and processors (such as the ones listed on the [`tape`\n  page](https://www.npmjs.com/package/tape#pretty-reporters)). By piping\n  it to other consumers, you can avoid the need to add specific test\n  runners to your test code. Since the TAP results are printed as they\n  come in, the consumers can directly display results while the tests\n  are run.\n- ... only contains a TAP reporter, so no parsers, no frameworks, no\n  dependencies, ...\n- ... is configurable: you can choose how you want the test output and\n  test result diagnostics to end up in your TAP output (as TAP\n  diagnostics, YAML blocks, or attachments). The defaults are optimized\n  for a [Jenkins](http://jenkins-ci.org) based flow.\n\n\u003e Nice work with pycotap! I took a \"kitchen sink\" approach with tappy so\n\u003e I'm glad someone made a no dependency TAP unittest runner. :) -- [Matt\n\u003e Layman](http://www.mattlayman.com), author of\n\u003e [tappy](http://tappy.readthedocs.org/en/latest/)\n\n## Installation\n\nYou can install the package directly from\n[PIP](https://pypi.python.org):\n\n    pip install pycotap\n\nAlternatively, you can build and install the package yourself:\n\n    python setup.py install\n\nSince the module just consists of one file, you can also just drop the\nfile into your project somewhere.\n\n## Usage\n\nCreate a test suite, and run it with `-mpycotap` flag.\n\nFor example, given the following test suite in `test_example.py`:\n\n``` python\nimport unittest\n\nclass MyTests(unittest.TestCase):\n  def test_that_it_passes(self):\n    self.assertEqual(0, 0)\n\n  @unittest.skip(\"not finished yet\")\n  def test_that_it_skips(self): \n    raise Exception(\"Does not happen\")\n\n  def test_that_it_fails(self):\n    self.assertEqual(1, 0)\n```\n\nRunning the test prints the TAP results to standard output:\n\n    $ python -mpycotap test_example\n    not ok 1 __main__.MyTests.test_that_it_fails\n    ok 2 __main__.MyTests.test_that_it_passes\n    ok 3 __main__.MyTests.test_that_it_skips # Skipped: not finished yet\n    1..3\n\nAlternatively, you can pipe the test to any TAP pretty printer, such as\n[faucet](https://github.com/substack/faucet) or\n[tap-dot](https://github.com/scottcorgan/tap-dot):\n\n    $ python -mpycotap test_example  | faucet\n    ⨯ __main__.MyTests.test_that_it_fails\n    ✓ __main__.MyTests.test_that_it_passes\n    ✓ __main__.MyTests.test_that_it_skips # Skipped: not finished yet\n    ⨯ fail  1\n\n\n    $ python -mpycotap test_example  | tap-dot \n    x  ..  \n\n      3 tests\n      2 passed\n      1 failed  \n\n      Failed Tests:   There was 1 failure\n        x __main__.MyTests.test_that_it_fails\n\n### Bring your own `__main__`\n\nYou can create a `TAPTestRunner` yourself (e.g. to pass custom\nparameters), and use it to drive your own main function.\n\nFor example, the following can be added to the test example suite above\nto create a runnable Python script:\n\n``` python\nif __name__ == '__main__':\n  from pycotap import TAPTestRunner\n  suite = unittest.TestLoader().loadTestsFromTestCase(MyTests)\n  TAPTestRunner().run(suite)\n```\n\nThis script can now be run:\n\n    $ python ./test_example.py \n    not ok 1 __main__.MyTests.test_that_it_fails\n    ok 2 __main__.MyTests.test_that_it_passes\n    ok 3 __main__.MyTests.test_that_it_skips # Skipped: not finished yet\n    1..3\n\n## API\n\n### `TAPTestRunner([message_log], [test_output_log])`\n\n- `message_log` (Optional; Default: `LogMode.LogToYAML`):  \n  What to do with test messages (e.g. assertion failure details). See\n  `LogMode` for possible values.\n- `test_output_log` (Optional; Default: `LogMode.LogToDiagnostics`):  \n  What to do with output printed by the tests. See `LogMode` for\n  possible values.\n\n### `LogMode`\n\nEnumeration of different destinations to log information. Possible\nvalues:\n\n- `LogMode.LogToError`: Log all output to standard error. This means no\n  output information will end up in the TAP stream, and so will not be\n  processed by any processors.\n- `LogMode.LogToDiagnostics`: Put output in a diagnostics message after\n  the test result. This means all output will end up in the TAP stream.\n  How this is displayed depends on the processor.\n- `LogMode.LogToYAML`: Put output in a YAML block.\n- `LogMode.LogToAttachment`: Put output in a downloadable attachment in\n  a YAML block. This is an extension supported by e.g.\n  [`tap4j`](http://tap4j.org).\n\n## Changelog\n\n### 1.3.0 (2023-04-28)\n\n- Fix problem with garbage output (thanks [wjt](https://github.com/wjt))\n\n### 1.1.0 (2015-07-29)\n\n- Don't print message for expected failures\n- Fix problem with unexpected success\n\n### 1.0.1 (2015-07-28)\n\n- Fix problem with tests that cache `sys.std*` output streams\n\n### 1.0.0 (2015-01-24)\n\n- Initial stable version\n\n### 0.1.0 (2015-01-21)\n\n- Initial version\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fremko%2Fpycotap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fremko%2Fpycotap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fremko%2Fpycotap/lists"}