⏱️4 min read · 745 words
पाइटेस्ट 2026 में पायथन परीक्षण के लिए स्वर्ण मानक है। Django, FastAPI, NumPy और हजारों ओपन-सोर्स प्रोजेक्ट्स द्वारा उपयोग किया जाने वाला, पाइटेस्ट लेखन और परीक्षण को सहज और शक्तिशाली बनाता है। यह संपूर्ण मार्गदर्शिका आपको आपके पहले परीक्षण से लेकर उन्नत फिक्स्चर, पैरामीट्रिज़ और सीआई एकीकरण तक ले जाती है।
📋 Table of Contents
पाइटेस्ट यूनिटटेस्ट से अधिक क्यों?
- सरल वाक्यविन्यास– मैदान
assertसहायक विफलता संदेशों वाले कथन - शक्तिशाली जुड़नार– स्वचालित विच्छेदन के साथ निर्भरता इंजेक्शन
- पैरामीट्रिज़– कई इनपुट के साथ एक परीक्षण चलाएं
- समृद्ध प्लगइन पारिस्थितिकी तंत्र– कवरेज, एक्सडिस्ट, मॉक, एसिंसियो, और बहुत कुछ
- बेहतर खोज– बॉयलरप्लेट के बिना स्वचालित रूप से परीक्षण ढूँढता है
स्थापना और पहला परीक्षण
# Install pytest
pip install pytest pytest-cov pytest-asyncio
# Create a test
# test_math.py
def add(a, b):
return a + b
def test_add():
assert add(2, 3) == 5
assert add(-1, 1) == 0
assert add(0, 0) == 0
# Run tests
pytest # run all tests
pytest test_math.py # specific file
pytest -v # verbose output
pytest -k "add" # run tests matching name
pytest --tb=short # shorter tracebacks
परीक्षण संगठन
# Recommended structure
# tests/
# conftest.py — shared fixtures
# test_users.py
# test_orders.py
# integration/
# test_api.py
# unit/
# test_services.py
# pytest.ini or pyproject.toml
# [tool.pytest.ini_options]
# testpaths = ["tests"]
# addopts = "-v --tb=short"
# Test class grouping
class TestUserService:
def test_create_user(self):
user = create_user("alice@example.com")
assert user.email == "alice@example.com"
def test_create_user_invalid_email(self):
with pytest.raises(ValueError, match="Invalid email"):
create_user("not-an-email")
def test_duplicate_email_raises(self, db):
create_user("alice@example.com")
with pytest.raises(DuplicateError):
create_user("alice@example.com")
फिक्स्चर – पाइटेस्ट की महाशक्ति
import pytest
from app.database import Database
from app.models import User
# Simple fixture
@pytest.fixture
def sample_user():
return User(id=1, name="Alice", email="alice@example.com")
# Fixture with setup and teardown
@pytest.fixture
def db():
database = Database(url="sqlite:///:memory:")
database.create_tables()
yield database # test runs here
database.drop_tables() # teardown
# Session-scoped fixture — runs once per test session
@pytest.fixture(scope="session")
def app_client():
from app import create_app
app = create_app(testing=True)
return app.test_client()
# Fixture using other fixtures
@pytest.fixture
def admin_user(db):
user = db.create_user(email="admin@test.com", role="admin")
return user
# conftest.py — shared fixtures auto-discovered
# pytest finds conftest.py automatically
पैरामीट्रिज़ – एकाधिक मामलों का परीक्षण करें
import pytest
def is_valid_email(email: str) -> bool:
import re
return bool(re.match(r"[^@]+@[^@]+\.[^@]+", email))
@pytest.mark.parametrize("email,expected", [
("alice@example.com", True),
("user+tag@domain.co.uk", True),
("invalid", False),
("no-at-sign", False),
("@nodomain.com", False),
("user@.com", False),
("", False),
])
def test_email_validation(email, expected):
assert is_valid_email(email) == expected
# Multiple parametrize decorators — creates cartesian product
@pytest.mark.parametrize("base", [2, 10, 16])
@pytest.mark.parametrize("exp", [1, 2, 3])
def test_powers(base, exp):
result = base ** exp
assert result == pow(base, exp)
पाइस्टेस्ट-मॉक के साथ मजाक करना
pip install pytest-mock
import pytest
from app.services import UserService
from app.email import EmailSender
def test_registration_sends_welcome_email(mocker):
# Mock the email sender
mock_send = mocker.patch("app.services.EmailSender.send")
service = UserService()
service.register("alice@example.com", "securepass")
# Assert email was sent
mock_send.assert_called_once_with(
to="alice@example.com",
subject="Welcome to TechPulse!"
)
def test_external_api_timeout(mocker):
# Mock requests.get to simulate timeout
mocker.patch(
"requests.get",
side_effect=requests.exceptions.Timeout
)
with pytest.raises(ServiceUnavailableError):
fetch_weather("London")
# Spy on real method (calls real code but tracks calls)
def test_cache_used_on_second_call(mocker):
spy = mocker.spy(cache_service, "get")
fetch_user(1)
fetch_user(1) # should hit cache
assert spy.call_count == 2
Async कोड का परीक्षण
pip install pytest-asyncio
import pytest
import pytest_asyncio
# Mark entire file as async
# pytest.ini: asyncio_mode = auto
@pytest.mark.asyncio
async def test_async_fetch():
async with AsyncClient(app=app, base_url="http://test") as client:
response = await client.get("/api/users")
assert response.status_code == 200
# Async fixture
@pytest_asyncio.fixture
async def async_db():
async with AsyncDatabase() as db:
await db.create_tables()
yield db
await db.drop_tables()
कवरेज रिपोर्टिंग
# Run with coverage
pytest --cov=app --cov-report=html --cov-report=term-missing
# Output:
# Name Stmts Miss Cover
# app/models.py 45 3 93%
# app/services.py 87 12 86%
# TOTAL 132 15 89%
# Fail if coverage below threshold
pytest --cov=app --cov-fail-under=80
# .coveragerc or pyproject.toml
# [tool.coverage.run]
# omit = ["*/tests/*", "*/migrations/*"]
पाइटेस्ट मार्क्स – परीक्षणों को वर्गीकृत करें
import pytest
# Define marks in pyproject.toml
# [tool.pytest.ini_options]
# markers = [
# "slow: marks tests as slow",
# "integration: marks integration tests",
# "unit: marks unit tests",
# ]
@pytest.mark.slow
@pytest.mark.integration
def test_full_user_registration_flow(client, db):
# End-to-end registration test
response = client.post("/register", json={
"email": "test@example.com",
"password": "SecurePass123!"
})
assert response.status_code == 201
assert db.users.count() == 1
# Run only unit tests
# pytest -m unit
# Skip slow tests in CI
# pytest -m "not slow"
GitHub क्रियाएँ CI एकीकरण
# .github/workflows/test.yml
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.11", "3.12"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
pip install uv
uv pip install -e ".[dev]" --system
- name: Run tests
run: pytest --cov=app --cov-fail-under=80
- name: Upload coverage
uses: codecov/codecov-action@v4
पाइस्टेस्ट महारत के लिए अभ्यास की आवश्यकता होती है लेकिन लाभ मिलता है। सुविधाओं (टीडीडी) के साथ-साथ परीक्षण लिखें, सेटअप/टियरडाउन के लिए फिक्स्चर का उपयोग करें, किनारे के मामलों के लिए पैरामीट्रिज़ करें और बाहरी निर्भरता का अनुकरण करें। व्यावसायिक तर्क पर 80%+ कवरेज और महत्वपूर्ण पथों पर 100% कवरेज का लक्ष्य रखें।
🔗 Share this article
✍️ Leave a Comment