emtest 0.0.1__py3-none-any.whl → 0.0.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of emtest might be problematic. Click here for more details.
- _auto_run_with_pytest/__init__.py +32 -0
- emtest/__init__.py +9 -2
- emtest/pytest_utils.py +60 -20
- emtest/testing_utils.py +62 -6
- emtest-0.0.4.dist-info/METADATA +101 -0
- emtest-0.0.4.dist-info/RECORD +10 -0
- emtest-0.0.4.dist-info/licenses/LICENSE +18 -0
- emtest-0.0.1.dist-info/licenses/LICENCE → emtest-0.0.4.dist-info/licenses/LICENSE-CC0 +2 -2
- emtest-0.0.4.dist-info/top_level.txt +2 -0
- emtest-0.0.1.dist-info/METADATA +0 -49
- emtest-0.0.1.dist-info/RECORD +0 -8
- emtest-0.0.1.dist-info/top_level.txt +0 -1
- {emtest-0.0.1.dist-info → emtest-0.0.4.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Rerun the orignially executed python script in pytest instead of python."""
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
from emtest import run_pytest
|
|
7
|
+
|
|
8
|
+
# Configuration for standalone execution
|
|
9
|
+
|
|
10
|
+
path_parts = sys.argv[0].split(os.sep)
|
|
11
|
+
if not (
|
|
12
|
+
path_parts[-1] == "pytest"
|
|
13
|
+
or (
|
|
14
|
+
len(path_parts) > 1
|
|
15
|
+
and path_parts[-2] == "pytest"
|
|
16
|
+
and path_parts[-1] == "__main__.py"
|
|
17
|
+
)
|
|
18
|
+
):
|
|
19
|
+
test_file = os.path.abspath(sys.argv[0])
|
|
20
|
+
pytest_args = sys.argv[1:]
|
|
21
|
+
# print("RERUNNING IN PYTEST:", test_file)
|
|
22
|
+
|
|
23
|
+
# Use emtest's custom test runner with specific settings:
|
|
24
|
+
run_pytest(
|
|
25
|
+
test_path=test_file, # Run tests in this file
|
|
26
|
+
pytest_args=pytest_args,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
sys.exit(-1)
|
|
30
|
+
else:
|
|
31
|
+
# print("ALREADY RUNNING IN PYTEST")
|
|
32
|
+
pass
|
emtest/__init__.py
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
|
-
from .pytest_utils import run_pytest, configure_pytest_reporter
|
|
1
|
+
from .pytest_utils import run_pytest, configure_pytest_reporter, env_vars
|
|
2
2
|
from .testing_utils import (
|
|
3
3
|
add_path_to_python,
|
|
4
4
|
assert_is_loaded_from_source,
|
|
5
5
|
polite_wait,
|
|
6
6
|
await_thread_cleanup,
|
|
7
|
-
|
|
7
|
+
get_thread_names,
|
|
8
|
+
set_env_var,
|
|
9
|
+
are_we_in_docker,
|
|
10
|
+
make_dir,
|
|
11
|
+
delete_path,
|
|
12
|
+
ensure_dirs_exist,
|
|
13
|
+
ensure_dir_exists,
|
|
14
|
+
)
|
emtest/pytest_utils.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
from .testing_utils import set_env_var
|
|
4
4
|
import os
|
|
5
5
|
import sys
|
|
6
6
|
from typing import Any, Optional
|
|
@@ -9,24 +9,29 @@ from _pytest.config import Config
|
|
|
9
9
|
from _pytest.reports import TestReport
|
|
10
10
|
from termcolor import colored
|
|
11
11
|
|
|
12
|
+
from environs import Env
|
|
13
|
+
env_vars = Env()
|
|
14
|
+
|
|
15
|
+
|
|
12
16
|
class MinimalReporter(TerminalReporter):
|
|
13
17
|
"""Custom pytest reporter that provides clean, minimal output with colored symbols.
|
|
14
|
-
|
|
18
|
+
|
|
15
19
|
This reporter suppresses most default pytest output and displays only:
|
|
16
20
|
- ✓ for passed tests (green)
|
|
17
21
|
- ✗ for failed tests (red)
|
|
18
22
|
- - for skipped tests (yellow)
|
|
19
23
|
"""
|
|
20
|
-
|
|
24
|
+
|
|
25
|
+
def __init__(self, config: Config, print_errors: bool = True) -> None:
|
|
21
26
|
super().__init__(config)
|
|
22
27
|
self._tw.hasmarkup = True # enables colored output safely
|
|
28
|
+
self.print_errors = print_errors
|
|
29
|
+
self.current_test_file = ""
|
|
23
30
|
|
|
24
|
-
def
|
|
25
|
-
|
|
26
|
-
pass # override all default output methods
|
|
31
|
+
def report_collect(self, final: bool = False) -> None:
|
|
32
|
+
pass
|
|
27
33
|
|
|
28
|
-
def
|
|
29
|
-
"""Override summary writing to suppress it."""
|
|
34
|
+
def pytest_collection(self) -> None:
|
|
30
35
|
pass
|
|
31
36
|
|
|
32
37
|
def pytest_sessionstart(self, session: Any) -> None:
|
|
@@ -37,6 +42,10 @@ class MinimalReporter(TerminalReporter):
|
|
|
37
42
|
def pytest_runtest_logstart(self, nodeid: str, location: Any) -> None:
|
|
38
43
|
"""Override test start logging to suppress it."""
|
|
39
44
|
# print("pytest_runtest_logstart")
|
|
45
|
+
current_test_file = os.path.basename(location[0]).strip(".py")
|
|
46
|
+
if current_test_file != self.current_test_file:
|
|
47
|
+
self.current_test_file = current_test_file
|
|
48
|
+
print(f"\n{self.current_test_file}")
|
|
40
49
|
pass # suppress test start lines
|
|
41
50
|
|
|
42
51
|
def pytest_runtest_logreport(self, report: TestReport) -> None:
|
|
@@ -46,12 +55,20 @@ class MinimalReporter(TerminalReporter):
|
|
|
46
55
|
|
|
47
56
|
test_name = report.nodeid.split("::")[-1]
|
|
48
57
|
if report.passed:
|
|
49
|
-
|
|
58
|
+
self.write("✓", green=True)
|
|
59
|
+
# symbol = colored("✓", "green")
|
|
50
60
|
elif report.failed:
|
|
51
|
-
|
|
61
|
+
self.write("✗", red=True)
|
|
62
|
+
# symbol = colored("✗", "red")
|
|
52
63
|
elif report.skipped:
|
|
53
|
-
|
|
54
|
-
|
|
64
|
+
self.write("-", yellow=True)
|
|
65
|
+
# symbol = colored("-", "yellow")
|
|
66
|
+
# self.write(f"{symbol} {test_name}")
|
|
67
|
+
|
|
68
|
+
self.write(f" {test_name}\n")
|
|
69
|
+
|
|
70
|
+
if self.print_errors and report.failed:
|
|
71
|
+
print(colored(report.longreprtext, "red"))
|
|
55
72
|
|
|
56
73
|
def summary_stats(self) -> None:
|
|
57
74
|
"""Override result counts to suppress them."""
|
|
@@ -62,30 +79,53 @@ class MinimalReporter(TerminalReporter):
|
|
|
62
79
|
pass # suppress final summary output
|
|
63
80
|
|
|
64
81
|
|
|
65
|
-
|
|
82
|
+
# Environment Variable and CLI option to deactivate MinimalReporter
|
|
83
|
+
PYTEST_STANDARD_OUTPUT_ENV = "DEFAULT_TERMINAL_REPORTER"
|
|
84
|
+
PYTEST_STANDARD_OUTPUT_OPT = "--default-terminal-reporter"
|
|
85
|
+
if PYTEST_STANDARD_OUTPUT_OPT in sys.argv:
|
|
86
|
+
set_env_var(PYTEST_STANDARD_OUTPUT_ENV, "1", True)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def configure_pytest_reporter(config: Config, print_errors=True) -> None:
|
|
66
90
|
"""Configure the minimal reporter if terminalreporter plugin is disabled.
|
|
67
|
-
|
|
91
|
+
|
|
68
92
|
Args:
|
|
69
93
|
config: Pytest configuration object
|
|
70
94
|
"""
|
|
95
|
+
if env_vars.bool(PYTEST_STANDARD_OUTPUT_ENV, default=False):
|
|
96
|
+
return
|
|
97
|
+
minimal_reporter = MinimalReporter(config, print_errors=print_errors)
|
|
71
98
|
# if terminalreporter plugin is disabled
|
|
72
99
|
if "no:terminalreporter" in config.option.plugins:
|
|
73
100
|
pluginmanager = config.pluginmanager
|
|
74
|
-
pluginmanager.register(
|
|
101
|
+
pluginmanager.register(minimal_reporter, "minimal-reporter")
|
|
102
|
+
|
|
103
|
+
if config.pluginmanager.has_plugin("terminalreporter"):
|
|
104
|
+
reporter = config.pluginmanager.get_plugin("terminalreporter")
|
|
105
|
+
config.pluginmanager.unregister(reporter, "terminalreporter")
|
|
106
|
+
config.pluginmanager.register(minimal_reporter, "terminalreporter")
|
|
75
107
|
|
|
76
108
|
|
|
77
|
-
def run_pytest(
|
|
109
|
+
def run_pytest(
|
|
110
|
+
test_path: str,
|
|
111
|
+
breakpoints: bool = False,
|
|
112
|
+
enable_print: bool = False,
|
|
113
|
+
pytest_args: list[str] | None = None
|
|
114
|
+
) -> None:
|
|
78
115
|
"""Run pytest with customizable options for output control and debugging.
|
|
79
|
-
|
|
116
|
+
|
|
80
117
|
Args:
|
|
81
118
|
test_path: Path to the test file or directory to run
|
|
82
119
|
breakpoints: If True, enables pytest debugger (--pdb) on failures
|
|
83
120
|
deactivate_pytest_output: If True, uses minimal reporter instead of default output
|
|
84
121
|
enable_print: If True, enables print statements in tests (-s flag)
|
|
85
122
|
"""
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
123
|
+
if pytest_args:
|
|
124
|
+
args = pytest_args
|
|
125
|
+
if PYTEST_STANDARD_OUTPUT_OPT in args:
|
|
126
|
+
args.remove(PYTEST_STANDARD_OUTPUT_OPT)
|
|
127
|
+
else:
|
|
128
|
+
args = []
|
|
89
129
|
if enable_print:
|
|
90
130
|
args.append("-s") # -s disables output capturing
|
|
91
131
|
if breakpoints:
|
emtest/testing_utils.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
import sys
|
|
5
|
+
import shutil
|
|
5
6
|
import threading
|
|
6
7
|
import time
|
|
7
8
|
from time import sleep
|
|
@@ -11,15 +12,20 @@ from tqdm import TMonitor, tqdm
|
|
|
11
12
|
from types import ModuleType
|
|
12
13
|
|
|
13
14
|
|
|
15
|
+
def are_we_in_docker() -> bool:
|
|
16
|
+
"""Check if this code is running in a docker container."""
|
|
17
|
+
return os.path.exists('/.dockerenv')
|
|
18
|
+
|
|
19
|
+
|
|
14
20
|
def add_path_to_python(src_path: str) -> None:
|
|
15
21
|
"""Add a directory to the Python path for importing modules.
|
|
16
|
-
|
|
22
|
+
|
|
17
23
|
Removes the path if it already exists, then inserts it at the beginning
|
|
18
24
|
of sys.path to ensure it takes priority over installed packages.
|
|
19
|
-
|
|
25
|
+
|
|
20
26
|
Args:
|
|
21
27
|
src_path: Directory path to add to Python path
|
|
22
|
-
|
|
28
|
+
|
|
23
29
|
Raises:
|
|
24
30
|
FileNotFoundError: If the path doesn't exist
|
|
25
31
|
NotADirectoryError: If the path is not a directory
|
|
@@ -64,7 +70,7 @@ def assert_is_loaded_from_source(
|
|
|
64
70
|
|
|
65
71
|
def polite_wait(n_sec: int) -> None:
|
|
66
72
|
"""Wait for the given duration, displaying a progress bar.
|
|
67
|
-
|
|
73
|
+
|
|
68
74
|
Args:
|
|
69
75
|
n_sec: Number of seconds to wait
|
|
70
76
|
"""
|
|
@@ -75,10 +81,10 @@ def polite_wait(n_sec: int) -> None:
|
|
|
75
81
|
|
|
76
82
|
def await_thread_cleanup(timeout: int = 5) -> bool:
|
|
77
83
|
"""Wait for all threads to exit, with a timeout and progress bar.
|
|
78
|
-
|
|
84
|
+
|
|
79
85
|
Args:
|
|
80
86
|
timeout: Maximum seconds to wait for thread cleanup
|
|
81
|
-
|
|
87
|
+
|
|
82
88
|
Returns:
|
|
83
89
|
True if only the main thread remains, False if other threads persist
|
|
84
90
|
"""
|
|
@@ -95,4 +101,54 @@ def await_thread_cleanup(timeout: int = 5) -> bool:
|
|
|
95
101
|
|
|
96
102
|
return len(get_threads()) == 1
|
|
97
103
|
|
|
104
|
+
def get_thread_names():
|
|
105
|
+
"""Get a list of the names of all active threads."""
|
|
106
|
+
return [thread.name for thread in threading.enumerate()]
|
|
107
|
+
|
|
108
|
+
def set_env_var(name: str, value: str | bool | int, override: bool = True):
|
|
109
|
+
"""
|
|
110
|
+
Set an environment variable with optional overriding behavior.
|
|
98
111
|
|
|
112
|
+
Args:
|
|
113
|
+
name (str): The name of the environment variable to set.
|
|
114
|
+
value (str): The value to assign to the environment variable.
|
|
115
|
+
override (bool, optional): Whether to overwrite the variable if it is already set.
|
|
116
|
+
Defaults to False.
|
|
117
|
+
|
|
118
|
+
Behavior:
|
|
119
|
+
- If 'override' is True, the environment variable will always be set to 'value'.
|
|
120
|
+
- If 'override' is False, the variable will only be set if it is not already defined.
|
|
121
|
+
"""
|
|
122
|
+
if isinstance(value, bool):
|
|
123
|
+
value = int(value)
|
|
124
|
+
if isinstance(value, int):
|
|
125
|
+
value = str(value)
|
|
126
|
+
if override or name not in os.environ:
|
|
127
|
+
os.environ[name] = value
|
|
128
|
+
|
|
129
|
+
def make_dir(dir_path: str, clear_existing: bool = False) -> str:
|
|
130
|
+
"""Create a directory, handling the case where it already exists."""
|
|
131
|
+
if clear_existing and os.path.exists(dir_path):
|
|
132
|
+
shutil.rmtree(dir_path)
|
|
133
|
+
if not os.path.isdir(dir_path):
|
|
134
|
+
os.makedirs(dir_path)
|
|
135
|
+
return dir_path
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def delete_path(path: bool) -> bool:
|
|
139
|
+
"""Delete the specified file or folder."""
|
|
140
|
+
if os.path.isdir(path):
|
|
141
|
+
shutil.rmtree(path)
|
|
142
|
+
elif os.path.exists(path):
|
|
143
|
+
os.remove(path)
|
|
144
|
+
|
|
145
|
+
def ensure_dirs_exist(*dirs):
|
|
146
|
+
"""Ensure that all directories in the list exist."""
|
|
147
|
+
for dir in dirs:
|
|
148
|
+
os.makedirs(dir, exist_ok=True)
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def ensure_dir_exists(dir_path):
|
|
152
|
+
if not os.path.exists(dir_path):
|
|
153
|
+
os.makedirs(dir_path)
|
|
154
|
+
return dir_path
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: emtest
|
|
3
|
+
Version: 0.0.4
|
|
4
|
+
Summary: Testing utilities which I find useful.
|
|
5
|
+
Author-email: Emendir <dev@emendir.tech>
|
|
6
|
+
License-Expression: MIT-0 OR CC0-1.0
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Operating System :: OS Independent
|
|
9
|
+
Requires-Python: >=3.6
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
License-File: LICENSE-CC0
|
|
13
|
+
Requires-Dist: tqdm
|
|
14
|
+
Dynamic: license-file
|
|
15
|
+
|
|
16
|
+
# emtest - Python Testing Utilities
|
|
17
|
+
|
|
18
|
+
A Python package providing testing utilities.
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
### 🎨 Clean Test Output for Pytest
|
|
23
|
+
- **MinimalReporter**: Custom pytest reporter with clean, colored output using simple symbols (✓/✗/-)
|
|
24
|
+
- **Configurable Output**: Toggle between minimal and standard pytest output modes
|
|
25
|
+
|
|
26
|
+
### 🔧 Development Utilities
|
|
27
|
+
- **Source Path Management**: Dynamically add directories to Python path for testing source code
|
|
28
|
+
- **Module Source Validation**: Ensure modules are loaded from source directories (not installed packages)
|
|
29
|
+
- **Thread Cleanup Monitoring**: Wait for and verify proper thread cleanup in tests
|
|
30
|
+
|
|
31
|
+
### ⚡ Enhanced Test Execution
|
|
32
|
+
- **Dual Execution Pattern**: Run tests both as pytest tests and standalone Python scripts
|
|
33
|
+
- **Breakpoint Integration**: Easy debugging with pytest's `--pdb` integration
|
|
34
|
+
- **Progress Indicators**: Visual progress bars for waiting operations
|
|
35
|
+
|
|
36
|
+
## Installation
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
pip install emtest
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
See the `examples/` directory for complete working examples showing:
|
|
45
|
+
- Basic test setup with `conftest.py`
|
|
46
|
+
- Dual execution pattern implementation
|
|
47
|
+
- Source loading validation
|
|
48
|
+
- Thread cleanup testing
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
## Documentation
|
|
52
|
+
|
|
53
|
+
- [Full Documentation](docs/README.md):
|
|
54
|
+
- [API-Reference](docs/API-Reference/README.html)
|
|
55
|
+
|
|
56
|
+
## Roadmap
|
|
57
|
+
|
|
58
|
+
## Contributing
|
|
59
|
+
|
|
60
|
+
### Get Involved
|
|
61
|
+
|
|
62
|
+
- GitHub Discussions: if you want to share ideas
|
|
63
|
+
- GitHub Issues: if you find bugs, other issues, or would like to submit feature requests
|
|
64
|
+
- GitHub Merge Requests: if you think you know what you're doing, you're very welcome!
|
|
65
|
+
|
|
66
|
+
### Donations
|
|
67
|
+
|
|
68
|
+
To support me in my work on this and other projects, you can make donations with the following currencies:
|
|
69
|
+
|
|
70
|
+
- **Bitcoin:** `BC1Q45QEE6YTNGRC5TSZ42ZL3MWV8798ZEF70H2DG0`
|
|
71
|
+
- **Ethereum:** `0xA32C3bBC2106C986317f202B3aa8eBc3063323D4`
|
|
72
|
+
- [**Fiat** (via Credit or Debit Card, Apple Pay, Google Pay, Revolut Pay)](https://checkout.revolut.com/pay/4e4d24de-26cf-4e7d-9e84-ede89ec67f32)
|
|
73
|
+
|
|
74
|
+
Donations help me:
|
|
75
|
+
- dedicate more time to developing and maintaining open-source projects
|
|
76
|
+
- cover costs for IT infrastructure
|
|
77
|
+
- finance projects requiring additional hardware & compute
|
|
78
|
+
|
|
79
|
+
## About the Developer
|
|
80
|
+
|
|
81
|
+
This project is developed by a human one-man team, publishing under the name _Emendir_.
|
|
82
|
+
I build open technologies trying to improve our world;
|
|
83
|
+
learning, working and sharing under the principle:
|
|
84
|
+
|
|
85
|
+
> _Freely I have received, freely I give._
|
|
86
|
+
|
|
87
|
+
Feel welcome to join in with code contributions, discussions, ideas and more!
|
|
88
|
+
|
|
89
|
+
## Open-Source in the Public Domain
|
|
90
|
+
|
|
91
|
+
I dedicate this project to the public domain.
|
|
92
|
+
It is open source and free to use, share, modify, and build upon without restrictions or conditions.
|
|
93
|
+
|
|
94
|
+
I make no patent or trademark claims over this project.
|
|
95
|
+
|
|
96
|
+
Formally, you may use this project under either the:
|
|
97
|
+
- [MIT No Attribution (MIT-0)](https://choosealicense.com/licenses/mit-0/) or
|
|
98
|
+
- [Creative Commons Zero (CC0)](https://choosealicense.com/licenses/cc0-1.0/)
|
|
99
|
+
licence at your choice.
|
|
100
|
+
|
|
101
|
+
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
_auto_run_with_pytest/__init__.py,sha256=P2Tgn9TbVJvNiyOygCrBso4uAd7Og9suuHmKE0-CEtU,753
|
|
2
|
+
emtest/__init__.py,sha256=G_EnVC57IL_OjVJAjaz75y9owlCcdbvXfvR-ncO1icU,344
|
|
3
|
+
emtest/pytest_utils.py,sha256=qGKGlQTIgKi3BjmUTfcqzPE_0QfWkWfefy8Oitq3sdQ,4844
|
|
4
|
+
emtest/testing_utils.py,sha256=lzXRXwA50YQBHO35Y2s6NcbvgrdTcwGJjJ79CkzJKkk,4780
|
|
5
|
+
emtest-0.0.4.dist-info/licenses/LICENSE,sha256=i720OgyQLs68DSskm7ZLzaGKMnfskBIIHOuPWfwT2q4,907
|
|
6
|
+
emtest-0.0.4.dist-info/licenses/LICENSE-CC0,sha256=kXBMw0w0VVXQAbLjqMKmis4OngrPaK4HY9ScH6MdtxM,7038
|
|
7
|
+
emtest-0.0.4.dist-info/METADATA,sha256=Brr2oyYeArMDrP0K17UTUELzQ-LiUURmAQgDlfXMUXE,3395
|
|
8
|
+
emtest-0.0.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
9
|
+
emtest-0.0.4.dist-info/top_level.txt,sha256=sfToBhqMjk35PDheZ42yiMGYNYatT3V5Mwhb79fp5dE,29
|
|
10
|
+
emtest-0.0.4.dist-info/RECORD,,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
MIT No Attribution
|
|
2
|
+
|
|
3
|
+
Copyright [year] [fullname]
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so.
|
|
11
|
+
|
|
12
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
13
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
14
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
15
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
16
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
17
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
18
|
+
SOFTWARE.
|
|
@@ -101,7 +101,7 @@ express Statement of Purpose.
|
|
|
101
101
|
|
|
102
102
|
4. Limitations and Disclaimers.
|
|
103
103
|
|
|
104
|
-
a. No trademark
|
|
104
|
+
a. No trademark rights held by Affirmer are waived, abandoned,
|
|
105
105
|
surrendered, licensed or otherwise affected by this document.
|
|
106
106
|
b. Affirmer offers the Work as-is and makes no representations or
|
|
107
107
|
warranties of any kind concerning the Work, express, implied,
|
|
@@ -118,4 +118,4 @@ express Statement of Purpose.
|
|
|
118
118
|
Work.
|
|
119
119
|
d. Affirmer understands and acknowledges that Creative Commons is not a
|
|
120
120
|
party to this document and has no duty or obligation with respect to
|
|
121
|
-
this CC0 or use of the Work.
|
|
121
|
+
this CC0 or use of the Work.
|
emtest-0.0.1.dist-info/METADATA
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: emtest
|
|
3
|
-
Version: 0.0.1
|
|
4
|
-
Summary: Testing utilities which I find useful.
|
|
5
|
-
Author-email: Emendir <dev@emendir.tech>
|
|
6
|
-
License-Expression: CC0-1.0
|
|
7
|
-
Classifier: Programming Language :: Python :: 3
|
|
8
|
-
Classifier: Operating System :: OS Independent
|
|
9
|
-
Requires-Python: >=3.6
|
|
10
|
-
Description-Content-Type: text/markdown
|
|
11
|
-
License-File: LICENCE
|
|
12
|
-
Requires-Dist: tqdm
|
|
13
|
-
Dynamic: license-file
|
|
14
|
-
|
|
15
|
-
# emtest - Python Testing Utilities
|
|
16
|
-
|
|
17
|
-
A Python package providing testing utilities.
|
|
18
|
-
|
|
19
|
-
## Features
|
|
20
|
-
|
|
21
|
-
### 🎨 Clean Test Output for Pytest
|
|
22
|
-
- **MinimalReporter**: Custom pytest reporter with clean, colored output using simple symbols (✓/✗/-)
|
|
23
|
-
- **Configurable Output**: Toggle between minimal and standard pytest output modes
|
|
24
|
-
|
|
25
|
-
### 🔧 Development Utilities
|
|
26
|
-
- **Source Path Management**: Dynamically add directories to Python path for testing source code
|
|
27
|
-
- **Module Source Validation**: Ensure modules are loaded from source directories (not installed packages)
|
|
28
|
-
- **Thread Cleanup Monitoring**: Wait for and verify proper thread cleanup in tests
|
|
29
|
-
|
|
30
|
-
### ⚡ Enhanced Test Execution
|
|
31
|
-
- **Dual Execution Pattern**: Run tests both as pytest tests and standalone Python scripts
|
|
32
|
-
- **Breakpoint Integration**: Easy debugging with pytest's `--pdb` integration
|
|
33
|
-
- **Progress Indicators**: Visual progress bars for waiting operations
|
|
34
|
-
|
|
35
|
-
## Installation
|
|
36
|
-
|
|
37
|
-
```sh
|
|
38
|
-
pip install emtest
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Usage
|
|
42
|
-
|
|
43
|
-
See the `examples/` directory for complete working examples showing:
|
|
44
|
-
- Basic test setup with `conftest.py`
|
|
45
|
-
- Dual execution pattern implementation
|
|
46
|
-
- Source loading validation
|
|
47
|
-
- Thread cleanup testing
|
|
48
|
-
|
|
49
|
-
|
emtest-0.0.1.dist-info/RECORD
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
emtest/__init__.py,sha256=tC-Hx6hKUVswMSIik-RwLF4fO4rDaZXi05DzDkixoCE,195
|
|
2
|
-
emtest/pytest_utils.py,sha256=0vVNw6P4FdS7BsX18GMXK7bne-hfSNWiLtRS0sLiZOA,3486
|
|
3
|
-
emtest/testing_utils.py,sha256=uZeEw4EKhy_2sUIzUPF1kvfVfyis3mF7Q5SSj9uxzCU,2899
|
|
4
|
-
emtest-0.0.1.dist-info/licenses/LICENCE,sha256=bUia9ikmYtnjbTTOSUI3hJhKX25B17WPSbASZN9Z-gM,7047
|
|
5
|
-
emtest-0.0.1.dist-info/METADATA,sha256=UWQ9-OOa4u74B_kwP8BG2-2c77u1Mjod5mXS71TnGOM,1570
|
|
6
|
-
emtest-0.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
7
|
-
emtest-0.0.1.dist-info/top_level.txt,sha256=8yXylA__VmNeIDW3MBOmSiOpUCZoEprrys-qdB54CLo,7
|
|
8
|
-
emtest-0.0.1.dist-info/RECORD,,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
emtest
|
|
File without changes
|