مقدمه ای بر تست واحد پایتون با واحد تست و پایتون
مقدمه ای بر تست واحد پایتون با واحد تست و پایتون
در این مقاله، به این خواهیم پرداخت که تست نرم افزار چیست و چرا باید به آن اهمیت دهید. نحوه طراحی تست های واحد و نحوه نوشتن تست های واحد پایتون را یاد خواهیم گرفت. به طور خاص، ما به دو مورد از پرکاربردترین چارچوبهای تست واحد در پایتون، unittest
و pytest
نگاه خواهیم کرد. طراحی سایت
مقدمه ای بر تست نرم افزار
آزمایش نرمافزار فرآیند بررسی رفتار یک محصول نرمافزاری برای ارزیابی و تأیید سازگاری آن با مشخصات است. محصولات نرم افزاری می توانند هزاران خط کد و صدها جزء داشته باشند که با هم کار می کنند. اگر یک خط به درستی کار نکند، باگ می تواند منتشر شود و باعث خطاهای دیگری شود. بنابراین، برای اطمینان از اینکه یک برنامه همانطور که باید عمل می کند، باید آزمایش شود.
از آنجایی که نرم افزار مدرن می تواند بسیار پیچیده باشد، چندین سطح آزمایش وجود دارد که جنبه های مختلف صحت را ارزیابی می کند. همانطور که توسط سطح بنیاد آزمون گواهی شده ISTQB بیان شده است برنامه درسی، چهار سطح تست نرم افزار وجود دارد:
- تست واحد، که خطوط خاصی از کد را آزمایش می کند
- تست ادغام، که ادغام بین بسیاری از واحدها را آزمایش می کند
- تست سیستم، که کل سیستم را آزمایش می کند
- آزمایش پذیرش، که مطابقت با اهداف تجاری را بررسی میکند
در این مقاله، ما در مورد تست واحد صحبت خواهیم کرد، اما قبل از اینکه عمیقاً به آن بپردازیم، می خواهم یک اصل مهم در تست نرم افزار را معرفی کنم.
آزمایش وجود نقصها را نشان میدهد، نه عدم وجود آنها.
— ISTQB CTFL برنامه درسی 2018
به عبارت دیگر، حتی اگر همه آزمایشهایی که اجرا میکنید هیچ گونه شکستی را نشان ندهند، این ثابت نمیکند که سیستم نرمافزاری شما بدون اشکال است، یا اینکه یک مورد آزمایشی دیگر نقصی در رفتار دستگاه پیدا نمیکند. نرم افزار شما
تست واحد چیست؟
این اولین سطح آزمایش است که آزمایش مؤلفه نیز نامیده میشود. در این قسمت قطعات تک نرم افزار تست می شوند. بسته به زبان برنامه نویسی، واحد نرم افزار ممکن است یک کلاس، یک تابع یا یک متد باشد. برای مثال، اگر یک کلاس جاوا به نام ArithmeticOperations
دارید که دارای روشهای ضرب
و divide
است، واحد را برای ArithmeticOperations
آزمایش کنید. > کلاس باید رفتار صحیح روشهای ضرب
و divide
را آزمایش کند.
تستهای واحد معمولاً توسط آزمایشکنندگان نرمافزار انجام میشوند. برای اجرای تست های واحد، آزمایش کنندگان نرم افزار (یا توسعه دهندگان) نیاز به دسترسی به کد منبع دارند، زیرا کد منبع خود شی مورد آزمایش است. به همین دلیل، این رویکرد برای تست نرم افزار که به طور مستقیم کد منبع را آزمایش می کند تست جعبه سفید نامیده می شود.
ممکن است از خود بپرسید که چرا باید نگران آزمایش نرم افزار باشید و آیا ارزش آن را دارد یا خیر. در بخش بعدی، انگیزه آزمایش سیستم نرم افزار شما را تحلیل خواهیم کرد.
چرا باید تست واحد انجام دهید
مزیت اصلی تست نرم افزار این است که کیفیت نرم افزار را بهبود می بخشد. کیفیت نرم افزار بسیار مهم است، به ویژه در دنیایی که نرم افزار طیف گسترده ای از فعالیت های روزمره ما را مدیریت می کند. بهبود کیفیت نرم افزار هنوز یک هدف بسیار مبهم است. بیایید سعی کنیم منظورمان از کیفیت نرم افزار را بهتر مشخص کنیم. طبق استاندارد ISO/IEC 9126-1 ISO 9126، کیفیت نرم افزار شامل این عوامل است:
- قابلیت اطمینان
- کارکرد
- کارایی
- قابلیت استفاده
- قابلیت نگهداری
- قابلیت حمل
اگر صاحب یک شرکت هستید، تست نرم افزار فعالیتی است که باید به دقت در نظر بگیرید، زیرا می تواند بر کسب و کار شما تاثیر بگذارد. برای مثال، در ماه مه 2022، تسلا 130000 خودرو را به دلیل مشکل در سیستم اطلاعات سرگرمی خودروها فراخوان کرد. این مشکل سپس با بهروزرسانی نرمافزاری که “از طریق هوا” توزیع شده بود، برطرف شد. این خرابی ها برای شرکت هزینه و زمان می برد و برای مشتریان نیز مشکلاتی ایجاد می کرد زیرا مدتی نمی توانستند از خودروهای خود استفاده کنند. آزمایش نرم افزار واقعاً هزینه دارد، اما این نیز درست است که شرکت ها می توانند میلیون ها نفر در پشتیبانی فنی صرفه جویی کنند.
آزمایش واحد بر بررسی اینکه آیا نرمافزار به درستی عمل میکند یا خیر، تمرکز دارد، به این معنی که بررسی کنید که نقشهبرداری بین ورودیها و خروجیها به درستی انجام شده است. به عنوان یک فعالیت تست سطح پایین، تست واحد به شناسایی اولیه اشکالات کمک می کند تا به سطوح بالاتر سیستم نرم افزاری منتشر نشوند.
از دیگر مزایای تست واحد عبارتند از:
- سادهسازی یکپارچهسازی: با اطمینان از اینکه همه اجزا بهصورت جداگانه به خوبی کار میکنند، حل مشکلات یکپارچهسازی آسانتر میشود.
- به حداقل رساندن رگرسیون کد: با تعداد زیادی از موارد آزمایشی، اگر برخی از تغییرات در کد منبع در آینده باعث ایجاد مشکل شود، پیدا کردن مشکل آسانتر است.
- ارائه اسناد و مدارک: با آزمایش نگاشت صحیح بین ورودی و خروجی، آزمونهای واحد مستنداتی را در مورد نحوه عملکرد متد یا کلاس مورد آزمایش ارائه میکنند.
طراحی یک استراتژی تست
اکنون به نحوه طراحی استراتژی آزمایش نگاه می کنیم.
تعریف محدوده آزمون
قبل از شروع برنامه ریزی یک استراتژی آزمایشی، باید به یک سوال مهم پاسخ دهید. چه بخش هایی از سیستم نرم افزاری خود را می خواهید آزمایش کنید؟
این یک سوال حیاتی است، زیرا آزمایش جامع غیرممکن است. به همین دلیل، نمیتوانید هر ورودی و خروجی ممکن را آزمایش کنید، اما باید آزمایشهای خود را بر اساس ریسکهای موجود در اولویت قرار دهید.
هنگام تعیین محدوده آزمون شما باید عوامل بسیاری را در نظر گرفت:
- ریسک: اگر یک اشکال بر این مؤلفه تأثیر بگذارد، چه پیامدهای تجاری در پی خواهد داشت؟
- زمان: چه مدت می خواهید محصول نرم افزاری شما آماده شود؟ آیا مهلتی دارید؟
- بودجه: چقدر مایلید در فعالیت آزمایشی سرمایه گذاری کنید؟
زمانی که محدوده آزمایش را تعریف کردید، که مشخص میکند چه چیزی را باید آزمایش کنید و چه چیزی را نباید آزمایش کنید، آماده هستید که در مورد ویژگیهایی صحبت کنید که یک آزمون واحد خوب باید داشته باشد.
کیفیت های آزمون واحد
- سریع. تست های واحد عمدتا به صورت خودکار اجرا می شوند، به این معنی که باید سریع باشند. آزمایشهای واحد آهسته به احتمال زیاد توسط توسعهدهندگان نادیده گرفته میشوند زیرا بازخورد فوری ارائه نمیدهند.
- منزوی. تست های واحد بنا به تعریف مستقل هستند. آنها واحد کد جداگانه را آزمایش می کنند و به هیچ چیز خارجی (مانند یک فایل یا یک منبع شبکه) وابسته نیستند.
- قابل تکرار. تست های واحد به طور مکرر اجرا می شوند و نتیجه باید در طول زمان ثابت باشد.
- قابل اعتماد. تستهای واحد تنها در صورتی با شکست مواجه میشوند که در سیستم تحت آزمایش مشکلی وجود داشته باشد. محیط یا ترتیب اجرای آزمایشها نباید مهم باشد.
- به درستی نامگذاری شده. نام آزمون باید اطلاعات مربوط به خود آزمون را ارائه دهد.
یک مرحله آخر قبل از شیرجه زدن در آزمایش واحد در پایتون وجود ندارد. چگونه تست های خود را سازماندهی کنیم تا آنها را تمیز و خوانا کنیم؟ ما از الگویی به نام Arrange, Act and Assert (AAA) استفاده می کنیم.
الگوی AAA
الگوی Arange, Act and Assert یک استراتژی رایج است که برای نوشتن و سازماندهی آزمونهای واحد استفاده میشود. به روش زیر کار می کند:
- در طول مرحله ترتیب، تمام اشیا و متغیرهای مورد نیاز برای آزمایش تنظیم میشوند.
- بعد، در مرحله Act، تابع/روش/کلاس تحت آزمایش فراخوانی میشود.
- در پایان، در مرحله اظهار، نتیجه آزمایش را تأیید میکنیم.
این استراتژی با جداسازی تمام بخشهای اصلی یک آزمون: راهاندازی، اجرا و تأیید، یک رویکرد تمیز برای سازماندهی آزمونهای واحد ارائه میکند. بهعلاوه، خواندن آزمونهای واحد آسانتر است، زیرا همه آنها از یک ساختار پیروی میکنند.
آزمایش واحد در پایتون: unittest یا pytest؟
اکنون در مورد دو چارچوب مختلف تست واحد در پایتون صحبت خواهیم کرد. این دو چارچوب unittest
و pytest
هستند.
مقدمه ای بر واحد تست
کتابخانه استاندارد Python شامل چارچوب تست واحد unittest است. این فریم ورک از JUnit الهام گرفته شده است که یک چارچوب تست واحد در جاوا است.
همانطور که در اسناد رسمی ذکر شده است، unittest
از چند مفهوم مهم پشتیبانی می کند که در این مقاله به آنها اشاره خواهیم کرد:
-
- مورد تست که واحد واحد تست
است
- مجموعه تست، که مجموعه ای از موارد آزمایشی است که با هم اجرا می شوند
- test runner، که مؤلفه ای است که اجرا و نتیجه همه موارد تست را انجام می دهد
unittest
راه خود را برای نوشتن تست دارد. به طور خاص، ما باید:
-
- تستهای ما را بهعنوان متدهای کلاسی بنویسید که
unittest.TestCase
- تستهای ما را بهعنوان متدهای کلاسی بنویسید که
را زیر کلاسها قرار میدهد.
- از روشهای ادعای خاص استفاده کنید
از آنجایی که unittest
قبلاً نصب شده است، ما آماده ایم اولین آزمایش واحد خود را بنویسیم!
نوشتن تست های واحد با استفاده از unittest
فرض کنید کلاس BankAccount
را داریم:
وارد کردن واحد تست
کلاس حساب بانکی:
def __init__(self، id):
self.id = شناسه
self.balance =
def انصراف(self، مقدار):
اگر self.تعادل >= مقدار:
self.تعادل مقدار -=
بازگشت درست
بازگشت نادرست
def سپرده(self، مقدار):
self.تعادل مقدار +=
بازگشت درست
ما نمیتوانیم بیشتر از میزان موجودی سپرده برداشت کنیم، بنابراین بیایید آزمایش کنیم که این سناریو توسط کد منبع ما به درستی مدیریت میشود.
در همان فایل پایتون، میتوانیم کد زیر را اضافه کنیم:
کلاس TestBankOperations(unittest.TestCase):
def deposit_insufficient(self):
یک = حساب بانکی(1)
a.deposit(100)
نتیجه = a.withdraw(200)
self.assertFalse(نتیجه)
ما در حال ایجاد کلاسی به نام TestBankOperations
هستیم که زیر کلاس unittest.TestCase
است. به این ترتیب، یک مورد آزمایشی جدید ایجاد میکنیم.
در داخل این کلاس، یک تابع تست واحد را با متدی تعریف می کنیم که با test
شروع می شود. این مهم است، زیرا هر روش تست باید با کلمه test
شروع شود.
ما انتظار داریم که این روش آزمایشی False
را برگرداند، به این معنی که عملیات شکست خورده است. برای اثبات نتیجه، از یک روش ادعای خاص به نام assertFalse()
استفاده می کنیم.
ما آماده اجرای آزمایش هستیم. بیایید این دستور را در خط فرمان اجرا کنیم:
python -m unittest example.py
در اینجا، example.py
نام فایل حاوی تمام کد منبع است. خروجی باید چیزی شبیه به این باشد:
معرفی سایت: https://downloadpluse.ir/تصاویر-webp-چه-هستند-و-چگونه-در-ساختن-وب-مفی/
------------------------------------------------ --------------------
اجرای 1 آزمون در .001s
خوب
خوب! این بدان معناست که آزمایش ما موفقیت آمیز بوده است. حالا ببینیم خروجی در صورت خرابی چگونه به نظر می رسد. یک تست جدید به کلاس قبلی اضافه می کنیم. بیایید سعی کنیم مبلغ منفی را واریز کنیم که البته امکان پذیر نیست. آیا کد ما این سناریو را مدیریت خواهد کرد؟
این روش تست جدید ما است:
def test_negative_deposit(self):
یک = حساب بانکی(1)
نتیجه = a.deposit(-100)
self.assertFalse(نتیجه)
میتوانیم از حالت پرحرف unittest
برای اجرای این آزمایش با قرار دادن پرچم -v
استفاده کنیم:
python -m unittest -v example.py
و اکنون خروجی متفاوت است:
test_insuficient_deposit (example.TestBankOperations) ... خوب
test_negative_deposit (example.TestBankOperations) ... مردود شدن
============= ======= ============= ======= ================== ============
FAIL: test_negative_deposit (example.TestBankOperations)
------------------------------------------------ --------------------
ردیابی (آخرین تماس اخیر):
فایل "example.py"، خط 35، در سپرده_تست_منفی
self.assertFalse(نتیجه)
AssertionError: True نادرست نیست
------------------------------------------------ --------------------
انجام 2 تست در .002 ثانیه
ناموفق (شکست ها=1)
در این مورد، پرچم پرمخاطب اطلاعات بیشتری به ما می دهد. می دانیم که test_negative_deposit
ناموفق بود. به طور خاص، AssertionError
به ما می گوید که نتیجه مورد انتظار قرار بود نادرست
باشد اما True is not false
، به این معنی که روش نادرست
را برگرداند.درست.
چارچوب unittest
بر اساس نیازهای ما، روشهای ادعایی مختلفی را ارائه میکند:
assertEqual(x,y)
، که تست میکند آیاx == y
assertRaises(exception_type)
، که بررسی میکند آیا استثنای خاصی مطرح شده استassertIsNone(x)
، که آزمایش می کند آیاx هیچکدام است
assertIn(x,y)
، که بررسی میکند آیاx در y
اکنون که درک اولیه ای از نحوه نوشتن تست های واحد با استفاده از چارچوب unittest
داریم، بیایید نگاهی به چارچوب دیگر پایتون به نام pytest
بیاندازیم. .
مقدمه ای بر pytest
چارچوب pytest
یک چارچوب تست واحد پایتون است که دارای چند ویژگی مرتبط است:
- آزمایش پیچیده با استفاده از کد کمتر را امکان پذیر می کند
- از مجموعه های تست
unittest
پشتیبانی می کند - بیش از 800 افزونه خارجی ارائه می دهد
از آنجایی که pytest
به طور پیش فرض نصب نشده است، ابتدا باید آن را نصب کنیم. توجه داشته باشید که pytest
به Python 3.7+ نیاز دارد.
نصب pytest
نصب pytest
بسیار آسان است. فقط باید این دستور را اجرا کنید:
pip نصب -U pytest
سپس با تایپ این زیر بررسی کنید که همه چیز به درستی نصب شده باشد:
pytest --version
خروجی باید چیزی شبیه به این باشد:
pytest 7.1.2
خوب! بیایید اولین آزمایش را با استفاده از pytest
بنویسیم.
نوشتن تست های واحد با استفاده از pytest
از کلاس BankAccount
که قبلاً نوشته شده استفاده میکنیم و همان روشهای قبلی را آزمایش میکنیم. به این ترتیب، مقایسه تلاش مورد نیاز برای نوشتن تستها با استفاده از این دو چارچوب آسانتر است.
برای آزمایش با pytest
باید:
- یک دایرکتوری ایجاد کنید و فایل های آزمایشی خود را داخل آن قرار دهید.
- تست های ما را در فایل هایی بنویسید که نام آنها با
test_
یا با_test.py
ختم می شود.pytest
آن فایلها را در فهرست فعلی و زیرشاخههای آن جستجو میکند.
بنابراین، ما یک فایل به نام test_bank.py
ایجاد می کنیم و آن را در یک پوشه قرار می دهیم. اولین تابع تست ما به این صورت است:
def test_insuficiency_deposit():
یک = حساب بانکی(1)
a.deposit(100)
نتیجه = a.withdraw(200)
اثبات نتیجه == نادرست
همانطور که متوجه شدید، تنها چیزی که در رابطه با نسخه unittest
تغییر کرد، بخش اظهار نظر است. در اینجا ما از روشهای ادعای ساده پایتون استفاده میکنیم.
و اکنون میتوانیم به فایل test_bank.py
نگاهی بیندازیم:
کلاس حساب بانکی:
def __init__(self، id):
self.id = شناسه
self.balance =
def انصراف(self، مقدار):
اگر self.تعادل >= مقدار:
self.تعادل مقدار -=
بازگشت درست
بازگشت نادرست
def سپرده(self، مقدار):
self.تعادل مقدار +=
بازگشت درست
دف آزمون_ناکافی_سپرده():
یک = حساب بانکی(1)
a.deposit(100)
نتیجه = a.withdraw(200)
اثبات نتیجه == نادرست
برای اجرای این آزمایش، اجازه دهید یک خط فرمان را در داخل پوشه ای که فایل test_bank.py
در آن قرار دارد باز کنیم. سپس، این را اجرا کنید:
pytest
خروجی چیزی شبیه به این خواهد بود:
======== جلسه آزمون آزمون شروع می شود ========
پلتفرم win32 -- Python 3.7.11، pytest-7.1.2، pluggy-0.13.1
rootdir: پوشه
پلاگین ها: anyio-2.2.0
1 مورد را جمع آوری کرد
test_bank.py . [100%]
======== 1 در 0.02s ====== ==
در این صورت، میتوانیم ببینیم که نوشتن و اجرای یک تست چقدر آسان است. همچنین، می بینیم که ما کد کمتری در مقایسه با unittest
نوشتیم. نتیجه آزمایش نیز کاملاً قابل درک است.
بیایید برای دیدن یک آزمایش ناموفق حرکت کنیم!
از روش دومی که قبلا نوشتیم استفاده می کنیم که test_negative_deposit
نام دارد. ما بخش اظهار نظر را بازسازی می کنیم و نتیجه این است:
def test_negative_deposit():
یک = حساب بانکی(1)
نتیجه = a.deposit(-100)
اثبات نتیجه == نادرست
ما تست را به همان روش قبلی اجرا می کنیم و این باید خروجی باشد:
======= آزمون جلسه شروع می شود =======
پلتفرم win32 -- Python 3.7.11، pytest-7.1.2، pluggy-0.13.1
rootdir: پوشه
پلاگین ها: anyio-2.2.0
2 مورد را جمع آوری کرد
test_bank.py .F [100%]
======= خطاها ===== ==
_____________ آزمون_سپرده_منفی _____________
def test_negative_deposit():
یک = حساب بانکی(1)
نتیجه = a.deposit(-100)
> بیانگر نتیجه == نادرست
درست == نادرست را ثابت کنید
test_bank.py:32: خطای ادعا
======= کوتاه آزمون اطلاعات خلاصه =======
FAILED test_bank.py::test_negative_deposit - ادعای درست == نادرست
======= 1 ناموفق بود، 1 از گذشت .15s ==== ===
منبع: https://iransite.com