# Feather Test
Feather Test is an event-driven testing framework for Python, inspired by the unittest module but with enhanced features for parallel execution and customizable reporting.
## Features
- Event-driven architecture for flexible test execution and reporting
- Parallel test execution for improved performance
- Customizable reporters for tailored test output
- Command-line interface similar to unittest for ease of use
- Support for custom events during test execution
## Installation
You can install Feather Test using pip:
```bash
pip install feather-test
```
## Usage
### Command-line Interface
Feather Test can be run from the command line, similar to unittest:
```bash
feather [options] [start_directory]
```
Options:
- `-f`, `--failfast`: Stop on first fail or error
- `-c`, `--catch`: Catch control-C and display results
- `-k PROCESSES`, `--processes PROCESSES`: Number of processes to use
- `-r REPORTER`, `--reporter REPORTER`: Reporter to use (default: DefaultReporter)
- `-p PATTERN`, `--pattern PATTERN`: Pattern to match test files (default: test*.py)
You can also pass reporter-specific arguments by prefixing them with the reporter name:
```bash
feather -r CustomReporter --customreporter-output-file report.txt --customreporter-verbose
```
### Writing Tests
Tests are written similarly to unittest, but inherit from \`EventDrivenTestCase\`:
```python
from feather_test import EventDrivenTestCase
class MyTest(EventDrivenTestCase):
def test_example(self):
self.assertTrue(True)
def test_custom_event(self):
self.event_publisher.publish('custom_event', self.correlation_id,
data='Custom event data')
self.assertEqual(1, 1)
```
### Custom Reporters
You can create custom reporters by inheriting from \`BaseReporter\`:
```python
from feather_test.event_driven_unittest import BaseReporter
class CustomReporter(BaseReporter):
def __init__(self, output_file=None, verbose=False):
self.output_file = output_file
self.verbose = verbose
self.total_tests = 0
self.passed_tests = 0
def on_test_run_start(self, correlation_id, run_id):
print(f"Test run started (Run ID: {run_id}")
def on_test_success(self, correlation_id, test_name, class_name, module_name):
self.passed_tests += 1
if self.verbose:
print(f"Test passed: {module_name}.{class_name}.{test_name}")
def on_test_run_end(self, correlation_id, run_id):
print(f"Tests completed. Passed: {self.passed_tests}/{self.total_tests}")
if self.output_file:
with open(self.output_file, 'w') as f:
f.write(f"Passed: {self.passed_tests}/{self.total_tests}")
```
### Programmatic Usage
You can also use Feather Test programmatically:
```python
from feather_test import EventDrivenTestRunner
import unittest
def run_tests():
suite = unittest.TestSuite()
suite.addTest(unittest.TestLoader().loadTestsFromTestCase(MyTest))
runner = EventDrivenTestRunner(processes=2, verbosity=2, reporters=['CustomReporter'])
runner.run(suite)
if __name__ == '__main__':
run_tests()
```
## Events
Feather Test emits various events during the test execution process. Custom reporters can listen for these events to provide detailed and customized test reports. Here's a list of all events that can be emitted:
1. `test_run_start`: Emitted when the entire test run begins.
- Data: `run_id`
2. `test_run_end`: Emitted when the entire test run completes.
- Data: `run_id`
3. `test_start`: Emitted when an individual test method starts.
- Data: `test_name`, `class_name`, `module_name`
4. `test_end`: Emitted when an individual test method ends.
- Data: `test_name`, `class_name`, `module_name`
5. `test_success`: Emitted when a test passes successfully.
- Data: `test_name`, `class_name`, `module_name`
6. `test_failure`: Emitted when a test fails.
- Data: `test_name`, `class_name`, `module_name`, `failure` (error message and traceback)
7. `test_error`: Emitted when a test raises an unexpected exception.
- Data: `test_name`, `class_name`, `module_name`, `error` (error message and traceback)
8. `test_skip`: Emitted when a test is skipped.
- Data: `test_name`, `class_name`, `module_name`, `reason`
9. `test_setup`: Emitted when the setUp method of a test case is called.
- Data: `test_name`
10. `test_teardown`: Emitted when the tearDown method of a test case is called.
- Data: `test_name`
11. `test_run_error`: Emitted if there's an error in the test running process itself.
- Data: `error` (error message and traceback)
Custom events can also be emitted from within tests using the `self.event_publisher.publish()` method. These events will be passed to reporters with whatever data is provided.
When creating custom reporters, you can define methods to handle these events. The method names should be in the format `on_<event_name>`. For example, to handle the `test_start` event, you would define an `on_test_start` method in your reporter class.
### Emitting Custom Events
You can emit custom events from within your tests using the `event_publisher`:
```python
class MyTest(EventDrivenTestCase):
def test_example(self):
self.event_publisher.publish('my_custom_event', self.correlation_id,
custom_data='Some interesting information')
self.assertTrue(True)
```
Custom reporters can then handle these events by defining an `on_my_custom_event` method.
# Third-Party Extensions for Feather Test
Feather Test supports third-party TestServers and Reporters, allowing the community to extend the framework's functionality.
## Naming Convention
All third-party packages for Feather Test must follow this specific naming convention:
- For TestServers:
- Package name: `feather-test-server-<name>`
- Python module name: `feather_test_server_<name>`
- Main class name: `<Name>TestServer`
- For Reporters:
- Package name: `feather-test-reporter-<name>`
- Python module name: `feather_test_reporter_<name>`
- Main class name: `<Name>Reporter`
This convention helps maintain consistency, avoid naming conflicts, and makes the purpose of each package immediately clear.
## Creating a Third-Party TestServer Package
1. Create a new Python package named `feather-test-server-<name>` (e.g., `feather-test-server-custom`).
2. Name your Python module `feather_test_server_<name>` (e.g., `feather_test_server_custom`).
3. Implement your main TestServer class as `<Name>TestServer` (e.g., `CustomTestServer`) by subclassing `feather_test.test_server.TestServer`.
4. Publish your package to PyPI.
Example structure:
```
feather-test-server-custom/
feather_test_server_custom/
__init__.py
custom_test_server.py
setup.py
README.md
LICENSE
```
## Creating a Third-Party Reporter Package
1. Create a new Python package named `feather-test-reporter-<name>` (e.g., `feather-test-reporter-custom`).
2. Name your Python module `feather_test_reporter_<name>` (e.g., `feather_test_reporter_custom`).
3. Implement your main Reporter class as `<Name>Reporter` (e.g., `CustomReporter`) by subclassing `feather_test.reporters.base_reporter.BaseReporter`.
4. Publish your package to PyPI.
Example structure:
```
feather-test-reporter-custom/
feather_test_reporter_custom/
__init__.py
custom_reporter.py
setup.py
README.md
LICENSE
```
## Using Third-Party Extensions
After installing third-party packages, you can use them as follows:
1. Command line:
```
feather -s CustomTestServer -r CustomReporter
```
2. Programmatically:
```python
from feather_test import EventDrivenTestRunner
runner = EventDrivenTestRunner(processes=2, reporters=['CustomReporter'], server='CustomTestServer')
runner.discover_and_run('tests')
```
Note: When using third-party extensions, you only need to specify the class name. The framework will automatically determine the correct module to import based on the naming convention.
For more details on creating custom TestServers and Reporters, refer to the respective documentation sections.
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
## License
This project is licensed under the MIT License.
Raw data
{
"_id": null,
"home_page": "https://github.com/fictitiouswizard/feather-test",
"name": "feather-test",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.8",
"maintainer_email": null,
"keywords": "testing, unittest, event-driven",
"author": "Jason Sanders",
"author_email": "me@fictitiouswizard.com",
"download_url": "https://files.pythonhosted.org/packages/3b/e8/ebe8c2d526316489109e4f5837cb894b23b320602676629fca144c6c290b/feather_test-0.1.4.tar.gz",
"platform": null,
"description": "# Feather Test\n\nFeather Test is an event-driven testing framework for Python, inspired by the unittest module but with enhanced features for parallel execution and customizable reporting.\n\n## Features\n\n- Event-driven architecture for flexible test execution and reporting\n- Parallel test execution for improved performance\n- Customizable reporters for tailored test output\n- Command-line interface similar to unittest for ease of use\n- Support for custom events during test execution\n\n## Installation\n\nYou can install Feather Test using pip:\n\n```bash\npip install feather-test\n```\n\n## Usage\n\n### Command-line Interface\n\nFeather Test can be run from the command line, similar to unittest:\n\n```bash\nfeather [options] [start_directory]\n```\n\nOptions:\n- `-f`, `--failfast`: Stop on first fail or error\n- `-c`, `--catch`: Catch control-C and display results\n- `-k PROCESSES`, `--processes PROCESSES`: Number of processes to use\n- `-r REPORTER`, `--reporter REPORTER`: Reporter to use (default: DefaultReporter)\n- `-p PATTERN`, `--pattern PATTERN`: Pattern to match test files (default: test*.py)\n\nYou can also pass reporter-specific arguments by prefixing them with the reporter name:\n\n```bash\nfeather -r CustomReporter --customreporter-output-file report.txt --customreporter-verbose\n```\n\n### Writing Tests\n\nTests are written similarly to unittest, but inherit from \\`EventDrivenTestCase\\`:\n\n```python\nfrom feather_test import EventDrivenTestCase\n\nclass MyTest(EventDrivenTestCase):\n def test_example(self):\n self.assertTrue(True)\n\n def test_custom_event(self):\n self.event_publisher.publish('custom_event', self.correlation_id, \n data='Custom event data')\n self.assertEqual(1, 1)\n```\n\n### Custom Reporters\n\nYou can create custom reporters by inheriting from \\`BaseReporter\\`:\n\n```python\nfrom feather_test.event_driven_unittest import BaseReporter\n\nclass CustomReporter(BaseReporter):\n def __init__(self, output_file=None, verbose=False):\n self.output_file = output_file\n self.verbose = verbose\n self.total_tests = 0\n self.passed_tests = 0\n\n def on_test_run_start(self, correlation_id, run_id):\n print(f\"Test run started (Run ID: {run_id}\")\n\n def on_test_success(self, correlation_id, test_name, class_name, module_name):\n self.passed_tests += 1\n if self.verbose:\n print(f\"Test passed: {module_name}.{class_name}.{test_name}\")\n\n def on_test_run_end(self, correlation_id, run_id):\n print(f\"Tests completed. Passed: {self.passed_tests}/{self.total_tests}\")\n if self.output_file:\n with open(self.output_file, 'w') as f:\n f.write(f\"Passed: {self.passed_tests}/{self.total_tests}\")\n```\n\n### Programmatic Usage\n\nYou can also use Feather Test programmatically:\n\n```python\nfrom feather_test import EventDrivenTestRunner\nimport unittest\n\ndef run_tests():\n suite = unittest.TestSuite()\n suite.addTest(unittest.TestLoader().loadTestsFromTestCase(MyTest))\n\n runner = EventDrivenTestRunner(processes=2, verbosity=2, reporters=['CustomReporter'])\n runner.run(suite)\n\nif __name__ == '__main__':\n run_tests()\n```\n\n## Events\n\nFeather Test emits various events during the test execution process. Custom reporters can listen for these events to provide detailed and customized test reports. Here's a list of all events that can be emitted:\n\n1. `test_run_start`: Emitted when the entire test run begins.\n - Data: `run_id`\n\n2. `test_run_end`: Emitted when the entire test run completes.\n - Data: `run_id`\n\n3. `test_start`: Emitted when an individual test method starts.\n - Data: `test_name`, `class_name`, `module_name`\n\n4. `test_end`: Emitted when an individual test method ends.\n - Data: `test_name`, `class_name`, `module_name`\n\n5. `test_success`: Emitted when a test passes successfully.\n - Data: `test_name`, `class_name`, `module_name`\n\n6. `test_failure`: Emitted when a test fails.\n - Data: `test_name`, `class_name`, `module_name`, `failure` (error message and traceback)\n\n7. `test_error`: Emitted when a test raises an unexpected exception.\n - Data: `test_name`, `class_name`, `module_name`, `error` (error message and traceback)\n\n8. `test_skip`: Emitted when a test is skipped.\n - Data: `test_name`, `class_name`, `module_name`, `reason`\n\n9. `test_setup`: Emitted when the setUp method of a test case is called.\n - Data: `test_name`\n\n10. `test_teardown`: Emitted when the tearDown method of a test case is called.\n - Data: `test_name`\n\n11. `test_run_error`: Emitted if there's an error in the test running process itself.\n - Data: `error` (error message and traceback)\n\nCustom events can also be emitted from within tests using the `self.event_publisher.publish()` method. These events will be passed to reporters with whatever data is provided.\n\nWhen creating custom reporters, you can define methods to handle these events. The method names should be in the format `on_<event_name>`. For example, to handle the `test_start` event, you would define an `on_test_start` method in your reporter class.\n\n### Emitting Custom Events\n\nYou can emit custom events from within your tests using the `event_publisher`:\n\n```python\nclass MyTest(EventDrivenTestCase):\n def test_example(self):\n self.event_publisher.publish('my_custom_event', self.correlation_id,\n custom_data='Some interesting information')\n self.assertTrue(True)\n```\n\nCustom reporters can then handle these events by defining an `on_my_custom_event` method.\n\n# Third-Party Extensions for Feather Test\n\nFeather Test supports third-party TestServers and Reporters, allowing the community to extend the framework's functionality.\n\n## Naming Convention\n\nAll third-party packages for Feather Test must follow this specific naming convention:\n\n- For TestServers:\n - Package name: `feather-test-server-<name>`\n - Python module name: `feather_test_server_<name>`\n - Main class name: `<Name>TestServer`\n\n- For Reporters:\n - Package name: `feather-test-reporter-<name>`\n - Python module name: `feather_test_reporter_<name>`\n - Main class name: `<Name>Reporter`\n\nThis convention helps maintain consistency, avoid naming conflicts, and makes the purpose of each package immediately clear.\n\n## Creating a Third-Party TestServer Package\n\n1. Create a new Python package named `feather-test-server-<name>` (e.g., `feather-test-server-custom`).\n2. Name your Python module `feather_test_server_<name>` (e.g., `feather_test_server_custom`).\n3. Implement your main TestServer class as `<Name>TestServer` (e.g., `CustomTestServer`) by subclassing `feather_test.test_server.TestServer`.\n4. Publish your package to PyPI.\n\nExample structure:\n\n```\nfeather-test-server-custom/\n feather_test_server_custom/\n __init__.py\n custom_test_server.py\n setup.py\n README.md\n LICENSE\n```\n## Creating a Third-Party Reporter Package\n\n1. Create a new Python package named `feather-test-reporter-<name>` (e.g., `feather-test-reporter-custom`).\n2. Name your Python module `feather_test_reporter_<name>` (e.g., `feather_test_reporter_custom`).\n3. Implement your main Reporter class as `<Name>Reporter` (e.g., `CustomReporter`) by subclassing `feather_test.reporters.base_reporter.BaseReporter`.\n4. Publish your package to PyPI.\n\nExample structure:\n\n```\nfeather-test-reporter-custom/\n feather_test_reporter_custom/\n __init__.py\n custom_reporter.py\n setup.py\n README.md\n LICENSE\n```\n\n## Using Third-Party Extensions\n\nAfter installing third-party packages, you can use them as follows:\n\n1. Command line:\n ```\n feather -s CustomTestServer -r CustomReporter\n ```\n\n2. Programmatically:\n ```python\n from feather_test import EventDrivenTestRunner\n \n runner = EventDrivenTestRunner(processes=2, reporters=['CustomReporter'], server='CustomTestServer')\n runner.discover_and_run('tests')\n ```\n\nNote: When using third-party extensions, you only need to specify the class name. The framework will automatically determine the correct module to import based on the naming convention.\n\nFor more details on creating custom TestServers and Reporters, refer to the respective documentation sections.\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## License\n\nThis project is licensed under the MIT License.",
"bugtrack_url": null,
"license": "MIT",
"summary": "Feather-test: A event-driven testing framework for Python",
"version": "0.1.4",
"project_urls": {
"Bug Tracker": "https://github.com/fictitiouswizard/feather-test/issues",
"Documentation": "https://feather-test.readthedocs.io",
"Homepage": "https://github.com/fictitiouswizard/feather-test",
"Repository": "https://github.com/fictitiouswizard/feather-test"
},
"split_keywords": [
"testing",
" unittest",
" event-driven"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "4b5a10a66c5aa657f1e3b0c00227198b8e8941991044d5cc4b54ee47484403e0",
"md5": "6da7d02b94656e718ab4c6cebd217ca7",
"sha256": "d8058f8dc5cbe7727451d1e8c6b676547686454acb212094e416de3a196d2237"
},
"downloads": -1,
"filename": "feather_test-0.1.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "6da7d02b94656e718ab4c6cebd217ca7",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.8",
"size": 24262,
"upload_time": "2024-09-18T01:23:34",
"upload_time_iso_8601": "2024-09-18T01:23:34.798671Z",
"url": "https://files.pythonhosted.org/packages/4b/5a/10a66c5aa657f1e3b0c00227198b8e8941991044d5cc4b54ee47484403e0/feather_test-0.1.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "3be8ebe8c2d526316489109e4f5837cb894b23b320602676629fca144c6c290b",
"md5": "2ac02a70b74cbe8fcfb04e3463e9b7c1",
"sha256": "9743cbf3193279f2e69bcd38ec54dbe40980d31c441502b908dfe7044f376dae"
},
"downloads": -1,
"filename": "feather_test-0.1.4.tar.gz",
"has_sig": false,
"md5_digest": "2ac02a70b74cbe8fcfb04e3463e9b7c1",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.8",
"size": 20212,
"upload_time": "2024-09-18T01:23:36",
"upload_time_iso_8601": "2024-09-18T01:23:36.258053Z",
"url": "https://files.pythonhosted.org/packages/3b/e8/ebe8c2d526316489109e4f5837cb894b23b320602676629fca144c6c290b/feather_test-0.1.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-09-18 01:23:36",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "fictitiouswizard",
"github_project": "feather-test",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "feather-test"
}