rustest 0.3.0__cp311-cp311-win_amd64.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.
@@ -0,0 +1,658 @@
1
+ Metadata-Version: 2.4
2
+ Name: rustest
3
+ Version: 0.3.0
4
+ Classifier: Development Status :: 3 - Alpha
5
+ Classifier: Intended Audience :: Developers
6
+ Classifier: License :: OSI Approved :: MIT License
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Programming Language :: Python :: 3.10
9
+ Classifier: Programming Language :: Python :: 3.11
10
+ Classifier: Programming Language :: Python :: 3.12
11
+ Classifier: Programming Language :: Python :: 3.13
12
+ Classifier: Programming Language :: Python :: 3.14
13
+ Classifier: Programming Language :: Rust
14
+ Classifier: Topic :: Software Development :: Testing
15
+ Requires-Dist: typing-extensions>=4.15
16
+ Requires-Dist: basedpyright>=1.19 ; extra == 'dev'
17
+ Requires-Dist: maturin>=1.4,<2 ; extra == 'dev'
18
+ Requires-Dist: poethepoet>=0.22 ; extra == 'dev'
19
+ Requires-Dist: pre-commit>=3.5 ; extra == 'dev'
20
+ Requires-Dist: pytest>=7.0 ; extra == 'dev'
21
+ Requires-Dist: ruff>=0.1.9 ; extra == 'dev'
22
+ Provides-Extra: dev
23
+ License-File: LICENSE
24
+ Summary: Rust powered pytest-compatible runner
25
+ Author: rustest contributors
26
+ Requires-Python: >=3.10
27
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
28
+ Project-URL: Homepage, https://github.com/Apex-Engineers-Inc/rustest
29
+ Project-URL: Repository, https://github.com/Apex-Engineers-Inc/rustest
30
+
31
+ # rustest
32
+
33
+ Rustest (pronounced like Russ-Test) is a Rust-powered test runner that aims to provide the most common pytest ergonomics with a focus on raw performance. Get **~2x faster** test execution with familiar syntax and minimal setup.
34
+
35
+ ## Why rustest?
36
+
37
+ - ๐Ÿš€ **About 2x faster** than pytest on the rustest integration test suite
38
+ - โœ… Familiar `@fixture`, `@parametrize`, `@skip`, and `@mark` decorators
39
+ - ๐Ÿ” Automatic test discovery (`test_*.py` and `*_test.py` files)
40
+ - ๐ŸŽฏ Simple, clean APIโ€”if you know pytest, you already know rustest
41
+ - ๐Ÿงฎ Built-in `approx()` helper for tolerant numeric comparisons across scalars, collections, and complex numbers
42
+ - ๐Ÿชค `raises()` context manager for precise exception assertions with optional message matching
43
+ - ๐Ÿ“ฆ Easy installation with pip or uv
44
+ - โšก Low-overhead execution keeps small suites feeling instant
45
+
46
+ ## Performance
47
+
48
+ Rustest is designed for speed. Our latest benchmarks on the rustest integration suite (~200 tests) show a consistent **2.1x wall-clock speedup** over pytest:
49
+
50
+ | Test Runner | Reported Runtimeโ€  | Wall Clockโ€ก | Speedup (wall) | Command |
51
+ |-------------|------------------|-------------|----------------|---------|
52
+ | pytest | 0.43โ€“0.59s | 1.33โ€“1.59s | 1.0x (baseline) | `pytest tests/ examples/tests/ -q`
53
+ | rustest | 0.003s | 0.69โ€“0.70s | **~2.1x faster** | `python -m rustest tests/ examples/tests/`ยง
54
+
55
+ ### Large parametrized stress test
56
+
57
+ We also profiled an extreme case with **10,000 parametrized invocations** to ensure rustest scales on synthetic but heavy workloads. The test lives in [`benchmarks/test_large_parametrize.py`](benchmarks/test_large_parametrize.py) and simply asserts `value + value == 2 * value` across every case. Running the module on its own shows a dramatic gap:
58
+
59
+ | Test Runner | Avg. Wall Clock (3 runs) | Speedup | Command |
60
+ |-------------|--------------------------|---------|---------|
61
+ | pytest | 9.72s | 1.0x | `pytest benchmarks/test_large_parametrize.py -q`ยง
62
+ | rustest | 0.41s | **~24x** | `python -m rustest benchmarks/test_large_parametrize.py`ยง
63
+
64
+ โ€  pytest and rustest both report only active test execution time; rustest's figure omits Python interpreter start-up overhead.
65
+
66
+ โ€ก Integration-suite wall-clock timing measured with the shell `time` builtin across two consecutive runs in the same environment.
67
+
68
+ ยง Commands executed with `PYTHONPATH=python` in this repository checkout to exercise the local sources. Pytest relies on a small compatibility shim in [`benchmarks/conftest.py`](benchmarks/conftest.py) so it understands the rustest-style decorators. Large-parametrization timings come from averaging three `time.perf_counter()` measurements with output suppressed via `subprocess.DEVNULL`.
69
+
70
+ Rustest counts parametrized cases slightly differently than pytest, so you will see 199 executed cases vs. pytest's 201 discoveries on the same suiteโ€”the reported pass/skip counts still align.
71
+
72
+ **Why is rustest faster?**
73
+ - **Near-zero startup time**: Native Rust binary minimizes overhead before Python code starts running.
74
+ - **Rust-native test discovery**: Minimal imports until test execution keeps collection quick.
75
+ - **Optimized fixture resolution**: Efficient dependency graph resolution reduces per-test work.
76
+ - **Lean orchestration**: Rust handles scheduling and reporting so the Python interpreter focuses on running test bodies.
77
+
78
+ **Real-world impact:**
79
+ - **200 tests** (this repository): 1.46s โ†’ 0.70s (average wall-clock, ~0.76s saved per run)
80
+ - **1,000 tests** (projected): ~7.3s โ†’ ~3.4s assuming similar scaling
81
+ - **10,000 tests** (projected): ~73s โ†’ ~34sโ€”minutes saved across CI runs
82
+
83
+ See [BENCHMARKS.md](BENCHMARKS.md) for detailed performance analysis and methodology.
84
+
85
+ ## Installation
86
+
87
+ Rustest supports Python **3.10 through 3.14**.
88
+
89
+ ### Using pip
90
+ ```bash
91
+ pip install rustest
92
+ ```
93
+
94
+ ### Using uv
95
+ ```bash
96
+ uv add rustest
97
+ ```
98
+
99
+ ### For Development
100
+ If you want to contribute to rustest, see [DEVELOPMENT.md](DEVELOPMENT.md) for setup instructions.
101
+
102
+ ## Quick Start
103
+
104
+ ### 1. Write Your Tests
105
+
106
+ Create a file `test_math.py`:
107
+
108
+ ```python
109
+ from rustest import fixture, parametrize, mark, approx, raises
110
+
111
+ @fixture
112
+ def numbers() -> list[int]:
113
+ return [1, 2, 3, 4, 5]
114
+
115
+ def test_sum(numbers: list[int]) -> None:
116
+ assert sum(numbers) == approx(15)
117
+
118
+ @parametrize("value,expected", [(2, 4), (3, 9), (4, 16)])
119
+ def test_square(value: int, expected: int) -> None:
120
+ assert value ** 2 == expected
121
+
122
+ @mark.slow
123
+ def test_expensive_operation() -> None:
124
+ # This test is marked as slow for filtering
125
+ result = sum(range(1000000))
126
+ assert result > 0
127
+
128
+ def test_division_by_zero_is_reported() -> None:
129
+ with raises(ZeroDivisionError, match="division by zero"):
130
+ 1 / 0
131
+ ```
132
+
133
+ ### 2. Run Your Tests
134
+
135
+ ```bash
136
+ # Run all tests in the current directory
137
+ rustest
138
+
139
+ # Run tests in a specific directory
140
+ rustest tests/
141
+
142
+ # Run tests matching a pattern
143
+ rustest -k "test_sum"
144
+
145
+ # Show output during test execution
146
+ rustest --no-capture
147
+ ```
148
+
149
+ ## Usage Examples
150
+
151
+ ### CLI Usage
152
+
153
+ ```bash
154
+ # Run all tests in current directory
155
+ rustest
156
+
157
+ # Run tests in specific paths
158
+ rustest tests/ integration/
159
+
160
+ # Filter tests by name pattern
161
+ rustest -k "user" # Runs test_user_login, test_user_signup, etc.
162
+ rustest -k "auth" # Runs all tests with "auth" in the name
163
+
164
+ # Control output capture
165
+ rustest --no-capture # See print statements during test execution
166
+ ```
167
+
168
+ ### Python API Usage
169
+
170
+ You can also run rustest programmatically from Python:
171
+
172
+ ```python
173
+ from rustest import run
174
+
175
+ # Basic usage
176
+ report = run(paths=["tests"])
177
+ print(f"Passed: {report.passed}, Failed: {report.failed}")
178
+
179
+ # With pattern filtering
180
+ report = run(paths=["tests"], pattern="user")
181
+
182
+ # Without output capture (see print statements)
183
+ report = run(paths=["tests"], capture_output=False)
184
+
185
+ # Access individual test results
186
+ for result in report.results:
187
+ print(f"{result.name}: {result.status} ({result.duration:.3f}s)")
188
+ if result.status == "failed":
189
+ print(f" Error: {result.message}")
190
+ ```
191
+
192
+ ### Writing Tests
193
+
194
+ #### Basic Test Functions
195
+
196
+ ```python
197
+ def test_simple_assertion() -> None:
198
+ assert 1 + 1 == 2
199
+
200
+ def test_string_operations() -> None:
201
+ text = "hello world"
202
+ assert text.startswith("hello")
203
+ assert "world" in text
204
+ ```
205
+
206
+ #### Using Fixtures
207
+
208
+ Fixtures provide reusable test data and setup:
209
+
210
+ ```python
211
+ from rustest import fixture
212
+
213
+ @fixture
214
+ def database_connection() -> dict:
215
+ # Setup: create a connection
216
+ conn = {"host": "localhost", "port": 5432}
217
+ return conn
218
+ # Teardown happens automatically
219
+
220
+ @fixture
221
+ def sample_user() -> dict:
222
+ return {"id": 1, "name": "Alice", "email": "alice@example.com"}
223
+
224
+ def test_database_query(database_connection: dict) -> None:
225
+ assert database_connection["host"] == "localhost"
226
+
227
+ def test_user_email(sample_user: dict) -> None:
228
+ assert "@" in sample_user["email"]
229
+ ```
230
+
231
+ #### Fixtures with Dependencies
232
+
233
+ Fixtures can depend on other fixtures:
234
+
235
+ ```python
236
+ from rustest import fixture
237
+
238
+ @fixture
239
+ def api_url() -> str:
240
+ return "https://api.example.com"
241
+
242
+ @fixture
243
+ def api_client(api_url: str) -> dict:
244
+ return {"base_url": api_url, "timeout": 30}
245
+
246
+ def test_api_configuration(api_client: dict) -> None:
247
+ assert api_client["base_url"].startswith("https://")
248
+ assert api_client["timeout"] == 30
249
+ ```
250
+
251
+ #### Assertion Helpers
252
+
253
+ Rustest ships helpers for expressive assertions:
254
+
255
+ ```python
256
+ from rustest import approx, raises
257
+
258
+ def test_nearly_equal() -> None:
259
+ assert 0.1 + 0.2 == approx(0.3, rel=1e-9)
260
+
261
+ def test_raises_with_message() -> None:
262
+ with raises(ValueError, match="invalid configuration"):
263
+ raise ValueError("invalid configuration")
264
+ ```
265
+
266
+ #### Yield Fixtures with Setup/Teardown
267
+
268
+ Fixtures can use `yield` to perform cleanup after tests:
269
+
270
+ ```python
271
+ from rustest import fixture
272
+
273
+ @fixture
274
+ def database_connection():
275
+ # Setup: create connection
276
+ conn = create_db_connection()
277
+ print("Database connected")
278
+
279
+ yield conn
280
+
281
+ # Teardown: close connection
282
+ conn.close()
283
+ print("Database connection closed")
284
+
285
+ @fixture
286
+ def temp_file():
287
+ # Setup
288
+ file = open("temp.txt", "w")
289
+ file.write("test data")
290
+
291
+ yield file
292
+
293
+ # Teardown
294
+ file.close()
295
+ os.remove("temp.txt")
296
+
297
+ def test_database_query(database_connection):
298
+ result = database_connection.query("SELECT 1")
299
+ assert result is not None
300
+ ```
301
+
302
+ #### Fixture Scopes
303
+
304
+ Fixtures support different scopes to control when they are created and destroyed:
305
+
306
+ ```python
307
+ from rustest import fixture
308
+
309
+ @fixture # Default: function scope - new instance per test
310
+ def function_fixture() -> dict:
311
+ return {"value": "reset each test"}
312
+
313
+ @fixture(scope="class") # Shared across all tests in a class
314
+ def class_database() -> dict:
315
+ return {"connection": "db://test", "shared": True}
316
+
317
+ @fixture(scope="module") # Shared across all tests in a module
318
+ def module_config() -> dict:
319
+ return {"env": "test", "timeout": 30}
320
+
321
+ @fixture(scope="session") # Shared across entire test session
322
+ def session_cache() -> dict:
323
+ return {"global_cache": {}}
324
+
325
+ # Fixtures can depend on fixtures with different scopes
326
+ @fixture(scope="function")
327
+ def request_handler(module_config: dict, session_cache: dict) -> dict:
328
+ return {
329
+ "config": module_config, # module-scoped
330
+ "cache": session_cache, # session-scoped
331
+ "request_id": id(object()) # unique per test
332
+ }
333
+ ```
334
+
335
+ **Scope Behavior:**
336
+ - `function` (default): New instance for each test function
337
+ - `class`: Shared across all test methods in a test class
338
+ - `module`: Shared across all tests in a Python module
339
+ - `session`: Shared across the entire test session
340
+
341
+ Scoped fixtures are especially useful for expensive setup operations like database connections, API clients, or configuration loading.
342
+
343
+ **Using conftest.py for Shared Fixtures:**
344
+
345
+ You can define fixtures in a `conftest.py` file to share them across multiple test files:
346
+
347
+ ```python
348
+ # conftest.py
349
+ from rustest import fixture
350
+
351
+ @fixture(scope="session")
352
+ def database():
353
+ """Shared database connection for all tests."""
354
+ db = setup_database()
355
+ yield db
356
+ db.cleanup()
357
+
358
+ @fixture(scope="module")
359
+ def api_client():
360
+ """API client shared across a module."""
361
+ return create_api_client()
362
+ ```
363
+
364
+ All test files in the same directory (and subdirectories) can use these fixtures automatically.
365
+
366
+ #### Parametrized Tests
367
+
368
+ Run the same test with different inputs:
369
+
370
+ ```python
371
+ from rustest import parametrize
372
+
373
+ @parametrize("input,expected", [
374
+ (1, 2),
375
+ (2, 4),
376
+ (3, 6),
377
+ ])
378
+ def test_double(input: int, expected: int) -> None:
379
+ assert input * 2 == expected
380
+
381
+ # With custom test IDs for better output
382
+ @parametrize("value,expected", [
383
+ (2, 4),
384
+ (3, 9),
385
+ (4, 16),
386
+ ], ids=["two", "three", "four"])
387
+ def test_square(value: int, expected: int) -> None:
388
+ assert value ** 2 == expected
389
+ ```
390
+
391
+ #### Combining Fixtures and Parameters
392
+
393
+ ```python
394
+ from rustest import fixture, parametrize
395
+
396
+ @fixture
397
+ def multiplier() -> int:
398
+ return 10
399
+
400
+ @parametrize("value,expected", [
401
+ (1, 10),
402
+ (2, 20),
403
+ (3, 30),
404
+ ])
405
+ def test_multiply(multiplier: int, value: int, expected: int) -> None:
406
+ assert multiplier * value == expected
407
+ ```
408
+
409
+ #### Skipping Tests
410
+
411
+ ```python
412
+ from rustest import skip, mark
413
+
414
+ @skip("Not implemented yet")
415
+ def test_future_feature() -> None:
416
+ assert False
417
+
418
+ @mark.skip(reason="Waiting for API update")
419
+ def test_deprecated_api() -> None:
420
+ assert False
421
+ ```
422
+
423
+ #### Using Marks to Organize Tests
424
+
425
+ ```python
426
+ from rustest import mark
427
+
428
+ @mark.unit
429
+ def test_calculation() -> None:
430
+ assert 2 + 2 == 4
431
+
432
+ @mark.integration
433
+ def test_database_integration() -> None:
434
+ # Integration test
435
+ pass
436
+
437
+ @mark.slow
438
+ @mark.integration
439
+ def test_full_workflow() -> None:
440
+ # This test has multiple marks
441
+ pass
442
+ ```
443
+
444
+ #### Test Classes
445
+
446
+ Rustest supports pytest-style test classes, allowing you to organize related tests together:
447
+
448
+ ```python
449
+ from rustest import fixture, parametrize, mark
450
+
451
+ class TestBasicMath:
452
+ """Group related tests in a class."""
453
+
454
+ def test_addition(self):
455
+ assert 1 + 1 == 2
456
+
457
+ def test_subtraction(self):
458
+ assert 5 - 3 == 2
459
+
460
+ def test_multiplication(self):
461
+ assert 3 * 4 == 12
462
+ ```
463
+
464
+ **Using Fixtures in Test Classes:**
465
+
466
+ Test methods can inject fixtures just like standalone test functions:
467
+
468
+ ```python
469
+ from rustest import fixture
470
+
471
+ @fixture
472
+ def calculator():
473
+ return {"add": lambda x, y: x + y, "multiply": lambda x, y: x * y}
474
+
475
+ class TestCalculator:
476
+ """Test class using fixtures."""
477
+
478
+ def test_addition(self, calculator):
479
+ assert calculator["add"](2, 3) == 5
480
+
481
+ def test_multiplication(self, calculator):
482
+ assert calculator["multiply"](4, 5) == 20
483
+ ```
484
+
485
+ **Class-Scoped Fixtures:**
486
+
487
+ Class-scoped fixtures are shared across all test methods in the same class, perfect for expensive setup operations:
488
+
489
+ ```python
490
+ from rustest import fixture
491
+
492
+ @fixture(scope="class")
493
+ def database():
494
+ """Expensive setup shared across all tests in a class."""
495
+ db = {"connection": "db://test", "data": []}
496
+ return db
497
+
498
+ class TestDatabase:
499
+ """All tests share the same database fixture instance."""
500
+
501
+ def test_connection(self, database):
502
+ assert database["connection"] == "db://test"
503
+
504
+ def test_add_data(self, database):
505
+ database["data"].append("item1")
506
+ assert len(database["data"]) >= 1
507
+
508
+ def test_data_persists(self, database):
509
+ # Same database instance, so previous test's data is still there
510
+ assert len(database["data"]) >= 1
511
+ ```
512
+
513
+ **Fixture Methods Within Test Classes:**
514
+
515
+ You can define fixtures as methods inside test classes, providing class-specific setup:
516
+
517
+ ```python
518
+ from rustest import fixture
519
+
520
+ class TestWithFixtureMethod:
521
+ """Test class with its own fixture methods."""
522
+
523
+ @fixture(scope="class")
524
+ def class_resource(self):
525
+ """Fixture method shared across tests in this class."""
526
+ resource = {"value": 42, "name": "test_resource"}
527
+ yield resource
528
+ # Teardown happens after all tests in class
529
+ resource["closed"] = True
530
+
531
+ @fixture
532
+ def per_test_data(self, class_resource):
533
+ """Fixture method that depends on another fixture."""
534
+ return {"id": id(self), "resource": class_resource}
535
+
536
+ def test_uses_class_resource(self, class_resource):
537
+ assert class_resource["value"] == 42
538
+
539
+ def test_uses_per_test_data(self, per_test_data):
540
+ assert "resource" in per_test_data
541
+ assert per_test_data["resource"]["value"] == 42
542
+ ```
543
+
544
+ **Class Variables and Instance Variables:**
545
+
546
+ Test classes can use class variables for shared state and instance variables for per-test isolation:
547
+
548
+ ```python
549
+ class TestWithVariables:
550
+ """Test class with class and instance variables."""
551
+
552
+ class_variable = "shared_data" # Shared across all tests
553
+
554
+ def test_class_variable(self):
555
+ # Access class variable
556
+ assert self.class_variable == "shared_data"
557
+ assert TestWithVariables.class_variable == "shared_data"
558
+
559
+ def test_instance_variable(self):
560
+ # Each test gets a fresh instance
561
+ self.instance_var = "test_specific"
562
+ assert self.instance_var == "test_specific"
563
+ ```
564
+
565
+ **Parametrized Test Methods:**
566
+
567
+ Use `@parametrize` on class methods just like regular test functions:
568
+
569
+ ```python
570
+ from rustest import parametrize
571
+
572
+ class TestParametrized:
573
+ """Test class with parametrized methods."""
574
+
575
+ @parametrize("value,expected", [(2, 4), (3, 9), (4, 16)])
576
+ def test_square(self, value, expected):
577
+ assert value ** 2 == expected
578
+ ```
579
+
580
+ ### Test Output
581
+
582
+ When you run rustest, you'll see clean, informative output:
583
+
584
+ ```
585
+ PASSED 0.001s test_simple_assertion
586
+ PASSED 0.002s test_string_operations
587
+ PASSED 0.001s test_database_query
588
+ PASSED 0.003s test_square[two]
589
+ PASSED 0.001s test_square[three]
590
+ PASSED 0.002s test_square[four]
591
+ SKIPPED 0.000s test_future_feature
592
+ FAILED 0.005s test_broken_feature
593
+ ----------------------------------------
594
+ AssertionError: Expected 5, got 4
595
+ at test_example.py:42
596
+
597
+ 8 tests: 6 passed, 1 failed, 1 skipped in 0.015s
598
+ ```
599
+
600
+ ## Feature Comparison with pytest
601
+
602
+ Rustest aims to provide the most commonly-used pytest features with dramatically better performance. Here's how the two compare:
603
+
604
+ | Feature | pytest | rustest | Notes |
605
+ |---------|--------|---------|-------|
606
+ | **Core Test Discovery** |
607
+ | `test_*.py` / `*_test.py` files | โœ… | โœ… | Rustest uses Rust for dramatically faster discovery |
608
+ | Test function detection (`test_*`) | โœ… | โœ… | |
609
+ | Test class detection (`Test*`) | โœ… | โœ… | Full pytest-style class support with fixture methods |
610
+ | Pattern-based filtering | โœ… | โœ… | `-k` pattern matching |
611
+ | **Fixtures** |
612
+ | `@fixture` decorator | โœ… | โœ… | Rust-based dependency resolution |
613
+ | Fixture dependency injection | โœ… | โœ… | Much faster in rustest |
614
+ | Fixture scopes (function/class/module/session) | โœ… | โœ… | Full support for all scopes |
615
+ | Yield fixtures (setup/teardown) | โœ… | โœ… | Full support with cleanup |
616
+ | Fixture methods within test classes | โœ… | โœ… | Define fixtures as class methods |
617
+ | Fixture parametrization | โœ… | ๐Ÿšง | Planned |
618
+ | **Parametrization** |
619
+ | `@parametrize` decorator | โœ… | โœ… | Full support with custom IDs |
620
+ | Multiple parameter sets | โœ… | โœ… | |
621
+ | Parametrize with fixtures | โœ… | โœ… | |
622
+ | **Marks** |
623
+ | `@mark.skip` / `@skip` | โœ… | โœ… | Skip tests with reasons |
624
+ | Custom marks (`@mark.slow`, etc.) | โœ… | โœ… | Just added! |
625
+ | Mark with arguments | โœ… | โœ… | `@mark.timeout(30)` |
626
+ | Selecting tests by mark (`-m`) | โœ… | ๐Ÿšง | Mark metadata collected, filtering planned |
627
+ | **Test Execution** |
628
+ | Detailed assertion introspection | โœ… | โŒ | Uses standard Python assertions |
629
+ | Parallel execution | โœ… (`pytest-xdist`) | ๐Ÿšง | Planned (Rust makes this easier) |
630
+ | Test isolation | โœ… | โœ… | |
631
+ | Stdout/stderr capture | โœ… | โœ… | |
632
+ | **Reporting** |
633
+ | Pass/fail/skip summary | โœ… | โœ… | |
634
+ | Failure tracebacks | โœ… | โœ… | Full Python traceback support |
635
+ | Duration reporting | โœ… | โœ… | Per-test timing |
636
+ | JUnit XML output | โœ… | ๐Ÿšง | Planned |
637
+ | HTML reports | โœ… (`pytest-html`) | ๐Ÿšง | Planned |
638
+ | **Advanced Features** |
639
+ | Plugins | โœ… | โŒ | Not planned (keeps rustest simple) |
640
+ | Hooks | โœ… | โŒ | Not planned |
641
+ | Custom collectors | โœ… | โŒ | Not planned |
642
+ | `conftest.py` | โœ… | โœ… | Shared fixtures across test files |
643
+ | **Developer Experience** |
644
+ | Fully typed Python API | โš ๏ธ | โœ… | rustest uses `basedpyright` strict mode |
645
+ | Fast CI/CD runs | โš ๏ธ | โœ… | 78x faster = dramatically shorter feedback loops |
646
+
647
+ **Legend:**
648
+ - โœ… Fully supported
649
+ - ๐Ÿšง Planned or in progress
650
+ - โš ๏ธ Partial support
651
+ - โŒ Not planned
652
+
653
+ **Philosophy:** Rustest implements the 20% of pytest features that cover 80% of use cases, with a focus on raw speed and simplicity. If you need advanced pytest features like plugins or custom hooks, stick with pytest. If you want fast, straightforward testing with familiar syntax, rustest is for you.
654
+
655
+ ## License
656
+
657
+ rustest is distributed under the terms of the MIT license. See [LICENSE](LICENSE).
658
+
@@ -0,0 +1,16 @@
1
+ rustest-0.3.0.dist-info/METADATA,sha256=esXlixx0RIYl37WTKb13SkHQ2HrtF7LJDM698ymGoo8,20976
2
+ rustest-0.3.0.dist-info/WHEEL,sha256=bNaa2-XeaoMXnkzV391Sm2NgCjpJ3A2VmfN6ZUnNTZA,96
3
+ rustest-0.3.0.dist-info/entry_points.txt,sha256=7fUa3LO8vudQ4dKG1sTRaDnxcMdBSZsWs9EyuxFQ7Lk,48
4
+ rustest-0.3.0.dist-info/licenses/LICENSE,sha256=Ci0bB0T1ZGkqIV237Zp_Bv8LIJJ0Vxwc-AhLhgDgAoQ,1096
5
+ rustest/__init__.py,sha256=LL9UloOClzeNO6A-iMkEFtHDrBTAhRLko3sXy55H0QA,542
6
+ rustest/__main__.py,sha256=yMhaWvxGAV46BYY8fB6GoRy9oh8Z8YrS9wlZI3LmoyY,188
7
+ rustest/approx.py,sha256=sGaH15n3vSSv84dmR_QAIDV-xwaUrX-MqwpWIp5ihjk,5904
8
+ rustest/cli.py,sha256=-y-NDR9ndxK21Rlunm-Z5I0hPn95SdZ6RqHRG25KNVI,8958
9
+ rustest/core.py,sha256=oMNUz_9oa3j3FmKn41ttZxcS3IaOjRglYEKo46zifms,506
10
+ rustest/decorators.py,sha256=21PNOMl9nZoAm8kUnms9_tkhX5gAGNvr7xYG8kwESts,11723
11
+ rustest/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
+ rustest/reporting.py,sha256=g4jdlwjFoKF_fWA_sKfeDwmhDeHxPJQUqypa_E2XQlc,1686
13
+ rustest/rust.cp311-win_amd64.pyd,sha256=kRwTphiGE2mF4hT7zZ_suOr9d03h92AHGfpu4DvGCWc,1303040
14
+ rustest/rust.py,sha256=N_1C-uXRiC2qkV7ecKVcb51-XXyfhYNepd5zs-RIYOo,682
15
+ rustest/rust.pyi,sha256=rV1Msn2dGUeQ_GuPSoKjkgcFaoEehXD_QtzCY4-77_M,741
16
+ rustest-0.3.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: maturin (1.9.6)
3
+ Root-Is-Purelib: false
4
+ Tag: cp311-cp311-win_amd64
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ rustest=rustest.__main__:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Apex Engineers Inc
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, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.