ویژگی تصویر

کتابخانه pytest در پایتون

  /  پایتون   /  کتابخانه pytest در پایتون
بنر تبلیغاتی الف

کتابخانه pytest یکی از قدرتمندترین ابزارهای تست خودکار (Automated Testing) در زبان برنامه‌نویسی پایتون است. این کتابخانه به توسعه‌دهندگان کمک می‌کند تا کدهای خود را به شکل مؤثر، سریع و قابل اطمینان تست کنند. برخلاف تست‌های سنتی، pytest ساختاری ساده ولی در عین حال بسیار انعطاف‌پذیر دارد و برای پروژه‌های کوچک تا بزرگ مناسب است.

چرا از pytest استفاده کنیم؟

کتابخانه pytest امکانات زیادی دارد که آن را از دیگر فریم‌ورک‌های تست متمایز می‌کند:

  • سادگی در نوشتن و خواندن تست‌ها
  • پشتیبانی از fixtures برای آماده‌سازی داده‌ها یا محیط تست
  • قابلیت گسترش با افزونه‌های مختلف (Plugins)
  • گزارش‌دهی دقیق و قابل تنظیم
  • سازگاری با unittest و دیگر فریم‌ورک‌های تست پایتون

نصب کتابخانه pytest

برای نصب pytest کافی است از دستور زیر در ترمینال استفاده کنید:

pip install pytest

پس از نصب، می‌توانید با اجرای دستور زیر، مطمئن شوید که pytest به درستی نصب شده است:

pytest --version

در صورتی که نسخه نمایش داده شود، نصب موفق بوده است.

نوشتن اولین تست با pytest

تست‌ها در pytest معمولاً در فایل‌هایی نوشته می‌شوند که نامشان با test_ شروع می‌شود یا با _test.py ختم می‌شوند. درون این فایل‌ها، توابع تست نیز باید با پیشوند test_ شروع شوند.

# test_example.py
def add(a, b):
    return a + b

def test_add():
    assert add(2, 3) == 5

در این مثال، تابع add مقدار مجموع دو عدد را بازمی‌گرداند و با استفاده از عبارت assert بررسی می‌کنیم که خروجی تابع برابر ۵ باشد. اگر این شرط برقرار نباشد، pytest یک خطا گزارش می‌دهد.

اجرای تست‌ها

برای اجرای تست‌ها، کافی است دستور زیر را در خط فرمان اجرا کنید:

pytest

pytest به صورت خودکار تمام فایل‌هایی را که الگوی test_*.py یا *_test.py دارند پیدا کرده و اجرا می‌کند.

ساختار کلی خروجی pytest

پس از اجرای تست‌ها، خروجی pytest معمولاً شامل اطلاعاتی مانند نام فایل تست، وضعیت تست‌ها (موفق یا ناموفق)، و خلاصه‌ای از تعداد تست‌های اجراشده است.

============================= test session starts =============================
collected 1 item

test_example.py .                                                       [100%]

============================== 1 passed in 0.01s ==============================

علامت . نشان‌دهنده موفقیت تست است. اگر تستی با خطا مواجه شود، pytest جزئیات آن را نمایش می‌دهد.

بررسی خطاها در pytest

اگر تست با شکست مواجه شود، pytest اطلاعات مفصلی در مورد خطا ارائه می‌دهد. مثال زیر را در نظر بگیرید:

# test_fail.py
def multiply(a, b):
    return a * b

def test_multiply():
    assert multiply(2, 3) == 5

نتیجه اجرای این تست به شکل زیر خواهد بود:

============================= test session starts =============================
collected 1 item

test_fail.py F                                                         [100%]

=================================== FAILURES ===================================
_________________________________ test_multiply _______________________________
    def test_multiply():
>       assert multiply(2, 3) == 5
E       assert 6 == 5
E        +  where 6 = multiply(2, 3)

pytest دقیقاً مقدار واقعی (۶) و مقدار مورد انتظار (۵) را نشان می‌دهد. این قابلیت باعث می‌شود عیب‌یابی بسیار سریع‌تر انجام شود.

استفاده از Fixtures در pytest

Fixtures یکی از قدرتمندترین ویژگی‌های pytest هستند. آن‌ها برای آماده‌سازی داده‌ها یا محیط قبل از اجرای تست‌ها استفاده می‌شوند.

import pytest

@pytest.fixture
def sample_data():
    return [1, 2, 3, 4, 5]

def test_sum(sample_data):
    assert sum(sample_data) == 15

در این مثال، fixture با نام sample_data لیستی از اعداد را آماده می‌کند و سپس تابع تست test_sum از آن استفاده می‌کند. pytest به‌صورت خودکار این داده را به تست تزریق می‌کند.

پیکربندی pytest با فایل pytest.ini

برای کنترل تنظیمات و پیکربندی pytest می‌توانید از فایل pytest.ini استفاده کنید. مثلاً:

[pytest]
addopts = -v --maxfail=2
testpaths = tests

این تنظیمات pytest را در حالت verbose اجرا می‌کند و پس از دو شکست تست، اجرا را متوقف می‌نماید. همچنین مسیر پوشه تست‌ها را به tests/ محدود می‌کند.

گروه‌بندی تست‌ها با علامت‌گذاری (Markers)

می‌توان تست‌ها را با استفاده از markers گروه‌بندی کرد تا فقط بخشی از آن‌ها اجرا شود.

import pytest

@pytest.mark.math
def test_addition():
    assert 1 + 1 == 2

@pytest.mark.string
def test_concatenation():
    assert "Py" + "test" == "Pytest"

اکنون می‌توانید فقط تست‌های ریاضی را اجرا کنید:

pytest -m math

تست استثناها با pytest

pytest به راحتی اجازه می‌دهد بررسی کنید که آیا تابعی خطای خاصی را برمی‌گرداند یا خیر.

import pytest

def divide(a, b):
    return a / b

def test_divide_by_zero():
    with pytest.raises(ZeroDivisionError):
        divide(1, 0)

در اینجا از pytest.raises() برای بررسی خطای ZeroDivisionError استفاده شده است. اگر این خطا رخ ندهد، تست شکست می‌خورد.

اجرای موازی تست‌ها با pytest-xdist

با نصب افزونه pytest-xdist می‌توانید تست‌ها را به صورت همزمان روی چند هسته CPU اجرا کنید.

pip install pytest-xdist

سپس:

pytest -n 4

این دستور تست‌ها را روی ۴ پردازنده به طور همزمان اجرا می‌کند و باعث افزایش سرعت تست‌ها می‌شود.

گزارش HTML در pytest

با استفاده از افزونه pytest-html می‌توانید گزارش تست‌ها را در قالب فایل HTML تولید کنید.

pip install pytest-html
pytest --html=report.html

فایل report.html شامل گزارش کامل از تست‌های اجراشده، وضعیت‌ها، و جزئیات هر تست خواهد بود.

مقایسه pytest با unittest

ویژگیpytestunittest
سادگی در نوشتن تست‌هابسیار ساده و بدون کلاسنیاز به تعریف کلاس‌ها و متدها
پشتیبانی از Fixturesبله (پیشرفته)محدود
خروجی گزارشرنگی و قابل فهمخروجی ساده‌تر
قابلیت گسترش با پلاگینبله، بسیار زیادخیلی محدود

نکات و بهترین روش‌ها (Best Practices)

  • هر فایل تست را در پوشه‌ای جداگانه مانند tests/ نگهداری کنید.
  • نام تابع‌های تست را واضح و گویا بنویسید.
  • از Fixtures برای آماده‌سازی داده‌ها استفاده کنید تا کد تکراری کمتر شود.
  • از Markers برای دسته‌بندی تست‌ها بهره ببرید.
  • به‌طور منظم تست‌ها را اجرا کنید تا باگ‌ها زودتر شناسایی شوند.

جمع‌بندی

کتابخانه pytest یک ابزار قدرتمند، مدرن و کاربرپسند برای تست خودکار در پایتون است. با امکاناتی مانند fixtures، markers، گزارش HTML و اجرای موازی، pytest می‌تواند فرآیند توسعه و تضمین کیفیت کد را بسیار بهینه‌تر کند. استفاده از این ابزار در پروژه‌های کوچک و بزرگ توصیه می‌شود تا اطمینان حاصل شود که تغییرات در کد، عملکرد قبلی را مختل نمی‌کند.

آیا این مطلب برای شما مفید بود ؟

خیر
بله
موضوعات شما در انجمن: