python-skills 1.0.0__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.
Files changed (105) hide show
  1. python_skills/__init__.py +10 -0
  2. python_skills/__main__.py +6 -0
  3. python_skills/adapters/__init__.py +48 -0
  4. python_skills/adapters/agent_skills.py +415 -0
  5. python_skills/adapters/aider_adapter.py +226 -0
  6. python_skills/adapters/base.py +153 -0
  7. python_skills/adapters/claude.py +474 -0
  8. python_skills/adapters/cline.py +332 -0
  9. python_skills/adapters/codex.py +24 -0
  10. python_skills/adapters/continue_adapter.py +198 -0
  11. python_skills/adapters/cursor.py +327 -0
  12. python_skills/adapters/gemini.py +26 -0
  13. python_skills/adapters/goose.py +26 -0
  14. python_skills/adapters/junie.py +25 -0
  15. python_skills/adapters/kiro.py +382 -0
  16. python_skills/adapters/opencode.py +27 -0
  17. python_skills/adapters/roo.py +25 -0
  18. python_skills/adapters/universal.py +203 -0
  19. python_skills/adapters/vscode.py +27 -0
  20. python_skills/adapters/windsurf.py +26 -0
  21. python_skills/adapters/zed.py +27 -0
  22. python_skills/cli.py +326 -0
  23. python_skills/config.py +160 -0
  24. python_skills/detector.py +152 -0
  25. python_skills/installer.py +163 -0
  26. python_skills/markers.py +115 -0
  27. python_skills/skills/__init__.py +14 -0
  28. python_skills/skills/loader.py +171 -0
  29. python_skills/skills/metadata.py +152 -0
  30. python_skills/skills/registry.py +101 -0
  31. python_skills/state.py +204 -0
  32. python_skills-1.0.0.dist-info/METADATA +99 -0
  33. python_skills-1.0.0.dist-info/RECORD +105 -0
  34. python_skills-1.0.0.dist-info/WHEEL +4 -0
  35. python_skills-1.0.0.dist-info/entry_points.txt +2 -0
  36. python_skills-1.0.0.dist-info/licenses/LICENSE +21 -0
  37. skills/advanced_python.md +239 -0
  38. skills/anti_patterns/index.md +406 -0
  39. skills/comprehensions.md +167 -0
  40. skills/control_flow.md +175 -0
  41. skills/data_structures.md +243 -0
  42. skills/debugging/common_bugs.md +222 -0
  43. skills/debugging/inspection_techniques.md +249 -0
  44. skills/debugging/root_cause.md +203 -0
  45. skills/engineering/application_logging.md +195 -0
  46. skills/engineering/cli_apps.md +207 -0
  47. skills/engineering/configuration.md +218 -0
  48. skills/engineering/database.md +240 -0
  49. skills/engineering/dependency_management.md +205 -0
  50. skills/engineering/http_clients.md +267 -0
  51. skills/engineering/modules_packages.md +211 -0
  52. skills/engineering/packaging.md +197 -0
  53. skills/engineering/project_structure.md +155 -0
  54. skills/engineering/pyproject_toml.md +302 -0
  55. skills/engineering/virtual_environments.md +206 -0
  56. skills/functions.md +244 -0
  57. skills/generation/async_concurrency.md +291 -0
  58. skills/generation/error_handling.md +276 -0
  59. skills/generation/protocols_generics.md +243 -0
  60. skills/generation/type_hints.md +290 -0
  61. skills/generation/validation_pipeline.md +274 -0
  62. skills/generation/workflow.md +190 -0
  63. skills/oop.md +228 -0
  64. skills/quality/abstractions.md +154 -0
  65. skills/quality/comments.md +177 -0
  66. skills/quality/documentation.md +176 -0
  67. skills/quality/duplication.md +137 -0
  68. skills/quality/maintainability.md +142 -0
  69. skills/quality/naming.md +171 -0
  70. skills/quality/quality_functions.md +245 -0
  71. skills/quality/readability.md +239 -0
  72. skills/quality/type_annotations.md +192 -0
  73. skills/refactoring/behavior_preservation.md +157 -0
  74. skills/refactoring/incremental.md +187 -0
  75. skills/refactoring/interface_stability.md +199 -0
  76. skills/refactoring/safe_refactoring.md +206 -0
  77. skills/security/auth_boundaries.md +200 -0
  78. skills/security/command_injection.md +207 -0
  79. skills/security/dependency_risks.md +282 -0
  80. skills/security/file_handling.md +156 -0
  81. skills/security/input_validation.md +190 -0
  82. skills/security/path_traversal.md +172 -0
  83. skills/security/secrets.md +171 -0
  84. skills/security/sql_injection.md +188 -0
  85. skills/security/unsafe_deserialization.md +164 -0
  86. skills/stdlib/argparse.md +178 -0
  87. skills/stdlib/collections.md +212 -0
  88. skills/stdlib/datetime.md +187 -0
  89. skills/stdlib/functools.md +238 -0
  90. skills/stdlib/itertools.md +183 -0
  91. skills/stdlib/json.md +162 -0
  92. skills/stdlib/logging.md +185 -0
  93. skills/stdlib/os_sys.md +184 -0
  94. skills/stdlib/pathlib.md +218 -0
  95. skills/stdlib/re.md +171 -0
  96. skills/stdlib/statistics.md +112 -0
  97. skills/stdlib/subprocess.md +211 -0
  98. skills/testing/async_tests.md +249 -0
  99. skills/testing/coverage.md +168 -0
  100. skills/testing/edge_cases.md +197 -0
  101. skills/testing/fixtures_mocks.md +203 -0
  102. skills/testing/organization.md +205 -0
  103. skills/testing/parameterized.md +174 -0
  104. skills/testing/regression_tests.md +165 -0
  105. skills/variables_types.md +107 -0
@@ -0,0 +1,203 @@
1
+ # Testing: Fixtures and Mocks
2
+
3
+ **Purpose**: Effective test fixtures and mocking strategies.
4
+
5
+ **When to use**: Writing tests that need setup, dependencies, or isolation.
6
+
7
+ ---
8
+
9
+ ## Core Rules
10
+
11
+ ### Fixture Principles
12
+ - **Scope appropriately**: `function` (default), `class`, `module`, `session`
13
+ - **Single responsibility**: Each fixture does one thing
14
+ - **Explicit dependencies**: Fixtures request what they need
15
+ - **Cleanup**: Use `yield` for teardown
16
+
17
+ ### Fixture Patterns
18
+
19
+ ```python
20
+ # conftest.py
21
+
22
+ # Session-scoped expensive resource
23
+ @pytest.fixture(scope="session")
24
+ def database():
25
+ db = create_test_database()
26
+ yield db
27
+ db.drop()
28
+
29
+ # Function-scoped clean state
30
+ @pytest.fixture
31
+ def clean_db(database):
32
+ database.truncate_all()
33
+ yield database
34
+ database.truncate_all()
35
+
36
+ # Factory fixture
37
+ @pytest.fixture
38
+ def user_factory(clean_db):
39
+ def _create(email: str = "test@test.com", **kwargs):
40
+ return UserService(clean_db).create(email, **kwargs)
41
+ return _create
42
+
43
+ # Parametrized fixture
44
+ @pytest.fixture(params=["sqlite", "postgresql"])
45
+ def db_engine(request):
46
+ if request.param == "sqlite":
47
+ return create_sqlite_engine()
48
+ return create_pg_engine()
49
+ ```
50
+
51
+ ### Mocking Guidelines
52
+
53
+ ```python
54
+ # Mock at the boundary (where your code calls external code)
55
+ # NOT deep in the call stack
56
+
57
+ # GOOD — mock the client your code uses
58
+ @patch("mypackage.services.payment.StripeClient")
59
+ def test_charge(mock_stripe, payment_service):
60
+ mock_stripe.return_value.charge.return_value = ChargeResult(success=True)
61
+ result = payment_service.charge(100, "token")
62
+ assert result.success
63
+
64
+ # BAD — mock internal implementation
65
+ @patch("mypackage.services.payment.calculate_fee")
66
+ def test_charge_bad(mock_fee, payment_service):
67
+ ...
68
+ ```
69
+
70
+ ### Mock Types
71
+ ```python
72
+ from unittest.mock import Mock, MagicMock, AsyncMock, PropertyMock
73
+
74
+ # Sync mock
75
+ mock = Mock()
76
+ mock.method.return_value = "value"
77
+ mock.method.side_effect = Exception("error")
78
+ mock.property = PropertyMock(return_value="value")
79
+
80
+ # Async mock
81
+ async_mock = AsyncMock()
82
+ async_mock.async_method.return_value = "value"
83
+ async_mock.async_method.side_effect = [val1, val2, Exception("error")]
84
+
85
+ # Spec (prevents typos)
86
+ mock = Mock(spec=RealClass)
87
+ mock.real_method() # OK
88
+ mock.typo_method() # AttributeError!
89
+
90
+ # Autospec (signature checking)
91
+ mock = Mock(autospec=RealClass)
92
+ mock.real_method(1, 2) # OK
93
+ mock.real_method() # TypeError: missing args
94
+ ```
95
+
96
+ ### Test Data Builders
97
+ ```python
98
+ # For complex test objects
99
+ class UserBuilder:
100
+ def __init__(self):
101
+ self._email = "test@test.com"
102
+ self._name = "Test User"
103
+ self._active = True
104
+ self._roles = []
105
+
106
+ def with_email(self, email: str) -> "UserBuilder":
107
+ self._email = email
108
+ return self
109
+
110
+ def with_name(self, name: str) -> "UserBuilder":
111
+ self._name = name
112
+ return self
113
+
114
+ def inactive(self) -> "UserBuilder":
115
+ self._active = False
116
+ return self
117
+
118
+ def with_roles(self, *roles) -> "UserBuilder":
119
+ self._roles = list(roles)
120
+ return self
121
+
122
+ def build(self) -> User:
123
+ return User(
124
+ email=self._email,
125
+ name=self._name,
126
+ active=self._active,
127
+ roles=self._roles,
128
+ )
129
+
130
+ # Usage
131
+ def test_admin_user(user_factory):
132
+ admin = UserBuilder().with_roles("admin").build()
133
+ assert admin.has_permission("admin")
134
+ ```
135
+
136
+ ---
137
+
138
+ ## Decision Rules
139
+
140
+ | Need | Fixture/Mock Pattern |
141
+ |------|---------------------|
142
+ | Shared expensive resource | `scope="session"` fixture |
143
+ | Clean state per test | Function fixture with cleanup |
144
+ | Test data variations | Factory fixture or builder |
145
+ | External service | Mock at boundary |
146
+ | Time-dependent | `freezegun` / mock `time.time` |
147
+ | Random-dependent | Mock `random` / `secrets` |
148
+ | Multiple implementations | Parametrized fixture |
149
+
150
+ ---
151
+
152
+ ## Preferred Patterns
153
+
154
+ ```python
155
+ # Conftest organization
156
+ # tests/conftest.py — project-wide
157
+ # tests/unit/conftest.py — unit-specific
158
+ # tests/integration/conftest.py — integration-specific
159
+
160
+ # Fixture naming
161
+ @pytest.fixture
162
+ def user_service() -> UserService: # Return type hint
163
+ ...
164
+
165
+ # Async fixtures
166
+ @pytest.fixture
167
+ async def async_client() -> AsyncClient:
168
+ client = AsyncClient()
169
+ yield client
170
+ await client.aclose()
171
+
172
+ # Mock fixture
173
+ @pytest.fixture
174
+ def mock_email_service() -> Mock:
175
+ return Mock(spec=EmailService)
176
+ ```
177
+
178
+ ---
179
+
180
+ ## Avoid
181
+
182
+ - Fixtures with side effects (no cleanup)
183
+ - Over-mocking (mock everything, test nothing)
184
+ - Mocking standard library (mock `requests`, not `json`)
185
+ - Fixtures that depend on test order
186
+ - Complex fixture chains (>3 levels)
187
+
188
+ ---
189
+
190
+ ## Validation Considerations
191
+
192
+ - Fixture setup/teardown time (profile with `--durations=10`)
193
+ - Mock call verification (`assert_called_once_with`)
194
+ - No real network calls in unit tests (use `pytest-mock` + `requests-mock`)
195
+
196
+ ---
197
+
198
+ ## Related Skills
199
+
200
+ - `testing/organization.md`
201
+ - `testing/parameterized.md`
202
+ - `testing/async_tests.md`
203
+ - `generation/error_handling.md`
@@ -0,0 +1,205 @@
1
+ # Testing: Organization
2
+
3
+ **Purpose**: Structuring test suites for maintainability and speed.
4
+
5
+ **When to use**: Setting up or reorganizing test structure.
6
+
7
+ ---
8
+
9
+ ## Core Rules
10
+
11
+ ### Directory Structure
12
+ ```
13
+ tests/
14
+ ├── conftest.py # Root fixtures
15
+ ├── pytest.ini # Config (or pyproject.toml)
16
+ ├── unit/ # Fast, isolated
17
+ │ ├── conftest.py
18
+ │ ├── test_models.py
19
+ │ ├── test_services.py
20
+ │ └── test_utils.py
21
+ ├── integration/ # Real dependencies
22
+ │ ├── conftest.py
23
+ │ ├── test_database.py
24
+ │ ├── test_api.py
25
+ │ └── test_external.py
26
+ ├── e2e/ # Full stack (optional)
27
+ │ ├── conftest.py
28
+ │ └── test_flows.py
29
+ ├── performance/ # Benchmarks (optional)
30
+ │ └── test_benchmarks.py
31
+ ├── fixtures/ # Shared test data
32
+ │ ├── sample_users.json
33
+ │ └── sample_orders.json
34
+ └── helpers/ # Test utilities
35
+ ├── __init__.py
36
+ ├── builders.py
37
+ └── matchers.py
38
+ ```
39
+
40
+ ### Naming Conventions
41
+ ```
42
+ test_<module>.py # Module tests
43
+ test_<class>.py # Class tests
44
+ test_<function>_<scenario>.py # Specific scenario
45
+ Test<ClassName> # Test class
46
+ test_<function>_<condition> # Test function
47
+ ```
48
+
49
+ ### Test Class Organization
50
+ ```python
51
+ class TestUserService:
52
+ """Tests for UserService."""
53
+
54
+ class TestCreateUser:
55
+ """Tests for create_user method."""
56
+
57
+ def test_creates_user_with_valid_data(self):
58
+ ...
59
+
60
+ def test_raises_on_duplicate_email(self):
61
+ ...
62
+
63
+ def test_hashes_password(self):
64
+ ...
65
+
66
+ class TestGetUser:
67
+ """Tests for get_user method."""
68
+
69
+ def test_returns_user_when_exists(self):
70
+ ...
71
+
72
+ def test_returns_none_when_not_found(self):
73
+ ...
74
+ ```
75
+
76
+ ### Marks for Categorization
77
+ ```python
78
+ # pytest.ini
79
+ [tool.pytest.ini_options]
80
+ markers = [
81
+ "unit: Fast, isolated tests",
82
+ "integration: Tests with real dependencies",
83
+ "e2e: Full system tests",
84
+ "slow: Takes >1s",
85
+ "requires_db: Needs database",
86
+ "requires_network: Needs external API",
87
+ "regression: Bug fix verification",
88
+ "security: Security-related tests",
89
+ ]
90
+
91
+ # Usage
92
+ @pytest.mark.unit
93
+ def test_unit():
94
+ ...
95
+
96
+ @pytest.mark.integration
97
+ @pytest.mark.requires_db
98
+ def test_with_db():
99
+ ...
100
+
101
+ # Run subsets
102
+ # pytest -m unit
103
+ # pytest -m "integration and not slow"
104
+ # pytest -m "not e2e"
105
+ ```
106
+
107
+ ### Configuration
108
+ ```toml
109
+ # pyproject.toml
110
+ [tool.pytest.ini_options]
111
+ testpaths = ["tests"]
112
+ python_files = ["test_*.py"]
113
+ python_classes = ["Test*"]
114
+ python_functions = ["test_*"]
115
+ addopts = "-v --strict-markers --strict-config --tb=short"
116
+ filterwarnings = [
117
+ "ignore::DeprecationWarning",
118
+ "ignore::PendingDeprecationWarning",
119
+ ]
120
+ asyncio_mode = "auto"
121
+
122
+ [tool.coverage.run]
123
+ source = ["src"]
124
+ omit = ["tests/*", "*/__main__.py"]
125
+
126
+ [tool.coverage.report]
127
+ exclude_lines = [
128
+ "pragma: no cover",
129
+ "def __repr__",
130
+ "raise AssertionError",
131
+ "raise NotImplementedError",
132
+ "if __name__ == .__main__.:",
133
+ ]
134
+ ```
135
+
136
+ ---
137
+
138
+ ## Decision Rules
139
+
140
+ | Test Type | Location | Markers | Speed Target |
141
+ |-----------|----------|---------|--------------|
142
+ | Unit | `tests/unit/` | `unit` | <100ms |
143
+ | Integration | `tests/integration/` | `integration`, `requires_db` | <1s |
144
+ | E2E | `tests/e2e/` | `e2e` | <30s |
145
+ | Regression | `tests/regression/` | `regression` | Varies |
146
+
147
+ ---
148
+
149
+ ## Preferred Patterns
150
+
151
+ ```python
152
+ # Shared test utilities
153
+ # tests/helpers/builders.py
154
+ class UserBuilder:
155
+ def __init__(self):
156
+ self.data = {"email": "test@test.com", "name": "Test"}
157
+
158
+ def with_email(self, email):
159
+ self.data["email"] = email
160
+ return self
161
+
162
+ def build(self):
163
+ return User(**self.data)
164
+
165
+ # tests/helpers/matchers.py
166
+ def assert_user_equal(actual: User, expected: User):
167
+ assert actual.id == expected.id
168
+ assert actual.email == expected.email
169
+ assert actual.name == expected.name
170
+ # Don't compare timestamps (flaky)
171
+
172
+ # Custom assertions
173
+ def assert_validation_error(exc_info, field: str, message_contains: str):
174
+ assert exc_info.type is ValidationError
175
+ assert exc_info.value.field == field
176
+ assert message_contains in str(exc_info.value)
177
+ ```
178
+
179
+ ---
180
+
181
+ ## Avoid
182
+
183
+ - All tests in one directory
184
+ - No markers (can't run subsets)
185
+ - Mixed unit/integration in same file
186
+ - Slow tests in unit suite
187
+ - Test order dependencies
188
+ - Duplicate fixtures across directories
189
+
190
+ ---
191
+
192
+ ## Validation Considerations
193
+
194
+ - `pytest --collect-only | head -20` shows structure
195
+ - `pytest --durations=10` shows slowest tests
196
+ - Coverage targets per test type
197
+ - CI runs unit on every PR, integration nightly
198
+
199
+ ---
200
+
201
+ ## Related Skills
202
+
203
+ - `testing/fixtures_mocks.md`
204
+ - `testing/parameterized.md`
205
+ - `engineering/virtual_environments.md`
@@ -0,0 +1,174 @@
1
+ # Testing: Parameterized Tests
2
+
3
+ **Purpose**: Run same test logic with multiple inputs.
4
+
5
+ **When to use**: Testing multiple cases, edge cases, boundary values.
6
+
7
+ ---
8
+
9
+ ## Core Rules
10
+
11
+ ### Basic Parametrization
12
+ ```python
13
+ import pytest
14
+
15
+ @pytest.mark.parametrize("input,expected", [
16
+ (1, 2),
17
+ (2, 4),
18
+ (3, 6),
19
+ (0, 0),
20
+ (-1, -2),
21
+ ])
22
+ def test_double(input: int, expected: int):
23
+ assert double(input) == expected
24
+ ```
25
+
26
+ ### Multiple Parameters
27
+ ```python
28
+ @pytest.mark.parametrize("a,b,expected", [
29
+ (1, 2, 3),
30
+ (0, 0, 0),
31
+ (-1, 1, 0),
32
+ (100, 200, 300),
33
+ ])
34
+ def test_add(a: int, b: int, expected: int):
35
+ assert add(a, b) == expected
36
+ ```
37
+
38
+ ### Parametrized Fixtures
39
+ ```python
40
+ @pytest.fixture(params=[1, 2, 3, 10, 100])
41
+ def number(request):
42
+ return request.param
43
+
44
+ def test_positive(number: int):
45
+ assert number > 0
46
+
47
+ # Combined with test parametrization
48
+ @pytest.mark.parametrize("multiplier", [2, 3, 10])
49
+ def test_multiply(number: int, multiplier: int):
50
+ assert number * multiplier > 0
51
+ ```
52
+
53
+ ### Parametrizing with IDs
54
+ ```python
55
+ @pytest.mark.parametrize("email,valid", [
56
+ pytest.param("test@example.com", True, id="valid-standard"),
57
+ pytest.param("user+tag@domain.org", True, id="valid-plus-tag"),
58
+ pytest.param("invalid", False, id="invalid-no-at"),
59
+ pytest.param("@domain.com", False, id="invalid-no-local"),
60
+ pytest.param("user@", False, id="invalid-no-domain"),
61
+ ], ids=lambda x: x[1] and "valid" or "invalid")
62
+ def test_email_validation(email: str, valid: bool):
63
+ assert is_valid_email(email) == valid
64
+ ```
65
+
66
+ ### Parametrizing Classes
67
+ ```python
68
+ @pytest.mark.parametrize("storage_cls", [InMemoryStorage, RedisStorage, FileStorage])
69
+ class TestStorage:
70
+ def test_save_and_load(self, storage_cls):
71
+ storage = storage_cls()
72
+ storage.save("key", "value")
73
+ assert storage.load("key") == "value"
74
+
75
+ def test_delete(self, storage_cls):
76
+ storage = storage_cls()
77
+ storage.save("key", "value")
78
+ storage.delete("key")
79
+ assert storage.load("key") is None
80
+ ```
81
+
82
+ ### Dynamic Parametrization
83
+ ```python
84
+ def pytest_generate_tests(metafunc):
85
+ """Hook for dynamic parametrization."""
86
+ if "test_file" in metafunc.fixturenames:
87
+ test_files = list(Path("test_data").glob("*.json"))
88
+ metafunc.parametrize("test_file", test_files, ids=lambda p: p.stem)
89
+
90
+ def test_with_file(test_file: Path):
91
+ data = json.loads(test_file.read_text())
92
+ assert process(data) == data["expected"]
93
+ ```
94
+
95
+ ### Cartesian Product (Multiple Decorators)
96
+ ```python
97
+ @pytest.mark.parametrize("os", ["linux", "windows", "macos"])
98
+ @pytest.mark.parametrize("python", ["3.10", "3.11", "3.12"])
99
+ def test_compatibility(os: str, python: str):
100
+ # Runs 9 combinations
101
+ assert is_compatible(os, python)
102
+ ```
103
+
104
+ ---
105
+
106
+ ## Decision Rules
107
+
108
+ | Situation | Pattern |
109
+ |-----------|---------|
110
+ | Few cases (<10) | Inline parametrize |
111
+ | Many cases / data-driven | External data + `pytest_generate_tests` |
112
+ | Cross-product | Multiple `@parametrize` |
113
+ | Fixture variation | Parametrized fixture |
114
+ | Different implementations | Parametrize class |
115
+
116
+ ---
117
+
118
+ ## Preferred Patterns
119
+
120
+ ```python
121
+ # Boundary value testing
122
+ @pytest.mark.parametrize("value", [
123
+ 0, # Minimum
124
+ 1, # Just above min
125
+ 100, # Typical
126
+ 999, # Just below max
127
+ 1000, # Maximum
128
+ 1001, # Just above max (invalid)
129
+ ])
130
+ def test_range_validation(value: int):
131
+ if 0 <= value <= 1000:
132
+ assert validate_range(value) == value
133
+ else:
134
+ with pytest.raises(ValidationError):
135
+ validate_range(value)
136
+
137
+ # Error case parametrization
138
+ ERROR_CASES = [
139
+ (ValidationError, "empty", {}),
140
+ (ValidationError, "missing_field", {"name": "test"}),
141
+ (ConflictError, "duplicate", {"name": "test", "email": "a@b.c"}),
142
+ ]
143
+
144
+ @pytest.mark.parametrize("error_type,case_name,input_data", ERROR_CASES)
145
+ def test_create_user_errors(error_type, case_name, input_data):
146
+ with pytest.raises(error_type):
147
+ create_user(**input_data)
148
+ ```
149
+
150
+ ---
151
+
152
+ ## Avoid
153
+
154
+ - Too many combinations (exponential explosion)
155
+ - Parametrizing unrelated tests together
156
+ - Complex logic in parametrization (use fixtures instead)
157
+ - Missing `ids` for readability in output
158
+
159
+ ---
160
+
161
+ ## Validation Considerations
162
+
163
+ - `pytest --collect-only` shows all generated tests
164
+ - `pytest -v` shows parametrized test names
165
+ - `pytest -k "valid"` filters by id/name
166
+ - Duration tracking for large parametrized suites
167
+
168
+ ---
169
+
170
+ ## Related Skills
171
+
172
+ - `testing/organization.md`
173
+ - `testing/fixtures_mocks.md`
174
+ - `testing/edge_cases.md`