تست واحد یک تکنیک تست نرم افزار است که در آن اجزا یا واحدهای یک برنامه نرم افزاری مستقل از بقیه برنامه آزمایش می شوند.

در توسعه نرم افزار، تقسیم برنامه خود به واحدهای کوچک و مجزا مفید است. این رویکرد به شما اجازه می‌دهد تا تست‌های مستقلی بنویسید تا تمام بخش‌های برنامه خود را بررسی کنید و اطمینان حاصل کنید که مطابق انتظار رفتار می‌کنند. همچنین، اگر تستی با شکست مواجه شد، می‌توانید به راحتی قسمتی از کد را که دارای اشکال است، بدون دستکاری در بقیه برنامه‌های خود، ایزوله و عیب‌یابی کنید.

پایتون از طریق چارچوب تست unittest پشتیبانی داخلی را برای تست واحد ارائه می دهد. چارچوب‌های تست شخص ثالث دیگری نیز وجود دارد که می‌توانید برای آزمایش واحد خود از آنها استفاده کنید، مانند pytest.

این مقاله تمرکز دارد روی روش استفاده از unittest چارچوبی برای نوشتن تست برای برنامه های پایتون شما و اینکه چرا توسعه دهندگان اغلب آن را ترجیح می دهند.

برای به دست آوردن بهترین نتیجه از این مقاله، باید درک اولیه ای از زبان برنامه نویسی پایتون داشته باشید.

چرا توسعه دهندگان ترجیح می دهند از unittest استفاده کنند؟

در حالی که چارچوب‌های زیادی برای تست واحد در اکوسیستم پایتون وجود دارد، بسیاری از توسعه‌دهندگان هنوز هم نسخه داخلی را ترجیح می‌دهند. unittest به دلیل مزایای قانع کننده آن

اول، unittest ماژول بخشی از کتابخانه استاندارد پایتون است. این امر در دسترس بودن و سازگاری فوری را در محیط های مختلف بدون وابستگی اضافی تضمین می کند. ادغام یکپارچه با محیط های مختلف، استفاده از آن را برای توسعه دهندگان راحت می کند unittest بدون نصب بسته های اضافی

دوم، به عنوان یک چارچوب طولانی مدت در اکوسیستم پایتون، unittest از آشنایی و طول عمر بهره می برد. بسیاری از توسعه دهندگان قبلاً به API و ساختار آن عادت کرده اند و آن را به یک انتخاب قابل اعتماد برای آزمایش تبدیل می کند.

سوم، بیشتر محیط های توسعه یکپارچه (IDE) مانند PyCharm پشتیبانی داخلی را برای unittest. این کار بهره وری توسعه دهندگان را بهبود می بخشد و آزمایش را ساده می کند process، امکان مدیریت و اجرای آزمون را آسان تر می کند.

چهارم، چارچوب دارای اسناد جامع و به خوبی نگهداری شده است. این راهنمایی ها و مثال های دقیقی را ارائه می دهد و به توسعه دهندگان در استفاده موثر کمک می کند 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 کلاس، که از the به ارث می برد TestCase کلاس

در خط پنج کد خود، a را تعریف کردید 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 دایرکتوری در شما terminal و دستور زیر را اجرا کنید:

python -m unittest test_calculator.py

با اجرای دستور قبلی پیغام زیر را در خود خواهید داشت terminal:

.
----------------------------------------------------------------------
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

ممکن است تعجب کنید که چرا باید آن را درج کنید unittest ماژول در دستور شما به جای اجرا python test_calculator.py. این به این دلیل است که شما هنوز نتوانسته اید خود را بسازید test_calculator.py فایل یک اسکریپت مستقل پس دویدن python test_calculator.py هیچ خروجی به شما نمی دهد

پیشنهاد می‌کنیم بخوانید:  شبکه‌های عصبی در جاوا اسکریپت با Brain.js در چند سال اخیر، به‌ویژه، شبکه‌های عصبی (NN) واقعاً به‌عنوان یک روش عملی و کارآمد برای حل مشکلاتی مطرح شده‌اند که نمی‌توانند به راحتی با یک الگوریتم حل شوند، مانند تشخیص چهره، تشخیص صدا، و تشخیص پزشکی این تا حد زیادی به لطف اکتشافات اخیر است روی چگونه بهتر تمرین کنیم...

برای ساختن خودت 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 بازگشت به افزودن (+). حالا تست را با دستور دوباره اجرا کنید python test_calculator.py و خروجی خود را با خروجی قبلی مقایسه کنید.

این یک رویه معمول برای توسعه دهندگان است که ورودی های نامعتبر را با بالا بردن استثناها مدیریت کنند. بنابراین، نوشتن تست هایی که این استثناها را بررسی می کنند، مهم است.

به عنوان مثال، پایتون a را افزایش می دهد 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 توابع در برنامه ماشین حساب شما