سطح مقدماتی (Beginner Level)
تستنویسی یکی از مهمترین مهارتهای برنامهنویسی است. تستها به ما اطمینان میدهند که کد ما دقیقاً همان کاری را انجام میدهد که انتظار داریم و با تغییرات بعدی دچار خطا نمیشود. در پایتون، سادهترین روش تست استفاده از کلمه کلیدی assert و روش استاندارد آن استفاده از ماژول unittest است.
۱. دستور assert
سادهترین راه برای چک کردن صحت یک شرط در پایتون، استفاده از assert است. اگر شرط جلوی این دستور True باشد، هیچ اتفاقی نمیافتد، اما اگر False باشد، برنامه با خطای AssertionError متوقف میشود.
۲. معرفی ماژول unittest
برای پروژههای واقعی، assert کافی نیست. پایتون ماژول استاندارد unittest را دارد که به شما اجازه میدهد تستها را در قالب کلاسها سازماندهی کنید. هر متدی که نامش با test_ شروع شود، به عنوان یک تست اجرا میشود.
# مثال ۳: ساختار یک تست ساده (Static - نیاز به اجرا در ترمینال یا رانر دارد)
import unittest
def multiply(a, b):
return a * b
class TestMathOperations(unittest.TestCase):
def test_multiply_positive(self):
self.assertEqual(multiply(3, 4), 12)
def test_multiply_zero(self):
self.assertEqual(multiply(5, 0), 0)
# معمولاً در انتهای فایل نوشته میشود:
if __name__ == '__main__':
unittest.main()
سطح پیشرفته (Professional Level)
در سطح حرفهای، تستها باید ایزوله باشند و نباید به محیط خارجی (مثل دیتابیس واقعی یا اینترنت) وابسته باشند. همچنین مدیریت چرخه حیات تست (Lifecycle) بسیار مهم است.
۱. چرخه حیات تست (SetUp و TearDown)
متدهای setUp و tearDown قبل و بعد از هر متد تست اجرا میشوند. این برای آمادهسازی شرایط (مثل ساختن یک آبجکت یا فایل موقت) و پاکسازی آن بسیار کاربردی است. همچنین setUpClass و tearDownClass یکبار برای کل کلاس اجرا میشوند.
۲. تست کردن خطاها (AssertRaises)
گاهی باید مطمئن شویم که کد ما در شرایط خاص حتماً خطا میدهد (مثلاً وقتی ورودی اشتباه است). متد assertRaises برای این کار است.
۳. ماک کردن (Mocking)
در پروژههای بزرگ، نباید تستها به سرویسهای واقعی (API بانک، ایمیل سرور) وصل شوند. ما از unittest.mock استفاده میکنیم تا رفتار آنها را شبیهسازی کنیم.
# مثال ۷: استفاده از Mock (Static - مفهوم کلی)
from unittest import TestCase
from unittest.mock import patch
def get_user_data(api_client):
return api_client.fetch_user(1)
class TestAPI(TestCase):
@patch('api_module.ApiClient') # شبیهسازی کلاس ApiClient
def test_get_user(self, MockClient):
# تنظیم رفتار ماک
mock_instance = MockClient.return_value
mock_instance.fetch_user.return_value = {"id": 1, "name": "Ali"}
# اجرای تابع با کلاینت ماک شده
result = get_user_data(mock_instance)
# بررسی نتیجه
self.assertEqual(result['name'], "Ali")
# بررسی اینکه متد fetch_user دقیقاً یک بار صدا زده شده
mock_instance.fetch_user.assert_called_once_with(1)