نحوه نوشتن تست های واحد در پایتون – با نمونه کد تست
تست واحد یک تکنیک تست نرم افزار است که در آن اجزا یا واحدهای یک برنامه نرم افزاری مستقل از بقیه برنامه آزمایش می شوند.
در توسعه نرم افزار، تقسیم برنامه خود به واحدهای کوچک و مجزا مفید است. این رویکرد به شما اجازه میدهد تا تستهای مستقلی بنویسید تا تمام بخشهای برنامه خود را تحلیل کنید و اطمینان حاصل کنید که مطابق انتظار رفتار میکنند. همچنین، اگر تستی با شکست مواجه شد، میتوانید به راحتی قسمتی از کد را که دارای اشکال است، بدون دستکاری در بقیه برنامههای خود، ایزوله و عیبیابی کنید.
پایتون از طریق چارچوب تست unittest پشتیبانی داخلی را برای تست واحد ارائه می دهد. چارچوبهای تست شخص ثالث دیگری نیز وجود دارد که میتوانید برای آزمایش واحد خود از آنها استفاده کنید، مانند pytest .
این مقاله بر نحوه استفاده از چارچوب unittest
برای نوشتن تست برای برنامه های کاربردی پایتون و اینکه چرا توسعه دهندگان اغلب آن را ترجیح می دهند، تمرکز دارد.
برای به دست آوردن بهترین نتیجه از این مقاله، باید درک اولیه ای از زبان برنامه نویسی پایتون داشته باشید.
چرا توسعه دهندگان ترجیح می دهند از unittest استفاده کنند؟
در حالی که چارچوبهای زیادی برای تست واحد در اکوسیستم پایتون وجود دارد، بسیاری از توسعهدهندگان به دلیل مزایای قانعکننده آن، همچنان unittest
داخلی را ترجیح میدهند.
ابتدا ماژول unittest
بخشی از کتابخانه استاندارد پایتون است. این امر در دسترس بودن و سازگاری فوری را در محیط های مختلف بدون وابستگی اضافی تضمین می کند. ادغام یکپارچه با محیط های مختلف، استفاده از unittest
را بدون نصب بسته های اضافی برای توسعه دهندگان راحت می کند.
دوم، به عنوان یک چارچوب طولانی مدت در اکوسیستم پایتون، unittest
از آشنایی و طول عمر بهره می برد. بسیاری از توسعه دهندگان قبلاً به API و ساختار آن عادت کرده اند و آن را به یک انتخاب قابل اعتماد برای آزمایش تبدیل می کند.
سوم، اکثر محیطهای توسعه یکپارچه (IDE) مانند PyCharm پشتیبانی داخلی را برای unittest
ارائه میکنند. این کار بهرهوری توسعهدهنده را بهبود میبخشد و فرآیند آزمایش را سادهتر میکند و امکان مدیریت و اجرای آزمون را آسانتر میکند.
چهارم، چارچوب دارای اسناد جامع و به خوبی نگهداری شده است. این راهنمایی و مثالهای دقیقی را ارائه میکند و به توسعهدهندگان کمک میکند تا به طور مؤثر unittest
برای نیازهای آزمایشی خود استفاده کنند.
در نهایت، بسیاری از پروژههای موجود پایتون از unittest
برای آزمایش استفاده میکنند و از سازگاری با پایگاههای کد قدیمی اطمینان میدهند. این پذیرش گسترده به توسعه دهندگان اجازه می دهد تا پروژه های قدیمی تر را بدون نیاز به معرفی و انطباق با یک چارچوب آزمایشی جدید حفظ و گسترش دهند.
نحوه نوشتن تست های واحد با واحد تست
تست واحد با unittest
شامل ایجاد موارد آزمایشی برای تأیید عملکرد واحدهای جداگانه کد شما است. هر مورد آزمایشی با زیر کلاس بندی unittest.TestCase
تعریف می شود. این به شما امکان می دهد چندین روش ارائه شده توسط کلاس TestCase را به ارث ببرید.
برخی از متدهای ارائه شده توسط کلاس TestCase
متدهای ادعایی هستند. این روشهای ادعا به شما امکان میدهند تحلیل کنید که آیا نتیجه واقعی یک تابع یا عملیات با نتیجه مورد انتظار مطابقت دارد یا اینکه آیا شرایط خاصی برآورده شده است. اگر یک ادعا ناموفق باشد، آزمایش به عنوان ناموفق علامت گذاری می شود و شما یک پیام خطا دریافت خواهید کرد.
برای اطلاعات دقیق در مورد روش های مختلف ارائه شده توسط کلاس TestCase
به کلاس ها و توابع مراجعه کنید.
حال، بیایید از دو روش ادعا برای نوشتن تست برای یک برنامه ماشین حساب ساده استفاده کنیم. ابتدا یک پوشه جدید (دایرکتوری) به نام unit-testing
ایجاد کنید. سپس، یک فایل به نام calculator.py
در پوشه unit-testing
خود ایجاد کنید. اکنون کد زیر را در فایل calculator.py
خود کپی کنید:
def add(x, y): """add numbers""" return x + y def subtract(x, y): """subtract numbers""" return x - y def divide(x, y): """divide numbers""" return x / y def multiply(x, y): """multiply numbers""" return x * y
توجه داشته باشید که به جای اینکه برنامه ماشین حساب خود را در یک تابع واحد داشته باشیم، آن را به چهار تابع (واحد) مستقل تقسیم کردیم. این برای اطمینان از اینکه هر قسمت از برنامه به طور مستقل تست شده است. پس اگر هر یک از واحدها در حین تست خطا داد، می توانید به راحتی آن واحد را شناسایی کرده و بدون دستکاری در سایر قسمت های برنامه خود، آن را عیب یابی کنید.
همانطور که قبلا ذکر شد، تست با unittest
شامل ایجاد یک زیر کلاس از کلاس unittest.TestCase
و سپس تعریف متدهای درون کلاس فرعی برای آزمایش واحدهای جداگانه برنامه شما است.
برای نشان دادن این که چگونه کار می کند، بیایید یک آزمایش برای تابع add
در برنامه ماشین حساب خود بنویسیم. در پوشه unit-testing
خود، یک فایل جدید به نام test_calculator.py
ایجاد کنید و سپس کد زیر را در آن کپی کنید:
import unittest import calculator class TestCalculator(unittest.TestCase): def test_add(self): self.assertEqual(calculator.add(1, 2), 3) self.assertEqual(calculator.add(-1, 1), 0) self.assertEqual(calculator.add(-1, -1), -2) self.assertEqual(calculator.add(0, 0), 0)
در خطوط یک و دو کد خود، unittest
و ماژول های calculator
خود را وارد کردید. سپس یک کلاس TestCalculator
ایجاد کردید که از کلاس TestCase
به ارث می برد.
در خط پنج کد خود، یک متد test_add
را در کلاس خود تعریف کردید. این روش نیز مانند هر روش نمونه در پایتون، self
به عنوان اولین آرگومان خود در نظر می گیرد. از آنجایی که self
مرجعی از کلاس TestCalculator
است، می تواند به متد assertEqual
ارائه شده توسط کلاس TestCase
که TestCalculator
از آن به ارث برده است دسترسی داشته باشد.
متد assertEqual
تحلیل می کند که آیا دو مقدار برابر هستند یا خیر. دارای نحو زیر است:
self.assertEqual(first, second, msg=None)
در دستور قبلی، first
مقداری را نشان می دهد که می خواهید در برابر مقدار second
آزمایش کنید. msg
اختیاری است و نشان دهنده یک پیام سفارشی است که در صورت عدم موفقیت آن را دریافت خواهید کرد. اگر مقداری برای msg
ارائه نکنید، یک پیام پیش فرض دریافت خواهید کرد.
حالا بیایید از توضیح نحو برای توضیح استفاده از assertEqual
در متد test_add
خود استفاده کنیم. در اولین ادعای شما، self.assertEqual(add(1, 2), 3)
تحلیل می کند که آیا نتیجه add(1, 2)
برابر با 3 است یا خیر. اگر تابع 3 را برگرداند، تست انجام می شود. در غیر این صورت، از کار می افتد و پیامی مبنی بر عدم تطابق ارائه می دهد. این توضیح در مورد بقیه ادعاهای شما هم همینطور است.
همچنین توجه داشته باشید که فقط مقادیر نماینده را در روش test_add
خود آزمایش کرده اید. این تضمین می کند که تست شما طیف وسیعی از ورودی های ممکن را بدون کد اضافی پوشش می دهد. در اینجا به تفکیک مقادیر نماینده در روش test_add
شما آمده است:
جمع دو عدد مثبت ( self.assertEqual(calculator.add(1, 2), 3)
).
جمع کردن یک عدد منفی و یک عدد مثبت ( self.assertEqual(calculator.add(-1, 1), 0)
).
جمع دو عدد منفی ( self.assertEqual(calculator.add(-1, -1), -2)
).
جمع دو صفر ( self.assertEqual(calculator.add(0, 0), 0)
).
اکنون برای اجرای تست خود، به دایرکتوری unit-testing
در ترمینال خود بروید و دستور زیر را اجرا کنید:
python -m unittest test_calculator.py
با اجرای دستور قبلی پیغام زیر را در ترمینال به شما می دهد:
. ---------------------------------------------------------------------- Ran 1 test in 0.000s OK
خروجی نشان می دهد که شما یک تست را انجام داده اید و موفقیت آمیز بوده است.
برای اطمینان از اینکه تست شما مطابق انتظار کار می کند، به فایل calculator.py
خود برگردید و عملگر جمع ( +
) را در تابع add
به تفریق ( -
) تغییر دهید، مانند این:
def add(x, y): """add numbers""" return x - y
هنگامی که تغییرات را انجام دادید، اجرای مجدد تست شما یک AssertionError
را نشان می دهد که نشان می دهد تست شما شکست خورده است:
Traceback (most recent call last): File ".../test_calculator.py", line 6, in test_add self.assertEqual(calculator.add(1, 2), 3) AssertionError: -1 != 3 ---------------------------------------------------------------------- Ran 1 test in 0.000s
ممکن است تعجب کنید که چرا باید به جای اجرای python test_calculator.py
، ماژول unittest
در دستور خود قرار دهید. دلیلش این است که شما هنوز فایل test_calculator.py
خود را به یک اسکریپت مستقل تبدیل نکرده اید. پس اجرای python test_calculator.py
هیچ خروجی به شما نمی دهد.
برای اینکه test_calculator.py
خود را به عنوان یک اسکریپت مستقل قابل اجرا کنید، باید موارد زیر را به پایین فایل test_calculator.py
خود اضافه کنید:
if __name__ == "__main__": unittest.main()
همچنین، ماژول unittest
مستلزم این است که نام روشهای تست خود را با کلمه test
شروع کنید، در غیر این صورت، آزمون شما مطابق انتظار اجرا نمیشود.
برای امتحان کردن این، نام روش test_add
خود را به add_test
تغییر دهید:
class TestCalculator(unittest.TestCase): def add_test(self): self.assertEqual(calculator.add(1, 2), 3) self.assertEqual(calculator.add(-1, 1), 0) self.assertEqual(calculator.add(-1, -1), -2) self.assertEqual(calculator.add(0, 0), 0)
اکنون، اگر دستور python test_calculator.py
را اجرا کنید، پیامی مشابه این دریافت خواهید کرد:
---------------------------------------------------------------------- Ran 0 tests in 0.000s OK
توجه داشته باشید که خروجی قبلی نشان می دهد که تست های صفر اجرا شده اند. اکنون نام روش خود را به test_add
برگردانید. همچنین، عملگر را در تابع add
calculator.py
خود به add ( +
) تغییر دهید. اکنون تست را با دستور python test_calculator.py
دوباره اجرا کنید و خروجی خود را با خروجی قبلی مقایسه کنید.
این یک رویه معمول برای توسعه دهندگان است که ورودی های نامعتبر را با بالا بردن استثناها مدیریت کنند. پس ، نوشتن تست هایی که این استثناها را تحلیل می کنند، مهم است.
به عنوان مثال، اگر سعی کنید هر عددی را بر صفر تقسیم کنید، پایتون یک ZeroDivisionError
ایجاد می کند. برای آزمایش چنین خطاهایی می توانید از ماژول unittest
استفاده کنید.
اکنون، فایل test_calculator.py
خود را تغییر دهید تا یک روش آزمایشی برای تابع divide
خود داشته باشد:
import unittest import calculator class TestMathOperations(unittest.TestCase): def test_add(self): self.assertEqual(calculator.add(1, 2), 3) self.assertEqual(calculator.add(-1, 1), 0) self.assertEqual(calculator.add(-1, -1), -2) self.assertEqual(calculator.add(0, 0), 0) def test_divide(self): self.assertEqual(calculator.divide(10, 2), 5) self.assertEqual(calculator.divide(9, 3), 3) self.assertEqual(calculator.divide(-6, 2), -3) self.assertEqual(calculator.divide(0, 1), 0) with self.assertRaises(ZeroDivisionError): calculator.divide(10, 0) if __name__ == "__main__": unittest.main()
در کد قبلی، روش test_divide
جدید شما مقادیر نماینده را درست مانند روش test_add
شما آزمایش می کند. اما کد جدیدی در پایان وجود دارد که از assertRaises
استفاده می کند. assertRaises
روش دیگری است که توسط unittest
برای تحلیل اینکه آیا کد شما استثناء ایجاد می کند ارائه شده است. در اینجا، از روشی برای تحلیل ZeroDivisionError
استفاده کردید.
پس ، اگر اکنون تست ها را اجرا کنید، پیامی دریافت خواهید کرد که دو نقطه ( ..
) را نشان می دهد و نشان می دهد که دو تست را با موفقیت انجام داده اید:
.. ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK
نتیجه
این مقاله اصول اولیه تست واحد در پایتون را با استفاده از چارچوب تست unittest
به شما آموزش داده است.
شما اهمیت تست مستقل واحدهای برنامه خود را آموخته اید و دلایل unittest
هنوز یک انتخاب محبوب در میان توسعه دهندگان پایتون است. همچنین، یاد گرفتهاید که چگونه در برنامه ماشینحساب سادهتان، موارد آزمایشی اولیه را برای توابع add
و divide
بنویسید.
با این دانش، اکنون می توانید با اطمینان تست هایی ایجاد کنید که اطمینان حاصل شود کد شما مطابق انتظار عمل می کند و آن را قوی تر و قابل نگهداری تر می کند. من شما را تشویق می کنم که این درس ها را با نوشتن تست برای توابع subtract
و multiply
باقی مانده در برنامه ماشین حساب خود به کار ببرید.
ارسال نظر