یک کلاس برای تست کردن
بیایید یک کلاس ساده برای مدیریت پاسخهای یک نظرسنجی بسازیم. این کلاس به ما اجازه میدهد تا
پاسخهای جدید را ذخیره کنیم.
PYTHON
class AnonymousSurvey:
"""Collect anonymous answers to a survey question."""
def __init__(self, question):
"""Store a question, and prepare to store responses."""
self.question = question
self.responses = []
def show_question(self):
"""Show the survey question."""
print(self.question)
def store_response(self, new_response):
"""Store a single response to the survey."""
self.responses.append(new_response)
این کلاس یک سوال را در سازنده خود دریافت کرده و یک لیست خالی برای ذخیره پاسخها ایجاد میکند.
متد store_response یک پاسخ جدید را به این لیست اضافه میکند.
نوشتن تست برای کلاس
حالا بیایید یک تست برای کلاس AnonymousSurvey بنویسیم تا مطمئن شویم که متد store_response به
درستی کار میکند. ما میخواهیم بررسی کنیم که آیا یک پاسخ پس از فراخوانی این متد، واقعاً در لیست
responses ذخیره میشود یا خیر.
test_survey.py
from survey import AnonymousSurvey
def test_store_single_response():
"""Test that a single response is stored properly."""
question = "What language did you first learn to speak?"
my_survey = AnonymousSurvey(question)
my_survey.store_response('English')
assert 'English' in my_survey.responses
در این تست، ما ابتدا یک نمونه از کلاس AnonymousSurvey میسازیم. سپس یک پاسخ را با
store_response ذخیره میکنیم. در نهایت، با استفاده از assert و عملگر in، بررسی
میکنیم که آیا پاسخ ما در لیست responses نمونه مورد نظر وجود دارد یا خیر.
اجرای pytest در ترمینال نشان میدهد که این تست با موفقیت پاس میشود.
فیکسچرها (Fixtures) در pytest
در مثال بالا، ما برای هر تست یک نمونه جدید از AnonymousSurvey ساختیم. اگر تستهای زیادی داشته
باشیم، این کار منجر به تکرار کد میشود. «فیکسچرها» یا Fixtures در pytest راهی برای
استخراج و به اشتراکگذاری کدهای آمادهسازی تست هستند.
یک فیکسچر، تابعی است که با دکوراتور pytest.fixture@ علامتگذاری شده و معمولاً یک شیء را ساخته
و آن را برمیگرداند. سپس، توابع تست میتوانند نام این فیکسچر را به عنوان یکی از پارامترهای خود
دریافت کرده و از آن شیء آماده استفاده کنند.
test_survey.py
import pytest
from survey import AnonymousSurvey
@pytest.fixture
def language_survey():
"""A survey that will be available to all test functions."""
question = "What language did you first learn to speak?"
language_survey = AnonymousSurvey(question)
return language_survey
def test_store_single_response(language_survey):
"""Test that a single response is stored properly."""
language_survey.store_response('English')
assert 'English' in language_survey.responses
def test_store_three_responses(language_survey):
"""Test that three individual responses are stored properly."""
responses = ['English', 'Spanish', 'Mandarin']
for response in responses:
language_survey.store_response(response)
for response in responses:
assert response in language_survey.responses
در این نسخه بهبودیافته، ما یک فیکسچر به نام language_survey تعریف کردهایم که یک نمونه
آماده از AnonymousSurvey را میسازد.
هر دو تابع تست ما این فیکسچر را به عنوان آرگومان دریافت میکنند. pytest قبل از اجرای هر
تست، فیکسچر را اجرا کرده و مقدار بازگشتی آن را به تابع تست تزریق میکند. این کار نه تنها از
تکرار کد جلوگیری میکند، بلکه باعث میشود تستهای ما تمیزتر و متمرکزتر بر روی منطق اصلی باشند.
در این درس با نحوه نوشتن تستهای مؤثر برای کلاسها با استفاده از pytest آشنا شدیم. دیدیم
که چگونه میتوانیم با ساختن نمونهها و فراخوانی متدها، رفتار یک کلاس را بررسی کنیم و چگونه با
استفاده از فیکسچرها، کدهای تست خود را سازماندهی و تمیز کنیم. با این درس، فصل «آزمایش کدها» به
پایان میرسد. شما اکنون میتوانید با نوشتن تستهای خودکار، از کیفیت و پایداری کدهای پایتون خود
اطمینان حاصل کنید. در فصل بعدی، وارد یک پروژه بزرگ و هیجانانگیز خواهیم شد و «ساخت بازی هجوم
بیگانگان» را آغاز خواهیم کرد.