testrium 0.1.0__tar.gz → 0.2.0__tar.gz
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.
- testrium-0.2.0/PKG-INFO +293 -0
- testrium-0.2.0/README.md +271 -0
- {testrium-0.1.0 → testrium-0.2.0}/pyproject.toml +28 -27
- testrium-0.2.0/testrium/common/generator/config.toml +15 -0
- testrium-0.2.0/testrium/common/generator/main.py +38 -0
- testrium-0.2.0/testrium/common/generator/test_case.py +27 -0
- testrium-0.2.0/testrium/common/generator/units/source.toml +12 -0
- testrium-0.2.0/testrium/common/generator/units/target.toml +12 -0
- testrium-0.2.0/testrium/common/loaders.py +172 -0
- {testrium-0.1.0 → testrium-0.2.0}/testrium/common/sql_pool.py +29 -29
- testrium-0.2.0/testrium/common/utils.py +59 -0
- testrium-0.2.0/testrium/common/validate_configs.py +266 -0
- testrium-0.2.0/testrium/core.py +694 -0
- testrium-0.2.0/testrium/modules/events.py +392 -0
- testrium-0.2.0/testrium/tools/benchmark.py +176 -0
- {testrium-0.1.0 → testrium-0.2.0}/testrium/tools/dashborad.py +195 -195
- testrium-0.1.0/PKG-INFO +0 -72
- testrium-0.1.0/README.md +0 -52
- testrium-0.1.0/testrium/common/validate_configs.py +0 -1
- testrium-0.1.0/testrium/core.py +0 -177
- testrium-0.1.0/testrium/tools/benchmark.py +0 -113
- testrium-0.1.0/testrium/utils.py +0 -140
- {testrium-0.1.0 → testrium-0.2.0}/testrium/__init__.py +0 -0
- {testrium-0.1.0 → testrium-0.2.0}/testrium/tools/test_results.db +0 -0
testrium-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: testrium
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: A modern, advanced testing framework.
|
|
5
|
+
Home-page: https://github.com/letalboy/testrium
|
|
6
|
+
License: MIT
|
|
7
|
+
Author: Cristian Camargo
|
|
8
|
+
Author-email: ccf@cdone.com.br
|
|
9
|
+
Requires-Python: >=3.10,<4.0
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Requires-Dist: colorama (>=0.4.6,<0.5.0)
|
|
16
|
+
Requires-Dist: pandas (>=2.2.2,<3.0.0)
|
|
17
|
+
Requires-Dist: toml (>=0.10.2,<0.11.0)
|
|
18
|
+
Project-URL: Documentation, https://github.com/letalboy/testrium#readme
|
|
19
|
+
Project-URL: Repository, https://github.com/letalboy/testrium
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# Testrium
|
|
23
|
+
|
|
24
|
+
Testrium is a circuit-level end-to-end testing framework for Python systems.
|
|
25
|
+
|
|
26
|
+
It is built for tests where the important question is not only "did this function return the right value?", but:
|
|
27
|
+
|
|
28
|
+
```text
|
|
29
|
+
Did this event, command, request, or message travel through the whole system correctly?
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Testrium helps coordinate multiple Python processes, record probes from each unit, verify that the expected endpoints were activated, and measure latency and consistency across the full circuit.
|
|
33
|
+
|
|
34
|
+
## What Testrium Is For
|
|
35
|
+
|
|
36
|
+
Use Testrium when a test needs to prove behavior across multiple runtime units:
|
|
37
|
+
|
|
38
|
+
- a host and one or more clients
|
|
39
|
+
- two services exchanging messages
|
|
40
|
+
- an API that triggers a worker
|
|
41
|
+
- a producer writing to a queue and a consumer processing it
|
|
42
|
+
- a scheduler activating downstream logic
|
|
43
|
+
- a local microservice flow
|
|
44
|
+
- a module-to-module circuit where the final effect happens away from the source
|
|
45
|
+
|
|
46
|
+
Testrium is designed for tests where success means:
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
processes started
|
|
50
|
+
units synchronized
|
|
51
|
+
events happened
|
|
52
|
+
messages crossed boundaries
|
|
53
|
+
expected probes completed
|
|
54
|
+
the target endpoint activated
|
|
55
|
+
latency and consistency were measured
|
|
56
|
+
the whole circuit passed
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## What Testrium Is Not
|
|
60
|
+
|
|
61
|
+
Testrium is not a replacement for `pytest`, `unittest`, or direct API test tools.
|
|
62
|
+
|
|
63
|
+
Those tools are excellent for direct tests:
|
|
64
|
+
|
|
65
|
+
- function input/output
|
|
66
|
+
- class behavior
|
|
67
|
+
- isolated modules
|
|
68
|
+
- single endpoint responses
|
|
69
|
+
- fixtures and local assertions
|
|
70
|
+
|
|
71
|
+
Testrium sits beside them. It exists for the cases where direct assertions are not enough because the behavior crosses process, service, module, queue, socket, or callback boundaries.
|
|
72
|
+
|
|
73
|
+
## Why This Library Exists
|
|
74
|
+
|
|
75
|
+
In many systems, the actual behavior is a circuit:
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
source unit -> event/message/request -> intermediate unit -> endpoint activation
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Traditional test tools can test each piece, but the full circuit often becomes custom scripts, fixed sleeps, process joins, shared status flags, log scraping, and repeated manual assertions.
|
|
82
|
+
|
|
83
|
+
Testrium turns that repeated pattern into a framework:
|
|
84
|
+
|
|
85
|
+
```text
|
|
86
|
+
declare units
|
|
87
|
+
start coordinated processes
|
|
88
|
+
emit probes
|
|
89
|
+
collect events
|
|
90
|
+
verify the circuit
|
|
91
|
+
measure latency
|
|
92
|
+
report pass/fail
|
|
93
|
+
store history
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Core Concepts
|
|
97
|
+
|
|
98
|
+
### Unit
|
|
99
|
+
|
|
100
|
+
A unit is one actor in the scenario, such as `host`, `client`, `api`, `worker`, `scheduler`, or `consumer`.
|
|
101
|
+
|
|
102
|
+
### Probe
|
|
103
|
+
|
|
104
|
+
A probe is a completion tag emitted by a unit when something important happens.
|
|
105
|
+
|
|
106
|
+
Examples:
|
|
107
|
+
|
|
108
|
+
```text
|
|
109
|
+
host-ready
|
|
110
|
+
client-contacted
|
|
111
|
+
command-sent
|
|
112
|
+
command-received
|
|
113
|
+
worker-activated
|
|
114
|
+
response-received
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Event
|
|
118
|
+
|
|
119
|
+
An event is the stored record of a probe. Events include the unit, completed step, event type, event key, and timestamp.
|
|
120
|
+
|
|
121
|
+
### Circuit
|
|
122
|
+
|
|
123
|
+
A circuit is the full path from cause to effect.
|
|
124
|
+
|
|
125
|
+
Examples:
|
|
126
|
+
|
|
127
|
+
```text
|
|
128
|
+
client command -> host receives -> host callback runs -> client receives response
|
|
129
|
+
API request -> event emitted -> worker consumes -> database update completes
|
|
130
|
+
service A sends -> service B receives -> service B responds -> service A completes
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## What Testrium Measures
|
|
134
|
+
|
|
135
|
+
Testrium should make these checks first-class:
|
|
136
|
+
|
|
137
|
+
| Circuit concern | What Testrium verifies |
|
|
138
|
+
| --- | --- |
|
|
139
|
+
| Start point | Which unit emitted the event or command |
|
|
140
|
+
| Route | Which units should receive or process it |
|
|
141
|
+
| Endpoint activation | Which callback, handler, worker, or endpoint ran |
|
|
142
|
+
| Completion tags | Which probes completed in each unit |
|
|
143
|
+
| Consistency | Whether `Send` and `Receive` pairs match by `EventKey` |
|
|
144
|
+
| Latency | Time between send/receive events and total scenario duration |
|
|
145
|
+
| Failure evidence | Missing probes, exception events, orphan sends, orphan receives, duplicate keys |
|
|
146
|
+
|
|
147
|
+
## Comparison
|
|
148
|
+
|
|
149
|
+
| Tool or category | Best for | Where Testrium fits |
|
|
150
|
+
| --- | --- | --- |
|
|
151
|
+
| `pytest` | Direct function, class, fixture, and module tests | Use Testrium when the assertion depends on events crossing runtime boundaries |
|
|
152
|
+
| `unittest` | Standard-library direct tests | Use Testrium for coordinated multi-unit scenarios |
|
|
153
|
+
| API test tools | One endpoint request/response | Use Testrium when the endpoint triggers async or downstream behavior |
|
|
154
|
+
| Contract testing | Schema/provider compatibility | Use Testrium to prove the live circuit actually executed |
|
|
155
|
+
| Browser E2E tools | UI flows | Use Testrium for backend/service/module circuits |
|
|
156
|
+
| Load tools | Throughput and stress | Use Testrium for per-circuit correctness and latency |
|
|
157
|
+
| Custom scripts | Project-specific orchestration | Use Testrium to avoid rebuilding process coordination and probe verification |
|
|
158
|
+
|
|
159
|
+
## Current Features
|
|
160
|
+
|
|
161
|
+
- Config-driven test groups
|
|
162
|
+
- Unit definitions through TOML files
|
|
163
|
+
- Config-first unit entrypoints using `module:function`
|
|
164
|
+
- Coordinated Python unit processes
|
|
165
|
+
- Unit lifecycle states and readiness probes
|
|
166
|
+
- Isolated SQLite runtime state per test group run
|
|
167
|
+
- Process-based setup support
|
|
168
|
+
- Event/probe logging with SQLite
|
|
169
|
+
- `Default`, `Exception`, `Send`, and `Receive` event types
|
|
170
|
+
- Required probe verification
|
|
171
|
+
- Send/receive correlation with latency metrics
|
|
172
|
+
- Callback hooks for extra validation and final result handling
|
|
173
|
+
- Basic result summaries
|
|
174
|
+
- Template generation for starter config files
|
|
175
|
+
|
|
176
|
+
The remaining near-term work is focused on richer fixtures, public history APIs, and broader reporting polish.
|
|
177
|
+
|
|
178
|
+
## Installation
|
|
179
|
+
|
|
180
|
+
Using Poetry:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
poetry add testrium
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Using pip:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
pip install testrium
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Quick Start
|
|
193
|
+
|
|
194
|
+
Generate a starter config:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
testrium gen config-template .
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Run Testrium from a folder that contains test groups:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
testrium run
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Run with verbose logs:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
testrium --verbose run
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Exclude specific test groups:
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
testrium --less test_redirect run
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Example Shape
|
|
219
|
+
|
|
220
|
+
```text
|
|
221
|
+
tests/
|
|
222
|
+
test_connection/
|
|
223
|
+
config.toml
|
|
224
|
+
setup.py
|
|
225
|
+
test_case.py
|
|
226
|
+
units/
|
|
227
|
+
target.toml
|
|
228
|
+
source.toml
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Example unit config:
|
|
232
|
+
|
|
233
|
+
```toml
|
|
234
|
+
["source"]
|
|
235
|
+
init = 1
|
|
236
|
+
enabled = true
|
|
237
|
+
entrypoint = "test_case:run_source"
|
|
238
|
+
ready_event = "source-ready"
|
|
239
|
+
use_setup = false
|
|
240
|
+
in-except = "Resume"
|
|
241
|
+
unit_dependencies = ["target"]
|
|
242
|
+
events = [
|
|
243
|
+
"source-ready",
|
|
244
|
+
"command-sent",
|
|
245
|
+
"response-received"
|
|
246
|
+
]
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Example probe:
|
|
250
|
+
|
|
251
|
+
```python
|
|
252
|
+
from testrium.modules.events import Events_Manager
|
|
253
|
+
|
|
254
|
+
events = Events_Manager(Unit="source", path=".")
|
|
255
|
+
|
|
256
|
+
events.Set_Event("source-ready")
|
|
257
|
+
events.Set_Event("command-sent", event_type="Send", event_key="request-001")
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
The receiving unit can emit:
|
|
261
|
+
|
|
262
|
+
```python
|
|
263
|
+
from testrium.modules.events import Events_Manager
|
|
264
|
+
|
|
265
|
+
events = Events_Manager(Unit="target", path=".")
|
|
266
|
+
|
|
267
|
+
events.Set_Event("command-received", event_type="Receive", event_key="request-001")
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Testrium can then verify that the expected probes happened and that the circuit completed.
|
|
271
|
+
|
|
272
|
+
## Documentation
|
|
273
|
+
|
|
274
|
+
- [Developer guide](docs/developer-guide.md): how to structure scenarios, units, probes, and circuit-level tests.
|
|
275
|
+
- [Design decisions](docs/design-decisions.md): architecture, module responsibilities, flow diagrams, and implementation direction.
|
|
276
|
+
- [Implementation roadmap](docs/implementation-roadmap.md): issue-aligned gaps, acceptance gates, and MVP follow-up work.
|
|
277
|
+
|
|
278
|
+
## Project Direction
|
|
279
|
+
|
|
280
|
+
The near-term implementation priority is:
|
|
281
|
+
|
|
282
|
+
1. Make the CLI runnable and dependency-complete.
|
|
283
|
+
2. Add strict config and unit validation.
|
|
284
|
+
3. Implement unit orchestration by order, dependency, and setup policy.
|
|
285
|
+
4. Implement event/probe verification.
|
|
286
|
+
5. Add event correlation and history metrics.
|
|
287
|
+
|
|
288
|
+
Testrium's core promise is simple:
|
|
289
|
+
|
|
290
|
+
```text
|
|
291
|
+
test the whole circuit, not only one component inside it
|
|
292
|
+
```
|
|
293
|
+
|
testrium-0.2.0/README.md
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
# Testrium
|
|
2
|
+
|
|
3
|
+
Testrium is a circuit-level end-to-end testing framework for Python systems.
|
|
4
|
+
|
|
5
|
+
It is built for tests where the important question is not only "did this function return the right value?", but:
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
Did this event, command, request, or message travel through the whole system correctly?
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Testrium helps coordinate multiple Python processes, record probes from each unit, verify that the expected endpoints were activated, and measure latency and consistency across the full circuit.
|
|
12
|
+
|
|
13
|
+
## What Testrium Is For
|
|
14
|
+
|
|
15
|
+
Use Testrium when a test needs to prove behavior across multiple runtime units:
|
|
16
|
+
|
|
17
|
+
- a host and one or more clients
|
|
18
|
+
- two services exchanging messages
|
|
19
|
+
- an API that triggers a worker
|
|
20
|
+
- a producer writing to a queue and a consumer processing it
|
|
21
|
+
- a scheduler activating downstream logic
|
|
22
|
+
- a local microservice flow
|
|
23
|
+
- a module-to-module circuit where the final effect happens away from the source
|
|
24
|
+
|
|
25
|
+
Testrium is designed for tests where success means:
|
|
26
|
+
|
|
27
|
+
```text
|
|
28
|
+
processes started
|
|
29
|
+
units synchronized
|
|
30
|
+
events happened
|
|
31
|
+
messages crossed boundaries
|
|
32
|
+
expected probes completed
|
|
33
|
+
the target endpoint activated
|
|
34
|
+
latency and consistency were measured
|
|
35
|
+
the whole circuit passed
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## What Testrium Is Not
|
|
39
|
+
|
|
40
|
+
Testrium is not a replacement for `pytest`, `unittest`, or direct API test tools.
|
|
41
|
+
|
|
42
|
+
Those tools are excellent for direct tests:
|
|
43
|
+
|
|
44
|
+
- function input/output
|
|
45
|
+
- class behavior
|
|
46
|
+
- isolated modules
|
|
47
|
+
- single endpoint responses
|
|
48
|
+
- fixtures and local assertions
|
|
49
|
+
|
|
50
|
+
Testrium sits beside them. It exists for the cases where direct assertions are not enough because the behavior crosses process, service, module, queue, socket, or callback boundaries.
|
|
51
|
+
|
|
52
|
+
## Why This Library Exists
|
|
53
|
+
|
|
54
|
+
In many systems, the actual behavior is a circuit:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
source unit -> event/message/request -> intermediate unit -> endpoint activation
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Traditional test tools can test each piece, but the full circuit often becomes custom scripts, fixed sleeps, process joins, shared status flags, log scraping, and repeated manual assertions.
|
|
61
|
+
|
|
62
|
+
Testrium turns that repeated pattern into a framework:
|
|
63
|
+
|
|
64
|
+
```text
|
|
65
|
+
declare units
|
|
66
|
+
start coordinated processes
|
|
67
|
+
emit probes
|
|
68
|
+
collect events
|
|
69
|
+
verify the circuit
|
|
70
|
+
measure latency
|
|
71
|
+
report pass/fail
|
|
72
|
+
store history
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Core Concepts
|
|
76
|
+
|
|
77
|
+
### Unit
|
|
78
|
+
|
|
79
|
+
A unit is one actor in the scenario, such as `host`, `client`, `api`, `worker`, `scheduler`, or `consumer`.
|
|
80
|
+
|
|
81
|
+
### Probe
|
|
82
|
+
|
|
83
|
+
A probe is a completion tag emitted by a unit when something important happens.
|
|
84
|
+
|
|
85
|
+
Examples:
|
|
86
|
+
|
|
87
|
+
```text
|
|
88
|
+
host-ready
|
|
89
|
+
client-contacted
|
|
90
|
+
command-sent
|
|
91
|
+
command-received
|
|
92
|
+
worker-activated
|
|
93
|
+
response-received
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Event
|
|
97
|
+
|
|
98
|
+
An event is the stored record of a probe. Events include the unit, completed step, event type, event key, and timestamp.
|
|
99
|
+
|
|
100
|
+
### Circuit
|
|
101
|
+
|
|
102
|
+
A circuit is the full path from cause to effect.
|
|
103
|
+
|
|
104
|
+
Examples:
|
|
105
|
+
|
|
106
|
+
```text
|
|
107
|
+
client command -> host receives -> host callback runs -> client receives response
|
|
108
|
+
API request -> event emitted -> worker consumes -> database update completes
|
|
109
|
+
service A sends -> service B receives -> service B responds -> service A completes
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## What Testrium Measures
|
|
113
|
+
|
|
114
|
+
Testrium should make these checks first-class:
|
|
115
|
+
|
|
116
|
+
| Circuit concern | What Testrium verifies |
|
|
117
|
+
| --- | --- |
|
|
118
|
+
| Start point | Which unit emitted the event or command |
|
|
119
|
+
| Route | Which units should receive or process it |
|
|
120
|
+
| Endpoint activation | Which callback, handler, worker, or endpoint ran |
|
|
121
|
+
| Completion tags | Which probes completed in each unit |
|
|
122
|
+
| Consistency | Whether `Send` and `Receive` pairs match by `EventKey` |
|
|
123
|
+
| Latency | Time between send/receive events and total scenario duration |
|
|
124
|
+
| Failure evidence | Missing probes, exception events, orphan sends, orphan receives, duplicate keys |
|
|
125
|
+
|
|
126
|
+
## Comparison
|
|
127
|
+
|
|
128
|
+
| Tool or category | Best for | Where Testrium fits |
|
|
129
|
+
| --- | --- | --- |
|
|
130
|
+
| `pytest` | Direct function, class, fixture, and module tests | Use Testrium when the assertion depends on events crossing runtime boundaries |
|
|
131
|
+
| `unittest` | Standard-library direct tests | Use Testrium for coordinated multi-unit scenarios |
|
|
132
|
+
| API test tools | One endpoint request/response | Use Testrium when the endpoint triggers async or downstream behavior |
|
|
133
|
+
| Contract testing | Schema/provider compatibility | Use Testrium to prove the live circuit actually executed |
|
|
134
|
+
| Browser E2E tools | UI flows | Use Testrium for backend/service/module circuits |
|
|
135
|
+
| Load tools | Throughput and stress | Use Testrium for per-circuit correctness and latency |
|
|
136
|
+
| Custom scripts | Project-specific orchestration | Use Testrium to avoid rebuilding process coordination and probe verification |
|
|
137
|
+
|
|
138
|
+
## Current Features
|
|
139
|
+
|
|
140
|
+
- Config-driven test groups
|
|
141
|
+
- Unit definitions through TOML files
|
|
142
|
+
- Config-first unit entrypoints using `module:function`
|
|
143
|
+
- Coordinated Python unit processes
|
|
144
|
+
- Unit lifecycle states and readiness probes
|
|
145
|
+
- Isolated SQLite runtime state per test group run
|
|
146
|
+
- Process-based setup support
|
|
147
|
+
- Event/probe logging with SQLite
|
|
148
|
+
- `Default`, `Exception`, `Send`, and `Receive` event types
|
|
149
|
+
- Required probe verification
|
|
150
|
+
- Send/receive correlation with latency metrics
|
|
151
|
+
- Callback hooks for extra validation and final result handling
|
|
152
|
+
- Basic result summaries
|
|
153
|
+
- Template generation for starter config files
|
|
154
|
+
|
|
155
|
+
The remaining near-term work is focused on richer fixtures, public history APIs, and broader reporting polish.
|
|
156
|
+
|
|
157
|
+
## Installation
|
|
158
|
+
|
|
159
|
+
Using Poetry:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
poetry add testrium
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Using pip:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
pip install testrium
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Quick Start
|
|
172
|
+
|
|
173
|
+
Generate a starter config:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
testrium gen config-template .
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Run Testrium from a folder that contains test groups:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
testrium run
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Run with verbose logs:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
testrium --verbose run
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Exclude specific test groups:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
testrium --less test_redirect run
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Example Shape
|
|
198
|
+
|
|
199
|
+
```text
|
|
200
|
+
tests/
|
|
201
|
+
test_connection/
|
|
202
|
+
config.toml
|
|
203
|
+
setup.py
|
|
204
|
+
test_case.py
|
|
205
|
+
units/
|
|
206
|
+
target.toml
|
|
207
|
+
source.toml
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Example unit config:
|
|
211
|
+
|
|
212
|
+
```toml
|
|
213
|
+
["source"]
|
|
214
|
+
init = 1
|
|
215
|
+
enabled = true
|
|
216
|
+
entrypoint = "test_case:run_source"
|
|
217
|
+
ready_event = "source-ready"
|
|
218
|
+
use_setup = false
|
|
219
|
+
in-except = "Resume"
|
|
220
|
+
unit_dependencies = ["target"]
|
|
221
|
+
events = [
|
|
222
|
+
"source-ready",
|
|
223
|
+
"command-sent",
|
|
224
|
+
"response-received"
|
|
225
|
+
]
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Example probe:
|
|
229
|
+
|
|
230
|
+
```python
|
|
231
|
+
from testrium.modules.events import Events_Manager
|
|
232
|
+
|
|
233
|
+
events = Events_Manager(Unit="source", path=".")
|
|
234
|
+
|
|
235
|
+
events.Set_Event("source-ready")
|
|
236
|
+
events.Set_Event("command-sent", event_type="Send", event_key="request-001")
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
The receiving unit can emit:
|
|
240
|
+
|
|
241
|
+
```python
|
|
242
|
+
from testrium.modules.events import Events_Manager
|
|
243
|
+
|
|
244
|
+
events = Events_Manager(Unit="target", path=".")
|
|
245
|
+
|
|
246
|
+
events.Set_Event("command-received", event_type="Receive", event_key="request-001")
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Testrium can then verify that the expected probes happened and that the circuit completed.
|
|
250
|
+
|
|
251
|
+
## Documentation
|
|
252
|
+
|
|
253
|
+
- [Developer guide](docs/developer-guide.md): how to structure scenarios, units, probes, and circuit-level tests.
|
|
254
|
+
- [Design decisions](docs/design-decisions.md): architecture, module responsibilities, flow diagrams, and implementation direction.
|
|
255
|
+
- [Implementation roadmap](docs/implementation-roadmap.md): issue-aligned gaps, acceptance gates, and MVP follow-up work.
|
|
256
|
+
|
|
257
|
+
## Project Direction
|
|
258
|
+
|
|
259
|
+
The near-term implementation priority is:
|
|
260
|
+
|
|
261
|
+
1. Make the CLI runnable and dependency-complete.
|
|
262
|
+
2. Add strict config and unit validation.
|
|
263
|
+
3. Implement unit orchestration by order, dependency, and setup policy.
|
|
264
|
+
4. Implement event/probe verification.
|
|
265
|
+
5. Add event correlation and history metrics.
|
|
266
|
+
|
|
267
|
+
Testrium's core promise is simple:
|
|
268
|
+
|
|
269
|
+
```text
|
|
270
|
+
test the whole circuit, not only one component inside it
|
|
271
|
+
```
|
|
@@ -1,27 +1,28 @@
|
|
|
1
|
-
[tool.poetry]
|
|
2
|
-
name = "testrium"
|
|
3
|
-
version = "0.
|
|
4
|
-
description = "A modern, advanced testing framework."
|
|
5
|
-
authors = ["Cristian Camargo <ccf@cdone.com.br>"]
|
|
6
|
-
readme = "README.md"
|
|
7
|
-
homepage = "https://github.com/letalboy/testrium"
|
|
8
|
-
repository = "https://github.com/letalboy/testrium"
|
|
9
|
-
license = "MIT"
|
|
10
|
-
|
|
11
|
-
[tool.poetry.dependencies]
|
|
12
|
-
python = "^3.10"
|
|
13
|
-
toml = "^0.10.2"
|
|
14
|
-
pandas = "^2.2.2"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "testrium"
|
|
3
|
+
version = "0.2.0"
|
|
4
|
+
description = "A modern, advanced testing framework."
|
|
5
|
+
authors = ["Cristian Camargo <ccf@cdone.com.br>"]
|
|
6
|
+
readme = "README.md"
|
|
7
|
+
homepage = "https://github.com/letalboy/testrium"
|
|
8
|
+
repository = "https://github.com/letalboy/testrium"
|
|
9
|
+
license = "MIT"
|
|
10
|
+
|
|
11
|
+
[tool.poetry.dependencies]
|
|
12
|
+
python = "^3.10"
|
|
13
|
+
toml = "^0.10.2"
|
|
14
|
+
pandas = "^2.2.2"
|
|
15
|
+
colorama = "^0.4.6"
|
|
16
|
+
|
|
17
|
+
[tool.poetry.group.dev.dependencies]
|
|
18
|
+
pytest = "^9.0.3"
|
|
19
|
+
|
|
20
|
+
[build-system]
|
|
21
|
+
requires = ["poetry-core"]
|
|
22
|
+
build-backend = "poetry.core.masonry.api"
|
|
23
|
+
|
|
24
|
+
[tool.poetry.scripts]
|
|
25
|
+
testrium = "testrium.core:main"
|
|
26
|
+
|
|
27
|
+
[tool.poetry.urls]
|
|
28
|
+
Documentation = "https://github.com/letalboy/testrium#readme"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# This is the overall config for a circuit-level test group
|
|
2
|
+
["Configs"]
|
|
3
|
+
units = ["target", "source"]
|
|
4
|
+
debug-modes = ["DEBUG", "INFO", "WARNING", "EXCEPT"]
|
|
5
|
+
test-modes = ["DEBUG"] # Can be "<MODE>", ["<MODE1>", <"MODE2">, ...], "All"
|
|
6
|
+
enabled = true
|
|
7
|
+
timeout = 10
|
|
8
|
+
use-ai = false
|
|
9
|
+
diagnostics = true
|
|
10
|
+
detect-bad-behavior = true
|
|
11
|
+
save-resume = true
|
|
12
|
+
repeat = 0 # can be any between 0 - 10
|
|
13
|
+
gen-metrics = true
|
|
14
|
+
save-metrics = true
|
|
15
|
+
save-scores = true
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import shutil
|
|
3
|
+
from colorama import Fore
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def resolve_generation_path(path: str | None) -> str:
|
|
7
|
+
target_path = path or "."
|
|
8
|
+
return os.path.abspath(os.path.expanduser(target_path))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _copy_template_file(source: str, destination: str) -> None:
|
|
12
|
+
destination_file = os.path.join(destination, os.path.basename(source))
|
|
13
|
+
if os.path.isfile(destination_file):
|
|
14
|
+
print(f"{Fore.BLUE} {os.path.basename(source)} already exists")
|
|
15
|
+
return
|
|
16
|
+
shutil.copy2(source, destination)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def resolve_template(type: str, path: str | None = "."):
|
|
20
|
+
if type == "config-template":
|
|
21
|
+
target_path = resolve_generation_path(path)
|
|
22
|
+
if not os.path.isdir(target_path):
|
|
23
|
+
print(f"{Fore.RED} path argument is invalid")
|
|
24
|
+
return
|
|
25
|
+
|
|
26
|
+
template_dir = os.path.dirname(__file__)
|
|
27
|
+
_copy_template_file(os.path.join(template_dir, "config.toml"), target_path)
|
|
28
|
+
_copy_template_file(os.path.join(template_dir, "test_case.py"), target_path)
|
|
29
|
+
|
|
30
|
+
units_source = os.path.join(template_dir, "units")
|
|
31
|
+
units_target = os.path.join(target_path, "units")
|
|
32
|
+
os.makedirs(units_target, exist_ok=True)
|
|
33
|
+
for filename in os.listdir(units_source):
|
|
34
|
+
if filename.endswith(".toml"):
|
|
35
|
+
_copy_template_file(os.path.join(units_source, filename), units_target)
|
|
36
|
+
|
|
37
|
+
print(f"{Fore.GREEN} config template generated in {target_path}")
|
|
38
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from testrium.modules.events import Events_Manager
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def run_target():
|
|
5
|
+
events = Events_Manager(Unit="target", path=".")
|
|
6
|
+
all_events = Events_Manager(Unit="*", path=".")
|
|
7
|
+
|
|
8
|
+
events.Set_Event("target-ready")
|
|
9
|
+
if not all_events.wait_for_event("command-sent", unit="source", timeout=5):
|
|
10
|
+
events.Set_Event("source-command-timeout", event_type="Exception")
|
|
11
|
+
return
|
|
12
|
+
|
|
13
|
+
events.Set_Event("command-received", event_type="Receive", event_key="request-001")
|
|
14
|
+
events.Set_Event("endpoint-activated")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def run_source():
|
|
18
|
+
events = Events_Manager(Unit="source", path=".")
|
|
19
|
+
all_events = Events_Manager(Unit="*", path=".")
|
|
20
|
+
|
|
21
|
+
events.Set_Event("source-ready")
|
|
22
|
+
events.Set_Event("command-sent", event_type="Send", event_key="request-001")
|
|
23
|
+
|
|
24
|
+
if all_events.wait_for_event("endpoint-activated", unit="target", timeout=5):
|
|
25
|
+
events.Set_Event("response-received")
|
|
26
|
+
else:
|
|
27
|
+
events.Set_Event("response-timeout", event_type="Exception")
|