Skip to main content

A pytest plugin that reviews the quality of your tests

Project description

pytest-review

A pytest plugin that reviews the quality of your tests.

PyPI version Python versions License: MIT

Overview

pytest-review analyzes your test suite and provides actionable feedback on test quality. It detects common anti-patterns, missing assertions, overly complex tests, and more.

Features

  • Static Analysis: AST-based detection of test quality issues
  • Dynamic Analysis: Runtime performance tracking
  • Multiple Output Formats: Terminal, JSON, and HTML reports
  • Configurable: Customize thresholds and enable/disable analyzers
  • Quality Scoring: Get a letter grade (A-F) for your test suite

Analyzers

Analyzer Description
assertions Detects empty tests, trivial assertions (assert True), tautologies
naming Checks for descriptive test names, proper snake_case
complexity Flags tests with too many statements, deep nesting, high cyclomatic complexity
patterns Identifies anti-patterns: bare except, time.sleep, print statements
isolation Detects global state modifications, class attribute mutations
performance Tracks slow tests at runtime
smells Detects test smells: assertion roulette, duplicate asserts, eager tests, magic numbers

Installation

pip install pytest-review

Quick Start

Run pytest with the --review flag:

pytest --review

Example output:

====================== pytest-review: Test Quality Report ======================
  [X] tests/test_example.py:15 [test_empty] Test has no assertions
      Suggestion: Add at least one assertion to verify expected behavior
  [!] tests/test_example.py:20 [test_complex] Test has cyclomatic complexity of 12
      Suggestion: Simplify test logic or split into multiple tests
----------------------------------- Summary ------------------------------------
  Tests analyzed: 25
  Errors: 2
  Warnings: 5
  Info: 3
  Quality: NEEDS IMPROVEMENT

  Overall Score: 72.0/100 (C)
================================================================================

Command Line Options

Option Description
--review Enable test quality review
--review-format Output format: terminal (default), json, html
--review-output Write report to file
--review-strict Fail if quality errors are found
--review-min-score Minimum required score (0-100)
--review-only Comma-separated list of analyzers to run

Examples

# Generate HTML report
pytest --review --review-format=html --review-output=report.html

# Generate JSON report
pytest --review --review-format=json --review-output=report.json

# Run only specific analyzers
pytest --review --review-only=assertions,naming

# Fail CI if score below 80
pytest --review --review-min-score=80

# Strict mode: fail on any errors
pytest --review --review-strict

Configuration

Configure pytest-review in your pyproject.toml:

[tool.pytest-review]
enabled = true
strict = false
min_score = 0

[tool.pytest-review.analyzers]
assertions = { enabled = true, min_assertions = 1 }
naming = { enabled = true, min_length = 10 }
complexity = { enabled = true, max_statements = 20, max_depth = 3, max_complexity = 5 }
patterns = { enabled = true }
isolation = { enabled = true }
performance = { enabled = true, slow_threshold_ms = 500, very_slow_threshold_ms = 2000 }
smells = { enabled = true, max_assertions_without_message = 1, check_magic_numbers = true }

Skipping Tests

Use the review_skip marker to exclude specific tests from review:

import pytest

@pytest.mark.review_skip
def test_intentionally_complex():
    # This test won't be analyzed
    ...

Scoring System

The quality score is calculated using weighted categories:

Category Weight Analyzers
Assertions 30% assertions
Clarity 25% naming, smells
Isolation 20% isolation
Simplicity 15% complexity, patterns
Performance 10% performance

Severity penalties:

  • Error: -15 points per issue
  • Warning: -5 points per issue
  • Info: -1 point per issue

Critical penalties (applied globally):

  • Missing assertions: -20 points
  • Trivial assertions: -10 points

Grade Scale

Grade Score Range
A 90-100
B 80-89
C 70-79
D 60-69
F 0-59

Issue Types

Errors (X)

Critical issues that indicate likely bugs or useless tests:

  • assertions.missing - Test has no assertions
  • assertions.trivial - Trivial assertion like assert True
  • assertions.tautology - Comparing value to itself

Warnings (!)

Issues that may indicate problems:

  • naming.non_descriptive - Generic names like test_foo
  • complexity.too_many_statements - Test too long
  • complexity.too_deep - Excessive nesting
  • complexity.too_complex - High cyclomatic complexity
  • patterns.bare_except - Catches all exceptions
  • patterns.sleep_in_test - Uses time.sleep()
  • isolation.global_modification - Modifies global state
  • smells.assertion_roulette - Multiple assertions without messages
  • smells.duplicate_assert - Duplicate assertion statements
  • smells.ignored_test - Test is skipped with decorator

Info (i)

Suggestions for improvement:

  • naming.too_short - Name could be more descriptive
  • patterns.print_statement - Debug print left in test
  • performance.slow_test - Test runs slowly
  • smells.magic_number - Literal number in assertion
  • smells.eager_test - Test verifies multiple methods

Acknowledgments

  • The smells analyzer is inspired by the pytest-smell project from the dissertation "Detecting Test Smells in Python" by Maxim Pacsial.
  • Test smell concepts are based on research by Van Deursen et al. ("Refactoring Test Code", 2001) and Meszaros ("xUnit Test Patterns", 2007).

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytest_review-0.1.0.tar.gz (113.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pytest_review-0.1.0-py3-none-any.whl (36.6 kB view details)

Uploaded Python 3

File details

Details for the file pytest_review-0.1.0.tar.gz.

File metadata

  • Download URL: pytest_review-0.1.0.tar.gz
  • Upload date:
  • Size: 113.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for pytest_review-0.1.0.tar.gz
Algorithm Hash digest
SHA256 1365b4f7458717442f819441ba0d0a041223f2e016bb3726f6734ff96d3683ff
MD5 39e9a728e06a301ec6e4c61e847816bf
BLAKE2b-256 2b28b436aeb87f00fae9f8c0f9273c7adf0fd11ba256e701ac814fb5fed58a3d

See more details on using hashes here.

File details

Details for the file pytest_review-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pytest_review-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 36.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for pytest_review-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 83fcba9e4728cb9ef8f4876a4bd34ae1cc8013e8dbbcbe01d45b854890a46553
MD5 c1912bef5ae10719b18ded53eb1dd018
BLAKE2b-256 97e7b942baad367a33e206420c940a784c006bf9fbdbec842bc728146ffa7bd8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page