TS004: TestNamingConvention
Overview
| Property | Value |
|---|---|
| ID | TS004 |
| Name | TestNamingConvention |
| Group | tests |
| Severity | NOTE |
Description
Verifies that test files follow naming conventions for automatic test discovery.
pytest discovers tests by looking for files matching specific patterns. If your test files don’t follow these conventions, they may be silently skipped during test runs.
What it checks
The check scans all Python files in tests/ or test/ directories and verifies they match pytest’s discovery patterns:
- PASSED: All Python files match
test_*.pyor*_test.pypattern - FAILED: One or more files don’t match the expected patterns
- NOT_APPLICABLE: No tests directory found
Default allowed patterns
test_*.py(recommended, e.g.,test_module.py)*_test.py(alternative, e.g.,module_test.py)
Default allowed files
These files are allowed without matching the pattern:
__init__.py(package marker)conftest.py(pytest fixtures)
How to fix
Rename test files to use proper prefix
# Before - pytest won't discover these
tests/
my_tests.py # Wrong: not "test_*" or "*_test"
tests_for_module.py # Wrong: not "test_*" or "*_test"
# After - pytest will discover these
tests/
test_my_module.py # Correct: starts with "test_"
test_module.py # Correct: starts with "test_"Use suffix pattern if preferred
# Also valid pytest patterns
tests/
module_test.py # Correct: ends with "_test"
integration_test.py # Correct: ends with "_test"Move helper modules to conftest or separate files
# Before - pytest tries to collect from helpers.py
tests/
helpers.py # Contains test utilities, not tests
test_module.py
# After - clear separation
tests/
conftest.py # Move fixtures here (allowed by default)
test_module.pyOr if you need shared utilities that aren’t fixtures:
tests/
conftest.py
test_module.py
_helpers.py # Private module (starts with _)Configuration
Add custom patterns
If your project uses different naming conventions:
[tool.pycmdcheck.checks.TS004]
patterns = [
"test_*.py",
"*_test.py",
"check_*.py", # Custom pattern
]Add allowed files
Allow additional support files without matching patterns:
[tool.pycmdcheck.checks.TS004]
allowed_files = [
"fixtures.py",
"helpers.py",
"factories.py",
]Skip this check
[tool.pycmdcheck]
skip = ["TS004"]CLI
pycmdcheck --skip TS004Why naming matters
Test discovery
pytest’s default test discovery:
# pytest.ini or pyproject.toml
[tool.pytest.ini_options]
python_files = ["test_*.py", "*_test.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]Files not matching these patterns are ignored, which can lead to:
- Tests silently not running
- False confidence in test coverage
- Confusion when tests “pass” but bugs remain
IDE integration
Most IDEs recognize test_*.py files for:
- Test runner integration
- Coverage highlighting
- Quick navigation to tests
Convention over configuration
Using standard patterns means:
- New contributors immediately understand the structure
- CI/CD pipelines work without custom configuration
- Tools like pytest-cov, tox, and nox work out of the box