unittest --- چارچوب آزمون واحد

کد منبع: Lib/unittest/__init__.py


(اگر از پیش با مفاهیم پایه‌ای آزمون آشنا هستید، شاید بخواهید به فهرست متدهای assert بروید.)

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

برای دستیابی به این هدف، unittest از برخی مفاهیم مهم به‌صورت شیءگرا پشتیبانی می‌کند:

تدارکات آزمون (test fixture)

یک تدارک آزمون <test fixture> نشان‌دهنده‌ی آماده‌سازی لازم برای اجرای یک یا چند آزمون و هرگونه اقدام پاک‌سازی مرتبط است. این ممکن است برای مثال شامل ایجاد پایگاه‌های داده‌ی موقت یا پراکسی، پوشه‌ها، یا راه‌اندازی یک فرایند سرور باشد.

مورد آزمون

یک مورد آزمون <test case> واحد منفرد آزمون است. این مورد، پاسخ مشخصی به یک مجموعه‌ی معین از ورودی‌ها را بررسی می‌کند. unittest کلاس پایه‌ای، TestCase، را فراهم می‌کند که می‌توان از آن برای ایجاد موارد آزمون جدید استفاده کرد.

بدنه آزمون

یک بدنه آزمون <test suite> مجموعه‌ای از موارد آزمون، بدنه‌های آزمون، یا هر دو است. این برای تجمیع آزمون‌هایی که باید با هم اجرا شوند استفاده می‌شود.

اجراکننده آزمون

یک اجراکننده آزمون <test runner> کامپوننتی است که اجرای آزمون‌ها را هماهنگ می‌کند و نتیجه را در اختیار کاربر قرار می‌دهد. این اجراکننده ممکن است از یک رابط گرافیکی، یک رابط متنی استفاده کند یا مقدار خاصی را برای نشان دادن نتایج اجرای آزمون‌ها برگرداند.

همچنین ملاحظه نمائید

ماژول doctest

ماژول پشتیبانی آزمون دیگری با حال‌وهوای بسیار متفاوت.

آزمون ساده Smalltalk: با الگوها <https://web.archive.org/web/20150315073817/http://www.xprogramming.com/testfram.htm>_

مقاله‌ی اصلی کنت بک درباره‌ی چارچوب‌های آزمون که از الگوی مشترک با unittest استفاده می‌کنند.

pytest

چارچوب آزمون واحد شخص ثالث با سینتکس سبک‌تر برای نوشتن آزمون‌ها. برای مثال، assert func(10) == 42.

رده‌بندی ابزارهای آزمون پایتون

فهرست جامعی از ابزارهای آزمون پایتون، شامل چارچوب‌های آزمون عملکردی و کتابخانه‌های اشیای ماک.

فهرست پستی Testing in Python

یک گروه ویژه علاقه‌مندان (special-interest-group) برای بحث درباره‌ی آزمون و ابزارهای آزمون در پایتون.

اسکریپت Tools/unittestgui/unittestgui.py در توزیع کد منبع پایتون، یک ابزار GUI برای کشف و اجرای آزمون است. این ابزار عمدتاً برای سهولت استفاده‌ی تازه‌کاران آزمون واحد در نظر گرفته شده است. برای محیط‌های تولید، توصیه می‌شود که آزمون‌ها توسط یک سیستم یکپارچه‌سازی مداوم مانند Buildbot، Jenkins، GitHub Actions یا AppVeyor اجرا شوند.

مثال ساده

ماژول unittest مجموعه‌ای غنی از ابزارها را برای ساخت و اجرای آزمون‌ها فراهم می‌کند. این بخش نشان می‌دهد که زیرمجموعه‌ای کوچک از ابزارها برای برآوردن نیازهای بیشتر کاربران کافی است.

در اینجا یک اسکریپت کوتاه برای آزمایش سه متد رشته آمده است:

import unittest

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')

    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper())

    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):
            s.split(2)

if __name__ == '__main__':
    unittest.main()

یک مورد آزمون با ایجاد یک زیرکلاس از unittest.TestCase ساخته می‌شود. سه آزمون مجزا با متدهایی تعریف می‌شوند که نام آن‌ها با نویسه‌های test آغاز می‌شود. این قرارداد نام‌گذاری به اجراکننده آزمون اطلاع می‌دهد که کدام متدها نشان‌دهنده آزمون‌ها هستند.

اصل هر آزمون، فراخوانی assertEqual() برای بررسی نتیجه‌ی مورد انتظار؛ فراخوانی assertTrue() یا assertFalse() برای تأیید یک شرط؛ یا فراخوانی assertRaises() برای تأیید پرتاب یک استثنای خاص است. این متدها به‌جای دستور assert استفاده می‌شوند تا اجراکننده‌ی آزمون (test runner) بتواند همه‌ی نتایج آزمون را جمع‌آوری کند و گزارشی تولید کند.

متدهای setUp() و tearDown() به شما امکان می‌دهند دستوراتی را تعریف کنید که پیش و پس از هر متد آزمون اجرا می‌شوند. این موارد با جزئیات بیشتر در بخش سازمان‌دهی کد آزمون پوشش داده شده‌اند.

بلوک نهایی یک راه ساده برای اجرای آزمون‌ها نشان می‌دهد. unittest.main() یک رابط خط فرمان برای اسکریپت آزمون فراهم می‌کند. هنگام اجرا از خط فرمان، اسکریپت بالا خروجی‌ای شبیه به این تولید می‌کند:

...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

دادن گزینه -v به اسکریپت آزمون شما، باعث می‌شود unittest.main() سطح بالاتری از جزئیات را فعال کند و خروجی زیر را تولید کند:

test_isupper (__main__.TestStringMethods.test_isupper) ... ok
test_split (__main__.TestStringMethods.test_split) ... ok
test_upper (__main__.TestStringMethods.test_upper) ... ok

----------------------------------------------------------------------
Ran 3 tests in 0.001s

OK

مثال‌های بالا رایج‌ترین قابلیت‌های unittest را نشان می‌دهند که برای برآورده کردن بسیاری از نیازهای روزمره‌ی آزمون کافی هستند. باقی‌مانده‌ی مستندات مجموعه‌ی کامل قابلیت‌ها را از اصول اولیه بررسی می‌کند.

تغییر یافته در نسخه‌ی 3.11: رفتار برگرداندن مقدار از یک متد آزمون (غیر از مقدار پیش‌فرض None)، اکنون منسوخ شده است.

رابط خط فرمان

می‌توان از ماژول unittest از خط فرمان برای اجرای آزمون‌ها از ماژول‌ها، کلاس‌ها یا حتی متدهای آزمون منفرد استفاده کرد:

python -m unittest test_module1 test_module2
python -m unittest test_module.TestClass
python -m unittest test_module.TestClass.test_method

می‌توانید فهرستی شامل هر ترکیبی از نام ماژول‌ها و نام‌های کامل کلاس یا متد را وارد کنید.

همچنین می‌توان ماژول‌های آزمون را با مسیر پرونده مشخص کرد:

python -m unittest tests/test_something.py

این امکان را به شما می‌دهد که از قابلیت تکمیل نام پرونده پوسته برای مشخص کردن ماژول آزمون استفاده کنید. پرونده مشخص‌شده همچنان باید به‌عنوان یک ماژول قابل ایمپورت باشد. مسیر با حذف '.py' و تبدیل جداکننده‌های مسیر به '.' به نام ماژول تبدیل می‌شود. اگر می‌خواهید یک پرونده آزمون را اجرا کنید که به‌عنوان یک ماژول قابل ایمپورت نیست، باید در عوض پرونده را مستقیماً اجرا کنید.

می‌توانید با افزودن پرچم -v، آزمون‌ها را با جزئیات بیشتر (سطح جزئیات بالاتر) اجرا کنید:

python -m unittest -v test_module

هنگامی که بدون آرگومان اجرا شود، کشف آزمون آغاز می‌شود:

python -m unittest

برای فهرستی از تمام گزینه‌های خط فرمان:

python -m unittest -h

تغییر یافته در نسخه‌ی 3.2: در نسخه‌های پیشین، تنها می‌توانستید متدهای آزمون را به‌صورت جداگانه اجرا کنید، نه ماژول‌ها یا کلاس‌ها را.

اضافه شده در نسخه‌ی 3.14: خروجی به‌طور پیش‌فرض رنگی است و می‌تواند با استفاده از متغیرهای محیطی کنترل شود.

گزینه‌های خط فرمان

unittest از این گزینه‌های خط فرمان پشتیبانی می‌کند:

-b, --buffer

جریان‌های خروجی استاندارد و خطای استاندارد در طول اجرای آزمون، در بافر ذخیره می‌شوند. خروجی در طول یک آزمون موفق دور ریخته می‌شود. خروجی به‌طور عادی در صورت شکست یا خطای آزمون بازتاب داده می‌شود و به پیام‌های شکست اضافه می‌شود.

-c, --catch

Control-C در حین اجرای آزمون منتظر می‌ماند تا آزمون جاری به پایان برسد و سپس همه نتایج تاکنون را گزارش می‌کند. دومین Control-C استثنای معمول KeyboardInterrupt را پرتاب می‌کند.

برای آشنایی با توابعی که این قابلیت را فراهم می‌کنند، به Signal Handling مراجعه کنید.

-f, --failfast

در اولین خطا یا شکست، اجرای آزمون را متوقف کنید.

-k

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

الگوهایی که شامل یک وایلدکارد (*) هستند، با استفاده از fnmatch.fnmatchcase() با نام آزمون تطبیق داده می‌شوند؛ در غیر این صورت، از تطبیق ساده‌ی زیررشته با حساسیت به بزرگی و کوچکی حروف استفاده می‌شود.

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

برای مثال، -k foo با foo_tests.SomeTest.test_something و bar_tests.SomeTest.test_foo مطابقت دارد، اما با bar_tests.FooTest.test_something مطابقت ندارد.

--locals

نمایش متغیرهای محلی در ردگیری‌های پشته.

--durations N

نمایش N مورد از کندترین موارد آزمون (N=0 برای همه).

اضافه شده در نسخه‌ی 3.2: گزینه‌های خط فرمان -b، -c و -f افزوده شدند.

اضافه شده در نسخه‌ی 3.5: گزینه‌ی خط فرمان --locals.

اضافه شده در نسخه‌ی 3.7: گزینه‌ی خط فرمان -k.

اضافه شده در نسخه‌ی 3.12: گزینه‌ی خط فرمان --durations.

همچنین می‌توان از خط فرمان برای کشف آزمون، برای اجرای همه‌ی آزمون‌های یک پروژه یا فقط زیرمجموعه‌ای از آن‌ها استفاده کرد.

کشف آزمون

اضافه شده در نسخه‌ی 3.2.

Unittest از کشف ساده‌ی آزمون پشتیبانی می‌کند. برای سازگاری با کشف آزمون، همه‌ی پرونده‌های آزمون باید ماژول‌ها یا بسته‌هایی باشند که بتوان آن‌ها را از پوشه‌ی سطح بالای پروژه ایمپورت کرد (این بدان معناست که نام پرونده‌های آن‌ها باید شناسه‌های معتبر باشد).

کشف آزمون (test discovery) در TestLoader.discover() پیاده‌سازی شده است، اما می‌توان از آن در خط فرمان نیز استفاده کرد. استفاده‌ی پایه در خط فرمان به این صورت است:

cd project_directory
python -m unittest discover

توجه

به‌عنوان میان‌بر، python -m unittest معادل python -m unittest discover است. اگر می‌خواهید آرگومان‌هایی را به کشف آزمون بدهید، باید به‌صراحت از زیردستور discover استفاده شود.

زیردستور discover گزینه‌های زیر را دارد:

-v, --verbose

خروجی پرجزئیات

-s, --start-directory directory

پوشه برای آغاز کشف (پیش‌فرض .)

-p, --pattern pattern

الگو برای تطبیق پرونده‌های آزمون (پیش‌فرض: test*.py)

-t, --top-level-directory directory

پوشه‌ی سطح بالای پروژه (به‌طور پیش‌فرض پوشه‌ی شروع)

می‌توان گزینه‌های -s، -p و -t را به‌ترتیب به‌عنوان آرگومان‌های جایگاهی ارسال کرد. دو خط فرمان زیر معادل هستند:

python -m unittest discover -s project_directory -p "*_test.py"
python -m unittest discover project_directory "*_test.py"

علاوه بر مسیر، می‌توانید یک نام بسته را نیز به‌عنوان پوشه شروع ارسال کنید؛ برای مثال myproject.subpackage.test. نام بسته‌ای که ارائه می‌دهید سپس ایمپورت می‌شود و محل آن در سامانه فایل‌بندی به‌عنوان پوشه شروع استفاده خواهد شد.

ملاحظه

کشف آزمون، آزمون‌ها را با ایمپورت کردن آن‌ها بارگذاری می‌کند. هنگامی که کشف آزمون همه‌ی پرونده‌های آزمون را از پوشه‌ی شروعی که مشخص می‌کنید پیدا کرد، مسیرها را به نام‌های بسته برای ایمپورت تبدیل می‌کند. برای مثال foo/bar/baz.py به‌صورت foo.bar.baz ایمپورت می‌شود.

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

اگر پوشه شروع را به‌عنوان نام بسته ارائه دهید، نه به‌عنوان مسیر یک پوشه، discover فرض می‌کند هر مکانی که از آن ایمپورت می‌کند همان مکان مورد نظر شماست، بنابراین هشدار را دریافت نخواهید کرد.

ماژول‌ها و بسته‌های آزمون می‌توانند بارگذاری و کشف آزمون‌ها را از طریق load_tests protocol سفارشی‌سازی کنند.

تغییر یافته در نسخه‌ی 3.4: کشف آزمون از بسته‌های فضای نام پشتیبانی می‌کند.

تغییر یافته در نسخه‌ی 3.11: کشف آزمون، پشتیبانی از بسته‌های فضای نام را حذف کرد. این قابلیت از پایتون 3.7 خراب بوده است. پوشه شروع و زیرپوشه‌های آن که حاوی آزمون‌ها هستند، باید بسته‌های معمولی باشند که پرونده __init__.py دارند.

اگر پوشه شروع، نام نقطه‌دار بسته باشد، بسته‌های اجدادی می‌توانند بسته‌های فضای نامی باشند.

تغییر یافته در نسخه‌ی 3.14: کشف آزمون دوباره از بسته فضای نام به‌عنوان پوشه شروع پشتیبانی می‌کند. برای اجتناب از پویش پوشه‌های نامرتبط با پایتون، آزمون‌ها در زیرپوشه‌هایی که حاوی __init__.py نیستند، جستجو نمی‌شوند.

سازمان‌دهی کد آزمون

اجزای سازنده‌ی اساسی آزمون واحد، موارد آزمون <test cases> هستند --- سناریوهای منفردی که باید راه‌اندازی و از نظر صحت بررسی شوند. در unittest، موارد آزمون با نمونه‌های unittest.TestCase نمایش داده می‌شوند. برای ساخت موارد آزمون خودتان، باید زیرکلاس‌هایی از TestCase بنویسید یا از FunctionTestCase استفاده کنید.

کد آزمون یک نمونه TestCase باید کاملاً مستقل باشد، به‌طوری که بتوان آن را به‌تنهایی یا در ترکیب دلخواه با هر تعداد از موردهای آزمون دیگر اجرا کرد.

ساده‌ترین زیرکلاس TestCase صرفاً یک متد آزمون (یعنی متدی که نام آن با test شروع می‌شود) را برای اجرای کد آزمون خاص پیاده‌سازی می‌کند:

import unittest

class DefaultWidgetSizeTestCase(unittest.TestCase):
    def test_default_widget_size(self):
        widget = Widget('The widget')
        self.assertEqual(widget.size(), (50, 50))

توجه داشته باشید که برای آزمایش یک مورد، از یکی از متدهای assert* ارائه‌شده توسط کلاس پایه‌ی TestCase استفاده می‌کنیم. اگر آزمایش شکست بخورد، یک استثنا همراه با پیام توضیحی پرتاب خواهد شد و unittest مورد آزمایشی را به‌عنوان شکست <failure> شناسایی خواهد کرد. سایر استثناها به‌عنوان خطاها <errors> در نظر گرفته خواهند شد.

آزمون‌ها می‌توانند متعدد باشند و راه‌اندازی آن‌ها می‌تواند تکراری باشد. خوشبختانه، می‌توانیم کد راه‌اندازی را با پیاده‌سازی متدی به نام setUp() جدا کنیم، که چارچوب آزمون آن را برای تک‌تک آزمون‌هایی که اجرا می‌کنیم به‌طور خودکار فراخوانی می‌کند:

import unittest

class WidgetTestCase(unittest.TestCase):
    def setUp(self):
        self.widget = Widget('The widget')

    def test_default_widget_size(self):
        self.assertEqual(self.widget.size(), (50,50),
                         'incorrect default size')

    def test_widget_resize(self):
        self.widget.resize(100,150)
        self.assertEqual(self.widget.size(), (100,150),
                         'wrong size after resize')

توجه

ترتیب اجرای آزمون‌های مختلف با مرتب‌سازی نام متدهای آزمون بر اساس ترتیب توکار برای رشته‌ها تعیین می‌شود.

اگر متد setUp() در حین اجرای آزمون استثنایی را پرتاب کند، چارچوب در نظر خواهد گرفت که آزمون دچار خطا شده است و متد آزمون اجرا نخواهد شد.

به‌طور مشابه، می‌توانیم یک متد tearDown() فراهم کنیم که پس از اجرای متد آزمون، پاک‌سازی می‌کند:

import unittest

class WidgetTestCase(unittest.TestCase):
    def setUp(self):
        self.widget = Widget('The widget')

    def tearDown(self):
        self.widget.dispose()

اگر setUp() با موفقیت انجام شده باشد، tearDown() اجرا خواهد شد، چه متد آزمون موفق شده باشد چه نه.

به چنین محیط کاری برای کد آزمون، ثابت آزمایشی آزمون <test fixture> گفته می‌شود. یک نمونه جدید از TestCase به‌عنوان یک ثابت آزمایشی آزمون یکتا برای اجرای هر متد آزمون به‌طور جداگانه ایجاد می‌شود. بنابراین setUp()، tearDown() و TestCase.__init__() یک بار به ازای هر آزمون فراخوانی خواهند شد.

توصیه می‌شود از پیاده‌سازی‌های TestCase برای گروه‌بندی آزمون‌ها بر اساس قابلیت‌هایی که مورد آزمون قرار می‌دهند استفاده کنید. unittest سازوکاری برای این منظور فراهم می‌کند: بدنه‌ی آزمون <test suite>، که توسط کلاس TestSuite از unittest نمایش داده می‌شود. در بیشتر موارد، فراخوانی unittest.main() کار درست را انجام می‌دهد و تمام موارد آزمون ماژول را برای شما جمع‌آوری و اجرا می‌کند.

با این حال، اگر بخواهید ساخت بدنه‌ی آزمون خود را سفارشی‌سازی کنید، می‌توانید خودتان این کار را انجام دهید:

def suite():
    suite = unittest.TestSuite()
    suite.addTest(WidgetTestCase('test_default_widget_size'))
    suite.addTest(WidgetTestCase('test_widget_resize'))
    return suite

if __name__ == '__main__':
    runner = unittest.TextTestRunner()
    runner.run(suite())

می‌توانید تعاریف موارد آزمون و مجموعه‌های آزمون را در همان ماژول‌هایی قرار دهید که کد مورد آزمون در آن‌ها قرار دارد (مانند widget.py)، اما قرار دادن کد آزمون در یک ماژول جداگانه چندین مزیت دارد، مانند test_widget.py:

  • ماژول آزمون را می‌توان به‌صورت مستقل از خط فرمان اجرا کرد.

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

  • وسوسه کمتری وجود دارد که بدون دلیل موجه، کد آزمون را تغییر دهید تا با کد مورد آزمون تطبیق یابد.

  • کد آزمون باید بسیار کمتر از کدی که آن را آزمون می‌کند، تغییر کند.

  • کد آزمون‌شده به‌آسانی بیشتری قابل بازساخت است.

  • به هر حال، آزمون‌های ماژول‌های نوشته‌شده با C باید در ماژول‌های جداگانه باشند، پس چرا یکدست نباشیم؟

  • اگر راهبرد آزمون تغییر کند، نیازی به تغییر کد منبع نیست.

استفاده مجدد از کد آزمون قدیمی

برخی کاربران متوجه خواهند شد که کد آزمون موجودی دارند که می‌خواهند آن را از unittest اجرا کنند، بدون این‌که هر تابع آزمون قدیمی را به یک زیرکلاس TestCase تبدیل کنند.

به همین دلیل، unittest یک کلاس FunctionTestCase را فراهم می‌کند. می‌توان از این زیرکلاسِ TestCase برای دربرگرفتن یک تابع آزمون موجود استفاده کرد. همچنین می‌توان توابع راه‌اندازی و پاک‌سازی را نیز ارائه کرد.

با توجه به تابع آزمون زیر:

def testSomething():
    something = makeSomething()
    assert something.name is not None
    # ...

می‌توانید یک نمونه معادل از مورد آزمون را به صورت زیر ایجاد کنید، با متدهای اختیاری راه‌اندازی و پاک‌سازی:

testcase = unittest.FunctionTestCase(testSomething,
                                     setUp=makeSomethingDB,
                                     tearDown=deleteSomethingDB)

توجه

اگرچه می‌توان از FunctionTestCase برای تبدیل سریع یک پایه‌ی آزمون موجود به سامانه‌ای مبتنی بر unittest استفاده کرد، این روش توصیه نمی‌شود. صرف زمان برای ایجاد زیرکلاس‌های مناسب TestCase، بازآرایی‌های آینده‌ی آزمون‌ها را بی‌نهایت آسان‌تر خواهد کرد.

در برخی موارد، ممکن است آزمون‌های موجود با استفاده از ماژول doctest نوشته شده باشند. در این صورت، doctest کلاس DocTestSuite را فراهم می‌کند که می‌تواند به‌صورت خودکار نمونه‌های unittest.TestSuite را از آزمون‌های موجود مبتنی بر doctest بسازد.

پرش از آزمون‌ها و شکست‌های مورد انتظار

اضافه شده در نسخه‌ی 3.1.

آزمون واحد از پرش از متدهای آزمون جداگانه و حتی کلاس‌های کاملی از آزمون‌ها پشتیبانی می‌کند. علاوه بر این، از علامت‌گذاری یک آزمون به‌عنوان «شکست مورد انتظار» پشتیبانی می‌کند؛ آزمونی که خراب است و شکست خواهد خورد، اما نباید به‌عنوان یک شکست در یک TestResult محسوب شود.

رد کردن یک آزمون به‌سادگی با استفاده از دکوراتور @skip یا یکی از گونه‌های شرطی آن، فراخوانی TestCase.skipTest() در متد setUp() یا متد آزمون، یا پرتاب مستقیم SkipTest انجام می‌شود.

پرش ساده به این شکل است:

class MyTestCase(unittest.TestCase):

    @unittest.skip("demonstrating skipping")
    def test_nothing(self):
        self.fail("shouldn't happen")

    @unittest.skipIf(mylib.__version__ < (1, 3),
                     "not supported in this library version")
    def test_format(self):
        # Tests that work for only a certain version of the library.
        pass

    @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
    def test_windows_support(self):
        # windows specific testing code
        pass

    def test_maybe_skipped(self):
        if not external_resource_available():
            self.skipTest("external resource not available")
        # test code that depends on the external resource
        pass

این خروجی اجرای مثال بالا در حالت پرجزئیات است:

test_format (__main__.MyTestCase.test_format) ... skipped 'not supported in this library version'
test_nothing (__main__.MyTestCase.test_nothing) ... skipped 'demonstrating skipping'
test_maybe_skipped (__main__.MyTestCase.test_maybe_skipped) ... skipped 'external resource not available'
test_windows_support (__main__.MyTestCase.test_windows_support) ... skipped 'requires Windows'

----------------------------------------------------------------------
Ran 4 tests in 0.005s

OK (skipped=4)

می‌توان از کلاس‌ها درست مانند متدها پرش کرد:

@unittest.skip("showing class skipping")
class MySkippedTestCase(unittest.TestCase):
    def test_not_run(self):
        pass

TestCase.setUp() همچنین می‌تواند آزمون را رد کند. این زمانی مفید است که منبعی که باید راه‌اندازی شود، در دسترس نیست.

برای شکست‌های مورد انتظار از دکوراتور @expectedFailure استفاده می‌شود.

class ExpectedFailureTestCase(unittest.TestCase):
    @unittest.expectedFailure
    def test_fail(self):
        self.assertEqual(1, 0, "broken")

با ساختن دکوراتوری که هر زمان بخواهد آزمونی رد شود، skip() را روی آن آزمون فراخوانی می‌کند، می‌توانید به‌آسانی دکوراتورهای سفارشی خودتان را برای رد کردن آزمون بسازید. این دکوراتور، آزمون را رد می‌کند، مگر آنکه شیء داده‌شده دارای ویژگی مشخصی باشد:

def skipUnlessHasattr(obj, attr):
    if hasattr(obj, attr):
        return lambda func: func
    return unittest.skip("{!r} doesn't have {!r}".format(obj, attr))

دکوراتورها و استثنای زیر، پرش از آزمون و شکست‌های مورد انتظار را پیاده‌سازی می‌کنند:

@unittest.skip(reason)

بدون قید و شرط از آزمون دکوریت‌شده پرش می‌کند. reason باید دلیل پرش از آزمون را توضیح دهد.

@unittest.skipIf(condition, reason)

اگر condition درست باشد، از آزمون دکوریت‌شده صرف‌نظر می‌شود.

@unittest.skipUnless(condition, reason)

آزمون دکوریت‌شده را رد می‌کند، مگر اینکه condition درست باشد.

@unittest.expectedFailure

آزمون را به‌عنوان شکست یا خطای مورد انتظار علامت‌گذاری می‌کند. اگر آزمون در خود تابع آزمون با شکست یا خطا مواجه شود (نه در یکی از متدهای test fixture)، موفقیت در نظر گرفته می‌شود. اگر آزمون با موفقیت اجرا شود، شکست در نظر گرفته می‌شود.

exception unittest.SkipTest(reason)

این استثنا برای پرش از یک آزمون پرتاب می‌شود.

معمولاً می‌توانید به‌جای اینکه این را مستقیماً پرتاب کنید، از TestCase.skipTest() یا یکی از دکوراتورهای پرش استفاده کنید.

برای آزمون‌های ردشده، setUp() یا tearDown() پیش و پس از آن‌ها اجرا نخواهد شد. برای کلاس‌های ردشده، setUpClass() یا tearDownClass() اجرا نخواهد شد. برای ماژول‌های ردشده، setUpModule() یا tearDownModule() اجرا نخواهد شد.

تمایز تکرارهای آزمون با استفاده از زیرآزمون‌ها

اضافه شده در نسخه‌ی 3.4.

هنگامی که تفاوت‌های بسیار کوچکی میان آزمون‌های شما وجود دارد، برای مثال برخی پارامترها، unittest به شما امکان می‌دهد آن‌ها را در بدنه‌ی یک متد آزمون با استفاده از مدیر زمینه‌ی subTest() از هم متمایز کنید.

برای مثال، آزمون زیر:

class NumbersTest(unittest.TestCase):

    def test_even(self):
        """
        Test that numbers between 0 and 5 are all even.
        """
        for i in range(0, 6):
            with self.subTest(i=i):
                self.assertEqual(i % 2, 0)

خروجی زیر را تولید خواهد کرد:

FAIL: test_even (__main__.NumbersTest.test_even) (i=1)
Test that numbers between 0 and 5 are all even.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 11, in test_even
    self.assertEqual(i % 2, 0)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 1 != 0

======================================================================
FAIL: test_even (__main__.NumbersTest.test_even) (i=3)
Test that numbers between 0 and 5 are all even.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 11, in test_even
    self.assertEqual(i % 2, 0)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 1 != 0

======================================================================
FAIL: test_even (__main__.NumbersTest.test_even) (i=5)
Test that numbers between 0 and 5 are all even.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 11, in test_even
    self.assertEqual(i % 2, 0)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 1 != 0

بدون استفاده از یک زیرآزمون (subtest)، اجرا پس از اولین شکست متوقف می‌شد و تشخیص خطا دشوارتر بود، زیرا مقدار i نمایش داده نمی‌شد:

FAIL: test_even (__main__.NumbersTest.test_even)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "subtests.py", line 32, in test_even
    self.assertEqual(i % 2, 0)
AssertionError: 1 != 0

کلاس‌ها و توابع

این بخش API مربوط به unittest را به‌طور عمیق شرح می‌دهد.

موارد آزمون

class unittest.TestCase(methodName='runTest')

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

هر نمونه از TestCase یک متد پایه واحد را اجرا می‌کند: متدی که methodName نام دارد. در بیشتر موارد استفاده از TestCase، شما نه methodName را تغییر می‌دهید و نه متد پیش‌فرض runTest() را مجدداً پیاده‌سازی می‌کنید.

تغییر یافته در نسخه‌ی 3.2: TestCase را می‌توان بدون ارائه‌ی methodName با موفقیت نمونه‌سازی کرد. این کار آزمایش با TestCase از مفسر تعاملی را آسان‌تر می‌کند.

نمونه‌های TestCase سه گروه از متدها را ارائه می‌دهند: یک گروه برای اجرای آزمون، گروه دیگر که توسط پیاده‌سازی آزمون برای بررسی شرایط و گزارش شکست‌ها استفاده می‌شود، و چند متد پرس‌وجو که امکان جمع‌آوری اطلاعات درباره خود آزمون را فراهم می‌کنند.

متدهای گروه اول (اجرای آزمون) عبارتند از:

setUp()

متدی که برای آماده‌سازی ثابت آزمایشی فراخوانی می‌شود. این متد بلافاصله پیش از فراخوانی متد آزمون فراخوانی می‌شود؛ به‌جز AssertionError یا SkipTest، هر استثنایی که توسط این متد پرتاب شود، به‌عنوان خطا در نظر گرفته خواهد شد، نه شکست آزمون. پیاده‌سازی پیش‌فرض هیچ کاری انجام نمی‌دهد.

tearDown()

متدی که بلافاصله پس از فراخوانی متد آزمون و ثبت نتیجه فراخوانی می‌شود. این متد حتی اگر متد آزمون استثنایی را پرتاب کرده باشد نیز فراخوانی می‌شود، بنابراین پیاده‌سازی در زیرکلاس‌ها ممکن است نیازمند دقت ویژه‌ای در بررسی وضعیت داخلی باشد. هر استثنایی غیر از AssertionError یا SkipTest که توسط این متد پرتاب شود، به‌عنوان یک خطای اضافی در نظر گرفته می‌شود، نه شکست آزمون (بنابراین تعداد کل خطاهای گزارش‌شده را افزایش می‌دهد). این متد تنها در صورتی فراخوانی می‌شود که setUp() با موفقیت اجرا شود، صرف‌نظر از نتیجه متد آزمون. پیاده‌سازی پیش‌فرض هیچ کاری انجام نمی‌دهد.

setUpClass()

یک متد کلاس که پیش از اجرای آزمون‌های یک کلاس منفرد فراخوانی می‌شود. setUpClass با کلاس به‌عنوان تنها آرگومان فراخوانی می‌شود و باید با دکوراتور @classmethod آراسته شود:

@classmethod
def setUpClass(cls):
    ...

برای جزئیات بیشتر Class and Module Fixtures را ببینید.

اضافه شده در نسخه‌ی 3.2.

tearDownClass()

یک متد کلاس که پس از اجرای آزمون‌ها در یک کلاس منفرد فراخوانی می‌شود. tearDownClass با کلاس به‌عنوان تنها آرگومان فراخوانی می‌شود و باید با دکوراتور @classmethod آراسته شود:

@classmethod
def tearDownClass(cls):
    ...

برای جزئیات بیشتر Class and Module Fixtures را ببینید.

اضافه شده در نسخه‌ی 3.2.

run(result=None)

آزمون را اجرا می‌کند و نتیجه را در شیء TestResult که به‌عنوان result ارسال‌شده است، جمع‌آوری می‌کند. اگر result حذف‌شده باشد یا None باشد، یک شیء نتیجه‌ی موقت ایجاد می‌شود (با فراخوانی متد defaultTestResult()) و مورد استفاده قرار می‌گیرد. شیء نتیجه به فراخواننده‌ی run() برگردانده می‌شود.

می‌توان همان اثر را به‌سادگی با فراخوانی نمونه‌ی TestCase به دست آورد.

تغییر یافته در نسخه‌ی 3.3: نسخه‌های پیشین run نتیجه را برنمی‌گرداندند. فراخوانی یک نمونه نیز همین‌طور بود.

skipTest(reason)

فراخوانی این در حین اجرای یک متد آزمون یا setUp()، آزمون فعلی را رد می‌کند. برای اطلاعات بیشتر پرش از آزمون‌ها و شکست‌های مورد انتظار را ببینید.

اضافه شده در نسخه‌ی 3.1.

subTest(msg=None, **params)

یک مدیر زمینه برمی‌گرداند که بلوک کد محصورشده را به‌عنوان یک زیرآزمون (subtest) اجرا می‌کند. msg و params مقادیر اختیاری و دلخواهی هستند که هر زمان یک زیرآزمون شکست بخورد، نمایش داده می‌شوند تا بتوانید آن‌ها را به‌وضوح شناسایی کنید.

یک مورد آزمون (test case) می‌تواند شامل هر تعداد اعلامیه‌ی زیرآزمون (subtest) باشد و این اعلامیه‌ها می‌توانند به‌صورت دلخواه تودرتو شوند.

برای اطلاعات بیشتر تمایز تکرارهای آزمون با استفاده از زیرآزمون‌ها را ببینید.

اضافه شده در نسخه‌ی 3.4.

debug()

آزمون را بدون جمع‌آوری نتیجه اجرا کنید. این کار اجازه می‌دهد استثناهای پرتاب‌شده توسط آزمون به فراخواننده منتشر شوند و می‌تواند برای پشتیبانی از اجرای آزمون‌ها تحت اشکال‌زدا استفاده شود.

کلاس TestCase چندین متد assert برای بررسی و گزارش شکست‌ها فراهم می‌کند. جدول زیر رایج‌ترین متدها را فهرست می‌کند (برای متدهای assert بیشتر، جدول‌های زیر را ببینید):

متد

بررسی می‌کند که

جدید در

assertEqual(a, b)

a == b

assertNotEqual(a, b)

a != b

assertTrue(x)

bool(x) is True

assertFalse(x)

bool(x) is False

assertIs(a, b)

a is b

3.1

assertIsNot(a, b)

a is not b

3.1

assertIsNone(x)

x is None

3.1

assertIsNotNone(x)

x is not None

3.1

assertIn(a, b)

a in b

3.1

assertNotIn(a, b)

a not in b

3.1

assertIsInstance(a, b)

isinstance(a, b)

3.2

assertNotIsInstance(a, b)

not isinstance(a, b)

3.2

assertIsSubclass(a, b)

issubclass(a, b)

3.14

assertNotIsSubclass(a, b)

not issubclass(a, b)

3.14

همه‌ی متدهای assert یک آرگومان msg می‌پذیرند که در صورت تعیین شدن، به‌عنوان پیام خطا هنگام شکست استفاده می‌شود (همچنین longMessage را ببینید). توجه داشته باشید که آرگومان کلیدواژه‌ای msg فقط زمانی می‌تواند به assertRaises()، assertRaisesRegex()، assertWarns() و assertWarnsRegex() ارسال شود که این متدها به‌عنوان مدیر زمینه استفاده شوند.

assertEqual(first, second, msg=None)

آزمون می‌کند که first و second برابر باشند. اگر مقادیر در مقایسه برابر نباشند، آزمون شکست می‌خورد.

علاوه بر این، اگر first و second دقیقاً نوع یکسانی باشند و آن نوع یکی از list، tuple، dict، set، frozenset یا str یا هر نوعی باشد که یک زیرکلاس آن را با addTypeEqualityFunc() ثبت کند، تابع برابری مختص نوع فراخوانی می‌شود تا پیام خطای پیش‌فرض مفیدتری تولید کند (همچنین فهرست متدهای مختص نوع را ببینید).

تغییر یافته در نسخه‌ی 3.1: فراخوانی خودکار تابع برابری مختص نوع افزوده شد.

تغییر یافته در نسخه‌ی 3.2: assertMultiLineEqual() به‌عنوان تابع برابری نوع پیش‌فرض برای مقایسه‌ی رشته‌ها افزوده شد.

assertNotEqual(first, second, msg=None)

آزمایش می‌کند که first و second برابر نیستند. اگر مقدارها برابر باشند، آزمون شکست خواهد خورد.

assertTrue(expr, msg=None)
assertFalse(expr, msg=None)

آزمایش می‌کند که expr درست (یا نادرست) باشد.

توجه داشته باشید که این معادل bool(expr) is True است و نه معادل expr is True (برای دومی از assertIs(expr, True) استفاده کنید). همچنین هنگامی که متدهای خاص‌تری در دسترس هستند، باید از این متد اجتناب شود (مثلاً assertEqual(a, b) به‌جای assertTrue(a == b))، زیرا آن‌ها در صورت شکست، پیام خطای بهتری ارائه می‌دهند.

assertIs(first, second, msg=None)
assertIsNot(first, second, msg=None)

آزمایش می‌کند که first و second همان شیء هستند (یا نیستند).

اضافه شده در نسخه‌ی 3.1.

assertIsNone(expr, msg=None)
assertIsNotNone(expr, msg=None)

آزمایش می‌کند که expr None است (یا نیست).

اضافه شده در نسخه‌ی 3.1.

assertIn(member, container, msg=None)
assertNotIn(member, container, msg=None)

آزمایش می‌کند که member در container وجود دارد (یا ندارد).

اضافه شده در نسخه‌ی 3.1.

assertIsInstance(obj, cls, msg=None)
assertNotIsInstance(obj, cls, msg=None)

آزمون کنید که obj نمونه‌ای از cls (که می‌تواند یک کلاس یا تاپلی از کلاس‌ها باشد، همان‌گونه که isinstance() پشتیبانی می‌کند) است (یا نیست). برای بررسی نوع دقیق، از assertIs(type(obj), cls) استفاده کنید.

اضافه شده در نسخه‌ی 3.2.

assertIsSubclass(cls, superclass, msg=None)
assertNotIsSubclass(cls, superclass, msg=None)

بررسی می‌کند که cls زیرکلاس superclass (که می‌تواند یک کلاس یا تاپلی از کلاس‌ها باشد، همان‌طور که issubclass() پشتیبانی می‌کند) باشد (یا نباشد). برای بررسی نوع دقیق، از assertIs(cls, superclass) استفاده کنید.

اضافه شده در نسخه‌ی 3.14.

همچنین می‌توان تولید استثناها، هشدارها و پیام‌های گزارش را با استفاده از متدهای زیر بررسی کرد:

متد

بررسی می‌کند که

جدید در

assertRaises(exc, fun, *args, **kwds)

fun(*args, **kwds) باعث پرتاب exc می‌شود

assertRaisesRegex(exc, r, fun, *args, **kwds)

fun(*args, **kwds) استثنای exc را پرتاب می‌کند و پیام آن با عبارت باقاعده‌ی r مطابقت دارد

3.1

assertWarns(warn, fun, *args, **kwds)

fun(*args, **kwds) باعث پرتاب warn می‌شود

3.2

assertWarnsRegex(warn, r, fun, *args, **kwds)

fun(*args, **kwds) موجب پرتاب warn می‌شود و پیام با عبارت باقاعده r مطابقت دارد

3.2

assertLogs(logger, level)

بلوک with روی logger با حداقل level گزارش می‌کند

3.4

assertNoLogs(logger, level)

بلوک with هیچ پیام گزارشی ثبت نمی‌کند.

logger با حداقل level

3.10

assertRaises(exception, callable, *args, **kwds)
assertRaises(exception, *, msg=None)

آزمون کنید که وقتی callable با هر آرگومان جایگاهی یا کلیدواژه‌ای که به assertRaises() نیز ارسال می‌شود فراخوانی می‌شود، یک استثنا پرتاب می‌شود. اگر exception پرتاب شود، آزمون موفق می‌شود؛ اگر استثنای دیگری پرتاب شود، خطا محسوب می‌شود؛ و اگر هیچ استثنایی پرتاب نشود، شکست می‌خورد. برای گرفتن هر یک از استثناهای یک گروه، می‌توان یک تاپلشامل کلاس‌های استثنا را به‌عنوان exception ارسال کرد.

اگر تنها آرگومان exception و احتمالاً آرگومان msg داده شده باشند، یک مدیر زمینه برمی‌گرداند تا کد تحت آزمون بتواند به‌صورت درون‌خطی نوشته شود، نه به‌صورت یک تابع:

with self.assertRaises(SomeException):
    do_something()

هنگام استفاده به‌عنوان مدیر زمینه، assertRaises() آرگومان کلیدواژه‌ای اضافی msg را می‌پذیرد.

مدیر زمینه، شیء استثنای گرفته‌شده را در ویژگی exception خود ذخیره می‌کند. این موضوع می‌تواند مفید باشد اگر هدف، انجام بررسی‌های بیشتر روی استثنای پرتاب‌شده باشد:

with self.assertRaises(SomeException) as cm:
    do_something()

the_exception = cm.exception
self.assertEqual(the_exception.error_code, 3)

تغییر یافته در نسخه‌ی 3.1: توانایی استفاده از assertRaises() به‌عنوان مدیر زمینه افزوده شد.

تغییر یافته در نسخه‌ی 3.2: ویژگی exception اضافه شد.

تغییر یافته در نسخه‌ی 3.3: هنگام استفاده به‌عنوان مدیر زمینه، آرگومان کلیدواژه‌ای msg اضافه شد.

assertRaisesRegex(exception, regex, callable, *args, **kwds)
assertRaisesRegex(exception, regex, *, msg=None)

مانند assertRaises() است، اما همچنین بررسی می‌کند که regex با نمایش رشته‌ای استثنای پرتاب‌شده مطابقت داشته باشد. regex می‌تواند یک شیء عبارت باقاعده یا رشته‌ای حاوی عبارت باقاعده‌ای مناسب برای استفاده در re.search() باشد. مثال‌ها:

self.assertRaisesRegex(ValueError, "invalid literal for.*XYZ'$",
                       int, 'XYZ')

یا:

with self.assertRaisesRegex(ValueError, 'literal'):
   int('XYZ')

اضافه شده در نسخه‌ی 3.1: با نام assertRaisesRegexp اضافه شد.

تغییر یافته در نسخه‌ی 3.2: به assertRaisesRegex() تغییر نام یافت.

تغییر یافته در نسخه‌ی 3.3: هنگام استفاده به‌عنوان مدیر زمینه، آرگومان کلیدواژه‌ای msg اضافه شد.

assertWarns(warning, callable, *args, **kwds)
assertWarns(warning, *, msg=None)

آزمون می‌کند که هنگام فراخوانی callable با هر آرگومان جایگاهی یا کلیدواژه‌ای که به assertWarns() نیز داده می‌شود، هشداری فعال می‌شود. این آزمون در صورتی موفق می‌شود که warning فعال شود و اگر فعال نشود ناموفق می‌شود. هر استثنا یک خطا محسوب می‌شود. برای گرفتن هر یک از هشدارهای یک گروه، می‌توان یک تاپل شامل کلاس‌های هشدار را به‌عنوان warnings ارسال کرد.

اگر تنها آرگومان‌های warning و احتمالاً msg داده شده باشند، یک مدیر زمینه برمی‌گرداند تا کد تحت آزمون بتواند به‌صورت درون‌خطی نوشته شود، نه به‌صورت یک تابع:

with self.assertWarns(SomeWarning):
    do_something()

هنگامی که به‌عنوان مدیر زمینه استفاده شود، assertWarns() آرگومان کلیدواژه‌ای اضافی msg را می‌پذیرد.

مدیر زمینه، شیء هشدار گرفته‌شده را در ویژگی warning خود و خط منبعی را که هشدارها را ایجاد کرده است در ویژگی‌های filename و lineno ذخیره می‌کند. این می‌تواند در صورتی مفید باشد که هدف، انجام بررسی‌های بیشتر روی هشدار گرفته‌شده باشد:

with self.assertWarns(SomeWarning) as cm:
    do_something()

self.assertIn('myfile.py', cm.filename)
self.assertEqual(320, cm.lineno)

این متد صرف‌نظر از فیلترهای هشدارِ برقرار در زمان فراخوانی، عمل می‌کند.

اضافه شده در نسخه‌ی 3.2.

تغییر یافته در نسخه‌ی 3.3: هنگام استفاده به‌عنوان مدیر زمینه، آرگومان کلیدواژه‌ای msg اضافه شد.

assertWarnsRegex(warning, regex, callable, *args, **kwds)
assertWarnsRegex(warning, regex, *, msg=None)

مانند assertWarns() است، اما همچنین آزمایش می‌کند که regex با پیام هشدار فعال‌شده مطابقت دارد. regex می‌تواند یک شیء عبارت باقاعده یا رشته‌ای حاوی عبارت باقاعده مناسب برای استفاده توسط re.search() باشد. مثال:

self.assertWarnsRegex(DeprecationWarning,
                      r'legacy_function\(\) is deprecated',
                      legacy_function, 'XYZ')

یا:

with self.assertWarnsRegex(RuntimeWarning, 'unsafe frobnicating'):
    frobnicate('/etc/passwd')

اضافه شده در نسخه‌ی 3.2.

تغییر یافته در نسخه‌ی 3.3: هنگام استفاده به‌عنوان مدیر زمینه، آرگومان کلیدواژه‌ای msg اضافه شد.

assertLogs(logger=None, level=None)

یک مدیر زمینه برای آزمایش اینکه حداقل یک پیام با حداقل level داده‌شده، روی logger یا یکی از فرزندان آن ثبت شده باشد.

در صورت ارائه، logger باید یک شیء logging.Logger یا یک str باشد که نام یک گزارش‌گیر را مشخص می‌کند. مقدار پیش‌فرض، گزارش‌گیر ریشه است که تمام پیام‌هایی را که توسط یک گزارش‌گیر فرزند بدون انتشار مسدود نشده‌اند، دریافت خواهد کرد.

در صورت ارائه، level باید یا یک سطح گزارش‌گیری عددی باشد یا معادل رشته‌ای آن (برای مثال یا "ERROR" یا logging.ERROR). مقدار پیش‌فرض logging.INFO است.

اگر حداقل یک پیام منتشرشده درون بلوک with با شرایط logger و level مطابقت داشته باشد، آزمون موفق می‌شود، در غیر این صورت شکست می‌خورد.

شیء برگردانده‌شده از سوی مدیر زمینه، یک شیء کمکی برای ضبط است که پیام‌های گزارش منطبق را پیگیری می‌کند. این شیء دو ویژگی دارد:

records

فهرستی از اشیاء logging.LogRecord مربوط به پیام‌های گزارش منطبق.

output

فهرستی از اشیای str با خروجی قالب‌بندی‌شده‌ی پیام‌های منطبق.

مثال:

with self.assertLogs('foo', level='INFO') as cm:
    logging.getLogger('foo').info('first message')
    logging.getLogger('foo.bar').error('second message')
self.assertEqual(cm.output, ['INFO:foo:first message',
                             'ERROR:foo.bar:second message'])

اضافه شده در نسخه‌ی 3.4.

assertNoLogs(logger=None, level=None)

یک مدیر زمینه برای آزمایش اینکه هیچ پیامی با دست‌کم level داده‌شده، روی logger یا یکی از فرزندان آن ثبت نمی‌شود.

در صورت ارائه، logger باید یک شیء logging.Logger یا یک str باشد که نام یک گزارش‌گیر را مشخص می‌کند. پیش‌فرض، گزارش‌گیر ریشه است که تمام پیام‌ها را دریافت می‌کند.

در صورت ارائه، level باید یا یک سطح گزارش‌گیری عددی باشد یا معادل رشته‌ای آن (برای مثال یا "ERROR" یا logging.ERROR). مقدار پیش‌فرض logging.INFO است.

برخلاف assertLogs()، هیچ چیزی توسط مدیر زمینه برگردانده نخواهد شد.

اضافه شده در نسخه‌ی 3.10.

همچنین متدهای دیگری نیز برای انجام بررسی‌های خاص‌تر وجود دارند، مانند:

متد

بررسی می‌کند که

جدید در

assertAlmostEqual(a, b)

round(a-b, 7) == 0

assertNotAlmostEqual(a, b)

round(a-b, 7) != 0

assertGreater(a, b)

a > b

3.1

assertGreaterEqual(a, b)

a >= b

3.1

assertLess(a, b)

a < b

3.1

assertLessEqual(a, b)

a <= b

3.1

assertRegex(s, r)

r.search(s)

3.1

assertNotRegex(s, r)

not r.search(s)

3.2

assertCountEqual(a, b)

a شامل همان عناصر b است، صرف‌نظر از ترتیب آن‌ها.

3.2

assertStartsWith(a, b)

a.startswith(b)

3.14

assertNotStartsWith(a, b)

not a.startswith(b)

3.14

assertEndsWith(a, b)

a.endswith(b)

3.14

assertNotEndsWith(a, b)

not a.endswith(b)

3.14

assertHasAttr(a, b)

hasattr(a, b)

3.14

assertNotHasAttr(a, b)

not hasattr(a, b)

3.14

assertAlmostEqual(first, second, places=7, msg=None, delta=None)
assertNotAlmostEqual(first, second, places=7, msg=None, delta=None)

با محاسبه‌ی اختلاف، گرد کردن به تعداد places اعشار داده‌شده (پیش‌فرض ۷)، و مقایسه با صفر، آزمایش می‌کند که first و second تقریباً برابر هستند (یا تقریباً برابر نیستند). توجه داشته باشید که این متدها مقادیر را به تعداد ارقام اعشار داده‌شده گرد می‌کنند (یعنی مانند تابع round()) و نه به تعداد ارقام بامعنی.

اگر delta به‌جای places ارائه شود، اختلاف بین first و second باید کمتر یا مساوی (یا بزرگ‌تر از) delta باشد.

ارائه هر دو delta و places باعث پرتاب TypeError می‌شود.

تغییر یافته در نسخه‌ی 3.2: assertAlmostEqual() به‌طور خودکار اشیایی را که در مقایسه برابرند، تقریباً برابر در نظر می‌گیرد. assertNotAlmostEqual() به‌طور خودکار اگر اشیاء در مقایسه برابر باشند، شکست می‌خورد. آرگومان کلیدواژه‌ای delta افزوده شد.

assertGreater(first, second, msg=None)
assertGreaterEqual(first, second, msg=None)
assertLess(first, second, msg=None)
assertLessEqual(first, second, msg=None)

آزمایش می‌کند که first بسته به نام متد، به‌ترتیب >، >=، < یا <= از second باشد. در غیر این صورت، آزمون شکست می‌خورد:

>>> self.assertGreaterEqual(3, 4)
AssertionError: "3" unexpectedly not greater than or equal to "4"

اضافه شده در نسخه‌ی 3.1.

assertRegex(text, regex, msg=None)
assertNotRegex(text, regex, msg=None)

آزمایش می‌کند که یک جست‌وجوی regex با text مطابقت داشته باشد (یا مطابقت نداشته باشد). در صورت شکست، پیام خطا شامل الگو و text (یا الگو و بخشی از text که به‌طور غیرمنتظره‌ای مطابقت داشت) خواهد بود. regex می‌تواند یک شیء عبارت باقاعده یا رشته‌ای حاوی یک عبارت باقاعده مناسب برای استفاده توسط re.search() باشد.

اضافه شده در نسخه‌ی 3.1: با نام assertRegexpMatches افزوده شد.

تغییر یافته در نسخه‌ی 3.2: متد assertRegexpMatches() به assertRegex() تغییر نام یافته است.

اضافه شده در نسخه‌ی 3.2: assertNotRegex().

assertCountEqual(first, second, msg=None)

آزمون می‌کند که دنباله‌ی first شامل همان عناصر second است، صرف‌نظر از ترتیب آن‌ها. در غیر این صورت، پیام خطایی که تفاوت‌های بین دنباله‌ها را فهرست می‌کند، تولید می‌شود.

عناصر تکراری هنگام مقایسه first و second نادیده گرفته نمی‌شوند. این متد بررسی می‌کند که هر عنصر در هر دو دنباله تعداد یکسانی داشته باشد. معادل است با: assertEqual(Counter(list(first)), Counter(list(second))) اما با دنباله‌هایی از اشیاء هش‌ناپذیر (unhashable) نیز کار می‌کند.

اضافه شده در نسخه‌ی 3.2.

assertStartsWith(s, prefix, msg=None)
assertNotStartsWith(s, prefix, msg=None)

آزمایش می‌کند که رشته‌ی یونیکدی یا بایتی s با یک prefix آغاز می‌شود (یا نمی‌شود). prefix همچنین می‌تواند تاپلی از رشته‌ها برای آزمایش باشد.

اضافه شده در نسخه‌ی 3.14.

assertEndsWith(s, suffix, msg=None)
assertNotEndsWith(s, suffix, msg=None)

آزمایش می‌کند که رشته‌ی یونیکدی یا بایتی s به یک suffix ختم می‌شود (یا ختم نمی‌شود). suffix همچنین می‌تواند تاپلی از رشته‌ها برای آزمایش باشد.

اضافه شده در نسخه‌ی 3.14.

assertHasAttr(obj, name, msg=None)
assertNotHasAttr(obj, name, msg=None)

آزمایش می‌کند که شیء obj ویژگی name را دارد (یا ندارد).

اضافه شده در نسخه‌ی 3.14.

متد assertEqual() بررسی برابری برای اشیء هم‌نوع را به متدهای مختلف مختص نوع ارجاع می‌دهد. این متدها از قبل برای بیشتر انواع توکار پیاده‌سازی شده‌اند، اما همچنین امکان ثبت متدهای جدید با استفاده از addTypeEqualityFunc() وجود دارد:

addTypeEqualityFunc(typeobj, function)

یک متد مختص به نوع را ثبت می‌کند که توسط assertEqual() فراخوانی می‌شود تا بررسی کند که آیا دو شیء از دقیقاً همان typeobj (نه زیرکلاس‌ها) با هم برابر هستند یا خیر. function باید دو آرگومان جایگاهی و یک آرگومان کلیدواژه‌ای سوم به شکل msg=None را بپذیرد، دقیقاً همان‌طور که assertEqual() می‌پذیرد. این تابع باید هنگامی که نابرابری بین دو پارامتر نخست تشخیص داده شود، self.failureException(msg) را پرتاب کند — و در صورت امکان اطلاعات مفیدی ارائه دهد و نابرابری‌ها را با جزئیات در پیام خطا توضیح دهد.

اضافه شده در نسخه‌ی 3.1.

فهرست متدهای مختص به نوعی که به‌طور خودکار توسط assertEqual() استفاده می‌شوند، در جدول زیر خلاصه شده است. توجه داشته باشید که معمولاً نیازی به فراخوانی مستقیم این متدها نیست.

متد

برای مقایسه استفاده می‌شود

جدید در

assertMultiLineEqual(a, b)

رشته‌ها

3.1

assertSequenceEqual(a, b)

دنباله‌ها

3.1

assertListEqual(a, b)

فهرست‌ها

3.1

assertTupleEqual(a, b)

تاپل‌ها

3.1

assertSetEqual(a, b)

مجموعه‌ها یا مجموعه‌های فریزشده

3.1

assertDictEqual(a, b)

دیکشنری‌ها

3.1

assertMultiLineEqual(first, second, msg=None)

آزمایش می‌کند که رشته چندخطی first با رشته second برابر باشد. در صورت نابرابر بودن، تفاوت (diff) دو رشته که تفاوت‌ها را برجسته می‌کند، در پیام خطا گنجانده خواهد شد. این متد به‌طور پیش‌فرض هنگام مقایسه رشته‌ها با assertEqual() استفاده می‌شود.

اضافه شده در نسخه‌ی 3.1.

assertSequenceEqual(first, second, msg=None, seq_type=None)

بررسی می‌کند که دو دنباله برابر باشند. اگر seq_type ارائه شود، هر دو first و second باید نمونه‌هایی از seq_type باشند، در غیر این صورت یک شکست پرتاب خواهد شد. اگر دنباله‌ها متفاوت باشند، پیام خطایی ساخته می‌شود که تفاوت میان آن دو را نشان می‌دهد.

این متد به‌طور مستقیم توسط assertEqual() فراخوانی نمی‌شود، اما برای پیاده‌سازی assertListEqual() و assertTupleEqual() از آن استفاده می‌شود.

اضافه شده در نسخه‌ی 3.1.

assertListEqual(first, second, msg=None)
assertTupleEqual(first, second, msg=None)

بررسی می‌کند که دو فهرست یا تاپل با هم برابر باشند. در غیر این صورت، پیام خطایی ساخته می‌شود که تنها تفاوت‌های میان آن دو را نشان می‌دهد. همچنین اگر نوع هر یک از پارامترها نادرست باشد، خطایی پرتاب می‌شود. این متدها به‌صورت پیش‌فرض هنگام مقایسه‌ی فهرست‌ها یا تاپل‌ها با assertEqual() استفاده می‌شوند.

اضافه شده در نسخه‌ی 3.1.

assertSetEqual(first, second, msg=None)

برابری دو مجموعه را آزمایش می‌کند. در غیر این صورت، پیام خطایی ساخته می‌شود که تفاوت‌های بین دو مجموعه را فهرست می‌کند. این متد به‌طور پیش‌فرض هنگام مقایسه‌ی مجموعه‌ها یا frozensetها با assertEqual() استفاده می‌شود.

اگر هر یک از first یا second متد difference() را نداشته باشد، شکست می‌خورد.

اضافه شده در نسخه‌ی 3.1.

assertDictEqual(first, second, msg=None)

برابر بودن دو دیکشنری را آزمایش می‌کند. در غیر این صورت، پیام خطایی ساخته می‌شود که تفاوت‌های موجود در دیکشنری‌ها را نشان می‌دهد. این متد به‌طور پیش‌فرض برای مقایسه‌ی دیکشنری‌ها در فراخوانی‌های assertEqual() استفاده خواهد شد.

اضافه شده در نسخه‌ی 3.1.

در نهایت، TestCase متدها و ویژگی‌های زیر را فراهم می‌کند:

fail(msg=None)

به‌صورت بی‌قیدوشرط یک شکست آزمون را اعلام می‌کند، با msg یا None برای پیام خطا.

failureException

این ویژگی کلاس، استثنایی را که توسط متد آزمون پرتاب می‌شود، مشخص می‌کند. اگر یک چارچوب آزمون نیاز داشته باشد از یک استثنای اختصاصی استفاده کند، احتمالاً برای انتقال اطلاعات اضافی، باید از این استثنا زیرکلاس بسازد تا با چارچوب «منصفانه» رفتار کند. مقدار اولیه این ویژگی AssertionError است.

longMessage

این صفت کلاس مشخص می‌کند که چه اتفاقی می‌افتد هنگامی که یک پیام شکست سفارشی به‌عنوان آرگومان msg به یک فراخوانی assertXYY که شکست می‌خورد ارسال می‌شود. True مقدار پیش‌فرض است. در این حالت، پیام سفارشی به انتهای پیام شکست استاندارد اضافه می‌شود. وقتی روی False تنظیم شود، پیام سفارشی جایگزین پیام استاندارد می‌شود.

می‌توان تنظیم کلاس را در متدهای آزمون جداگانه با انتساب یک ویژگی نمونه، self.longMessage، به True یا False پیش از فراخوانی متدهای assert لغو کرد.

تنظیم کلاس پیش از هر فراخوانی آزمون بازنشانی می‌شود.

اضافه شده در نسخه‌ی 3.1.

maxDiff

این ویژگی حداکثر طول تفاوت‌ها (diffs) در خروجی متدهای assert را که در صورت شکست، تفاوت‌ها را گزارش می‌کنند، کنترل می‌کند. مقدار پیش‌فرض آن ۸۰*۸ نویسه است. متدهای assert که تحت تأثیر این ویژگی هستند، عبارتند از assertSequenceEqual() (از جمله تمام متدهای مقایسه‌ی دنباله‌ها که به آن واگذار می‌شوند)، assertDictEqual() و assertMultiLineEqual().

تنظیم maxDiff روی None به این معناست که برای diffها حداکثر طولی وجود ندارد.

اضافه شده در نسخه‌ی 3.2.

چارچوب‌های آزمون می‌توانند از متدهای زیر برای جمع‌آوری اطلاعات مربوط به آزمون استفاده کنند:

countTestCases()

تعداد آزمون‌هایی که این شیء آزمون نشان می‌دهد را برمی‌گرداند. برای نمونه‌های TestCase، این مقدار همیشه 1 خواهد بود.

defaultTestResult()

نمونه‌ای از کلاس نتیجه آزمون را برمی‌گرداند که باید برای این کلاس مورد آزمون استفاده شود (اگر نمونه نتیجه دیگری به متد run() ارائه نشده باشد).

برای نمونه‌های TestCase، این همیشه نمونه‌ای از TestResult خواهد بود؛ زیرکلاس‌های TestCase باید در صورت لزوم این را بازنویسی کنند.

id()

رشته‌ای را برمی‌گرداند که مورد آزمون مشخص را شناسایی می‌کند. این معمولاً نام کامل متد آزمون، شامل نام ماژول و نام کلاس است.

shortDescription()

توضیحی از آزمون را برمی‌گرداند، یا اگر توضیحی ارائه نشده باشد None برمی‌گرداند. پیاده‌سازی پیش‌فرض این متد، اولین خط از رشته‌ی مستند متد آزمون را، در صورت وجود، برمی‌گرداند، یا None.

تغییر یافته در نسخه‌ی 3.1: در 3.1 این مورد تغییر کرد تا نام آزمون حتی در صورت وجود رشته مستند به توضیح کوتاه اضافه شود. این امر باعث مشکلات سازگاری با افزونه‌های unittest شد و افزودن نام آزمون در پایتون 3.2 به TextTestResult منتقل شد.

addCleanup(function, /, *args, **kwargs)

تابعی را اضافه کنید که پس از tearDown() برای پاک‌سازی منابع استفاده‌شده در طول آزمون فراخوانی شود. توابع به ترتیب معکوس نسبت به ترتیبی که اضافه شده‌اند فراخوانی می‌شوند (LIFO). آن‌ها با هر آرگومان و آرگومان کلیدواژه‌ای که هنگام افزودنشان به addCleanup() ارسال شده‌اند، فراخوانی می‌شوند.

اگر setUp() شکست بخورد، به این معنا که tearDown() فراخوانی نمی‌شود، هر تابع پاک‌سازی که اضافه شده باشد همچنان فراخوانی خواهد شد.

اضافه شده در نسخه‌ی 3.1.

enterContext(cm)

به مدیر زمینه ارائه‌شده وارد می‌شود. در صورت موفقیت، همچنین متد __exit__() آن را به‌عنوان تابع پاک‌سازی با addCleanup() اضافه می‌کند و نتیجه‌ی متد __enter__() را برمی‌گرداند.

اضافه شده در نسخه‌ی 3.11.

doCleanups()

این متد بدون قید و شرط پس از tearDown()، یا پس از setUp() در صورتی فراخوانی می‌شود که setUp() استثنایی را پرتاب کند.

این متد مسئول فراخوانی تمام توابع پاک‌سازی اضافه‌شده توسط addCleanup() است. اگر نیاز دارید توابع پاک‌سازی پیش از tearDown() فراخوانی شوند، می‌توانید خودتان doCleanups() را فراخوانی کنید.

doCleanups() متدها را یکی‌یکی از پشته‌ی توابع پاک‌سازی برمی‌دارد، بنابراین می‌توان آن را در هر زمانی فراخوانی کرد.

اضافه شده در نسخه‌ی 3.1.

classmethod addClassCleanup(function, /, *args, **kwargs)

یک تابع برای فراخوانی پس از tearDownClass() اضافه کنید تا منابع استفاده‌شده در طول کلاس آزمون پاک‌سازی شوند. توابع به ترتیب معکوس نسبت به ترتیب اضافه‌شدنشان فراخوانی می‌شوند (LIFO). آن‌ها با هر آرگومان و آرگومان کلیدواژه‌ای که هنگام اضافه‌شدنشان به addClassCleanup() ارسال شده باشد، فراخوانی می‌شوند.

اگر setUpClass() شکست بخورد، یعنی tearDownClass() فراخوانی نمی‌شود، هر یک از توابع پاک‌سازی اضافه‌شده همچنان فراخوانی خواهند شد.

اضافه شده در نسخه‌ی 3.8.

classmethod enterClassContext(cm)

وارد مدیر زمینه ارائه‌شده شوید. در صورت موفقیت، متد __exit__() آن را نیز به‌عنوان یک تابع پاک‌سازی از طریق addClassCleanup() اضافه کنید و نتیجه‌ی متد __enter__() را برگردانید.

اضافه شده در نسخه‌ی 3.11.

classmethod doClassCleanups()

این متد به‌صورت غیرشرطی پس از tearDownClass()، یا در صورتی که setUpClass() استثنایی پرتاب کند، پس از setUpClass() فراخوانی می‌شود.

این متد مسئول فراخوانی تمام توابع پاک‌سازی است که توسط addClassCleanup() افزوده شده‌اند. اگر نیاز دارید توابع پاک‌سازی پیش از tearDownClass() فراخوانی شوند، می‌توانید خودتان doClassCleanups() را فراخوانی کنید.

doClassCleanups() متدها را یکی‌یکی از پشته‌ی توابع پاک‌سازی برمی‌دارد، بنابراین در هر زمانی می‌توان آن را فراخوانی کرد.

اضافه شده در نسخه‌ی 3.8.

class unittest.IsolatedAsyncioTestCase(methodName='runTest')

این کلاس یک API مشابه TestCase ارائه می‌دهد و همچنین هم‌روال‌ها را به‌عنوان توابع آزمون می‌پذیرد.

اضافه شده در نسخه‌ی 3.8.

loop_factory

loop_factory که به asyncio.Runner داده می‌شود. در زیرکلاس‌ها آن را با asyncio.EventLoop بازنویسی کنید تا از استفاده از سیستم سیاست asyncio اجتناب شود.

اضافه شده در نسخه‌ی 3.13.

async asyncSetUp()

متدی که برای آماده‌سازی ثابت آزمایشی آزمون فراخوانی می‌شود. این متد پس از TestCase.setUp() فراخوانی می‌شود. این متد دقیقاً پیش از فراخوانی متد آزمون فراخوانی می‌شود؛ به‌جز AssertionError یا SkipTest، هر استثنایی که این متد پرتاب کند، خطا محسوب می‌شود، نه شکست آزمون. پیاده‌سازی پیش‌فرض هیچ کاری انجام نمی‌دهد.

async asyncTearDown()

متدی که بلافاصله پس از فراخوانی متد آزمون و ثبت نتیجه آن، فراخوانی می‌شود. این متد پیش از tearDown() فراخوانی می‌شود. این متد حتی اگر متد آزمون استثنایی را پرتاب کرده باشد نیز فراخوانی می‌شود، بنابراین پیاده‌سازی آن در زیرکلاس‌ها ممکن است نیازمند دقت ویژه‌ای در بررسی وضعیت داخلی باشد. هر استثنایی غیر از AssertionError یا SkipTest که توسط این متد پرتاب شود، یک خطای اضافی محسوب می‌شود نه شکست آزمون (بنابراین تعداد کل خطاهای گزارش‌شده را افزایش می‌دهد). این متد تنها زمانی فراخوانی می‌شود که asyncSetUp() موفق شود، صرف‌نظر از نتیجه متد آزمون. پیاده‌سازی پیش‌فرض هیچ کاری انجام نمی‌دهد.

addAsyncCleanup(function, /, *args, **kwargs)

این متد یک هم‌روال را می‌پذیرد که می‌تواند به‌عنوان تابع پاک‌سازی استفاده شود.

async enterAsyncContext(cm)

وارد مدیر زمینه ناهمگام ارائه‌شده می‌شود. در صورت موفقیت، همچنین متد __aexit__() آن را به‌عنوان یک تابع پاک‌سازی از طریق addAsyncCleanup() اضافه می‌کند و نتیجه‌ی متد __aenter__() را برمی‌گرداند.

اضافه شده در نسخه‌ی 3.11.

run(result=None)

یک حلقه‌ی رویداد جدید برای اجرای آزمون راه‌اندازی می‌کند و نتیجه را در شیء TestResult که به‌عنوان result ارسال شده است، جمع‌آوری می‌کند. اگر result حذف شده باشد یا None باشد، یک شیء نتیجه‌ی موقت ایجاد می‌شود (با فراخوانی متد defaultTestResult()) و استفاده می‌شود. شیء نتیجه به فراخواننده‌ی run() برگردانده می‌شود. در پایان آزمون، همه‌ی وظایف موجود در حلقه‌ی رویداد لغو می‌شوند.

مثالی که ترتیب را نشان می‌دهد:

from unittest import IsolatedAsyncioTestCase

events = []


class Test(IsolatedAsyncioTestCase):


    def setUp(self):
        events.append("setUp")

    async def asyncSetUp(self):
        self._async_connection = await AsyncConnection()
        events.append("asyncSetUp")

    async def test_response(self):
        events.append("test_response")
        response = await self._async_connection.get("https://example.com")
        self.assertEqual(response.status_code, 200)
        self.addAsyncCleanup(self.on_cleanup)

    def tearDown(self):
        events.append("tearDown")

    async def asyncTearDown(self):
        await self._async_connection.close()
        events.append("asyncTearDown")

    async def on_cleanup(self):
        events.append("cleanup")

if __name__ == "__main__":
    unittest.main()

پس از اجرای آزمون، events شامل ["setUp", "asyncSetUp", "test_response", "asyncTearDown", "tearDown", "cleanup"] خواهد بود.

class unittest.FunctionTestCase(testFunc, setUp=None, tearDown=None, description=None)

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

گروه‌بندی آزمون‌ها

class unittest.TestSuite(tests=())

این کلاس یک گردآوری از موارد آزمون منفرد و مجموعه‌های آزمون را نشان می‌دهد. این کلاس رابط مورد نیاز اجراکننده آزمون را ارائه می‌کند تا بتوان آن را مانند هر مورد آزمون دیگری اجرا کرد. اجرای یک نمونه TestSuite معادل پیمایش روی بدنه‌ی و اجرای هر آزمون به‌صورت جداگانه است.

اگر tests داده شود، باید یک پیمایش‌پذیر از موارد آزمون جداگانه یا سایر بدنه‌های آزمون باشد که در ابتدا برای ساخت بدنه استفاده می‌شود. متدهای دیگری برای افزودن موارد آزمون و مجموعه‌ها به این مجموعه در ادامه فراهم شده‌اند.

اشیای TestSuite بسیار مانند اشیای TestCase رفتار می‌کنند، با این تفاوت که در واقع یک آزمون را پیاده‌سازی نمی‌کنند. در عوض، از آن‌ها برای جمع‌آوری آزمون‌ها در گروه‌هایی که باید با هم اجرا شوند استفاده می‌شود. برخی متدهای اضافی برای افزودن آزمون‌ها به نمونه‌های TestSuite در دسترس هستند:

addTest(test)

یک TestCase یا TestSuite را به بدنه اضافه کنید.

addTests(tests)

تمام آزمون‌ها را از یک پیمایش‌پذیر شامل نمونه‌های TestCase و TestSuite به این بدنه‌ی آزمون اضافه کنید.

این معادل پیمایش روی tests و فراخوانی addTest() برای هر عنصر است.

TestSuite متدهای زیر را با TestCase به اشتراک می‌گذارد:

run(result)

آزمون‌های مرتبط با این بدنه را اجرا می‌کند و نتیجه را در شیء نتیجه آزمون که به‌عنوان result ارسال شده است، جمع‌آوری می‌کند. توجه داشته باشید که برخلاف TestCase.run()، TestSuite.run() نیازمند ارسال شیء نتیجه است.

debug()

آزمون‌های مرتبط با این بدنه را بدون جمع‌آوری نتیجه اجرا کنید. این کار اجازه می‌دهد استثناهای پرتاب‌شده توسط آزمون به فراخواننده منتقل شوند و می‌تواند برای پشتیبانی از اجرای آزمون‌ها زیر اشکال‌زدا استفاده شود.

countTestCases()

تعداد آزمون‌های بازنمایی‌شده توسط این شیء آزمون را برمی‌گرداند، شامل تمام آزمون‌های منفرد و زیرمجموعه‌های آزمون.

__iter__()

آزمون‌های گروه‌بندی‌شده در یک TestSuite همیشه از طریق پیمایش قابل‌دسترسی هستند. زیرکلاس‌ها می‌توانند با بازنویسی __iter__()، آزمون‌ها را به‌صورت تنبل فراهم کنند. توجه داشته باشید که این متد ممکن است چندین بار روی یک بدنه واحد فراخوانی شود (برای مثال هنگام شمارش آزمون‌ها یا مقایسه برای برابری)، بنابراین آزمون‌های برگردانده‌شده در تکرارهای مکرر پیش از TestSuite.run() باید برای هر بار فراخوانی یکسان باشند. پس از TestSuite.run()، فراخواننده‌ها نباید به آزمون‌های برگردانده‌شده توسط این متد اتکا کنند، مگر آنکه فراخواننده از زیرکلاسی استفاده کند که TestSuite._removeTestAtIndex() را برای حفظ ارجاع‌های آزمون‌ها بازنویسی کرده باشد.

تغییر یافته در نسخه‌ی 3.2: در نسخه‌های پیشین، TestSuite مستقیماً و نه از طریق پیمایش به آزمون‌ها دسترسی پیدا می‌کرد، بنابراین بازنویسی __iter__() برای فراهم کردن آزمون‌ها کافی نبود.

تغییر یافته در نسخه‌ی 3.4: در نسخه‌های پیشین، TestSuite پس از TestSuite.run() ارجاع‌هایی به هر TestCase نگه می‌داشت. زیرکلاس‌ها می‌توانند با بازنویسی TestSuite._removeTestAtIndex() آن رفتار را بازیابی کنند.

در استفاده‌ی معمول از یک شیء TestSuite، متد run() توسط یک TestRunner فراخوانی می‌شود، نه توسط چارچوب آزمون کاربر نهایی.

بارگذاری و اجرای آزمون‌ها

class unittest.TestLoader

از کلاس TestLoader برای ایجاد مجموعه‌های آزمون از کلاس‌ها و ماژول‌ها استفاده می‌شود. معمولاً نیازی به ایجاد نمونه‌ای از این کلاس نیست؛ ماژول unittest یک نمونه فراهم می‌کند که می‌توان آن را به‌عنوان unittest.defaultTestLoader به‌صورت مشترک استفاده کرد. با این حال، استفاده از یک زیرکلاس یا نمونه، امکان سفارشی‌سازی برخی ویژگی‌های قابل‌پیکربندی را فراهم می‌کند.

اشیای TestLoader دارای ویژگی‌های زیر هستند:

errors

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

اضافه شده در نسخه‌ی 3.5.

اشیای TestLoader متدهای زیر را دارند:

loadTestsFromTestCase(testCaseClass)

یک بدنه آزمون شامل تمام موارد آزمون موجود در testCaseClass مشتق‌شده از TestCase را برمی‌گرداند.

برای هر متدی که توسط getTestCaseNames() نام برده شده باشد، یک نمونه از مورد آزمون ایجاد می‌شود. به‌طور پیش‌فرض، این‌ها نام متدهایی هستند که با test شروع می‌شوند. اگر getTestCaseNames() هیچ متدی را برنگرداند، اما متد runTest() پیاده‌سازی شده باشد، در عوض یک مورد آزمون واحد برای آن متد ایجاد می‌شود.

loadTestsFromModule(module, *, pattern=None)

یک بدنه از تمام موارد آزمون موجود در ماژول داده‌شده برمی‌گرداند. این متد در module به دنبال کلاس‌هایی مشتق‌شده از TestCase می‌گردد و برای هر متد آزمون تعریف‌شده برای آن کلاس، یک نمونه از آن کلاس ایجاد می‌کند.

توجه

در حالی که استفاده از سلسله‌مراتبی از کلاس‌های مشتق‌شده از TestCase می‌تواند به‌اشتراک‌گذاری تدارکات (fixtures) و توابع کمکی را آسان کند، تعریف متدهای آزمون در کلاس‌های پایه‌ای که برای نمونه‌سازی مستقیم در نظر گرفته نشده‌اند، با این متد به‌خوبی کار نمی‌کند. با این حال، این کار می‌تواند زمانی مفید باشد که تدارکات متفاوت باشند و در زیرکلاس‌ها تعریف شده باشند.

اگر یک ماژول تابع load_tests را فراهم کند، برای بارگذاری آزمون‌ها فراخوانی می‌شود. این امر به ماژول‌ها امکان می‌دهد بارگذاری آزمون‌ها را سفارشی‌سازی کنند. این load_tests protocol است. آرگومان pattern به‌عنوان آرگومان سوم به load_tests ارسال می‌شود.

تغییر یافته در نسخه‌ی 3.2: پشتیبانی از load_tests اضافه شد.

تغییر یافته در نسخه‌ی 3.5: پشتیبانی از آرگومان فقط کلیدواژه‌ای pattern اضافه شد.

تغییر یافته در نسخه‌ی 3.12: پارامتر مستندنشده و غیررسمی use_load_tests حذف شده است.

loadTestsFromName(name, module=None)

یک بدنه از تمام موارد آزمون را بر اساس یک مشخص‌کننده رشته‌ای برمی‌گرداند.

مشخص‌کننده‌ی name یک «نام نقطه‌دار» است که ممکن است به یک ماژول، یک کلاس مورد آزمون، یک متد آزمون درون یک کلاس مورد آزمون، یک نمونه‌ی TestSuite، یا یک شیء قابل فراخوانی که یک نمونه‌ی TestCase یا TestSuite را برمی‌گرداند، حل شود. این بررسی‌ها به ترتیبی که در اینجا فهرست شده‌اند اعمال می‌شوند؛ یعنی یک متد در یک کلاس مورد آزمون احتمالی، به‌عنوان «متد آزمون درون یک کلاس مورد آزمون» شناسایی می‌شود، نه به‌عنوان «شیء فراخوانی‌پذیر».

برای مثال، اگر یک ماژول SampleTests داشته باشید که شامل یک کلاس مشتق‌شده از TestCase به نام SampleTestCase با ۳ متد آزمون (test_one()، test_two() و test_three()) باشد، مشخص‌کننده 'SampleTests.SampleTestCase' باعث می‌شود این متد یک بدنه آزمون را برگرداند که هر ۳ متد آزمون را اجرا می‌کند. استفاده از مشخص‌کننده 'SampleTests.SampleTestCase.test_two' باعث می‌شود آن متد یک بدنه آزمون را برگرداند که فقط متد آزمون test_two() را اجرا می‌کند. مشخص‌کننده می‌تواند به ماژول‌ها و بسته‌هایی اشاره کند که ایمپورت نشده‌اند؛ آن‌ها به‌عنوان یک اثر جانبی ایمپورت می‌شوند.

این متد به‌صورت اختیاری name را نسبت به module داده‌شده حل می‌کند.

تغییر یافته در نسخه‌ی 3.5: اگر هنگام پیمایش name یک ImportError یا AttributeError رخ دهد، یک آزمون مصنوعی که هنگام اجرا آن خطا را پرتاب می‌کند برگردانده خواهد شد. این خطاها در خطاهای جمع‌آوری‌شده توسط self.errors گنجانده می‌شوند.

loadTestsFromNames(names, module=None)

مشابه loadTestsFromName()، اما یک دنباله از نام‌ها را به‌جای یک نام دریافت می‌کند. مقدار بازگشتی یک بدنه آزمون (test suite) است که از تمام آزمون‌های تعریف‌شده برای هر نام پشتیبانی می‌کند.

getTestCaseNames(testCaseClass)

یک دنباله مرتب‌شده از نام متدهای یافت‌شده در testCaseClass را برمی‌گرداند؛ این باید زیرکلاسی از TestCase باشد.

discover(start_dir, pattern='test*.py', top_level_dir=None)

همه‌ی ماژول‌های آزمون را از پوشه شروع مشخص‌شده، با پیمایش بازگشتی در زیرپوشه‌ها پیدا می‌کند و یک شیء TestSuite حاوی آن‌ها را برمی‌گرداند. فقط پرونده‌های آزمونی که با pattern مطابقت دارند بارگذاری می‌شوند. (با استفاده از تطبیق الگو به سبک پوسته.) فقط نام ماژول‌هایی که قابل ایمپورت هستند (یعنی شناسه‌های معتبر پایتون هستند) بارگذاری می‌شوند.

همه‌ی ماژول‌های آزمون باید از سطح بالایی پروژه قابل ایمپورت باشند. اگر پوشه شروع، پوشه سطح بالایی نباشد، باید top_level_dir به‌طور جداگانه مشخص شود.

اگر ایمپورت یک ماژول با شکست مواجه شود، برای مثال به دلیل خطای سینتکسی، این مورد به‌عنوان یک خطای واحد ثبت خواهد شد و کشف ادامه خواهد یافت. اگر علت شکست ایمپورت، پرتاب SkipTest باشد، به‌جای خطا به‌عنوان یک پرش ثبت خواهد شد.

اگر یک بسته (پوشه‌ای که حاوی پرونده‌ای به نام __init__.py است) یافت شود، بسته از نظر وجود تابع load_tests بررسی می‌شود. اگر این تابع وجود داشته باشد، به‌صورت package.load_tests(loader, tests, pattern) فراخوانی می‌شود. کشف آزمون اطمینان حاصل می‌کند که یک بسته تنها یک بار در طول یک فراخوانی برای یافتن آزمون‌ها بررسی شود، حتی اگر تابع load_tests خودش loader.discover را فراخوانی کند.

اگر load_tests وجود داشته باشد، کشف (discovery) به‌صورت بازگشتی وارد بسته نمی‌شود، load_tests مسئول بارگذاری تمام آزمون‌ها در بسته است.

این الگو عمداً به‌عنوان یک ویژگی بارگذار ذخیره نمی‌شود تا بسته‌ها بتوانند خودشان کشف را ادامه دهند.

top_level_dir به‌صورت داخلی ذخیره می‌شود و به‌عنوان پیش‌فرض برای هر فراخوانی تودرتویی از discover() استفاده می‌شود. یعنی اگر load_tests یک بسته، loader.discover() را فراخوانی کند، نیازی به ارسال این آرگومان ندارد.

start_dir می‌تواند هم یک نام ماژول نقطه‌دار و هم یک پوشه باشد.

اضافه شده در نسخه‌ی 3.2.

تغییر یافته در نسخه‌ی 3.4: ماژول‌هایی که هنگام ایمپورت، SkipTest را پرتاب می‌کنند، به‌عنوان پرش ثبت می‌شوند، نه خطا.

start_dir می‌تواند یک بسته‌ی فضای نام باشد.

مسیرها پیش از ایمپورت شدن مرتب می‌شوند تا ترتیب اجرا یکسان باشد، حتی اگر ترتیب سامانه فایل‌بندی زیربنایی به نام پرونده وابسته نباشد.

تغییر یافته در نسخه‌ی 3.5: بسته‌های یافت‌شده اکنون از نظر load_tests بررسی می‌شوند، صرف‌نظر از اینکه مسیر آن‌ها با pattern مطابقت داشته باشد، زیرا غیرممکن است که نام یک بسته با الگوی پیش‌فرض مطابقت داشته باشد.

تغییر یافته در نسخه‌ی 3.11: start_dir نمی‌تواند یک بسته‌ی فضای نام باشد. این از پایتون 3.7 خراب بوده است، و پایتون 3.11 به‌طور رسمی آن را حذف می‌کند.

تغییر یافته در نسخه‌ی 3.13: top_level_dir فقط در طول فراخوانی discover ذخیره می‌شود.

تغییر یافته در نسخه‌ی 3.14: start_dir می‌تواند بار دیگر یک namespace package باشد.

ویژگی‌های زیرِ یک TestLoader را می‌توان یا از طریق زیرکلاس‌سازی یا با انتساب روی یک نمونه پیکربندی کرد:

testMethodPrefix

رشته‌ای که پیشوند نام متدهایی را که به‌عنوان متدهای آزمون تفسیر می‌شوند، مشخص می‌کند. مقدار پیش‌فرض 'test' است.

این موضوع بر getTestCaseNames() و تمام متدهای loadTestsFrom* تأثیر می‌گذارد.

sortTestMethodsUsing

تابعی که برای مقایسه‌ی نام متدها هنگام مرتب‌سازی آن‌ها در getTestCaseNames() و تمام متدهای loadTestsFrom* استفاده می‌شود.

suiteClass

شیء فراخوانی‌پذیری که یک بدنه آزمون را از فهرستی از آزمون‌ها می‌سازد. به هیچ متدی روی شیء حاصل نیازی نیست. مقدار پیش‌فرض، کلاس TestSuite است.

این بر تمام متدهای loadTestsFrom* تأثیر می‌گذارد.

testNamePatterns

فهرستی از الگوهای نام آزمون با وایلدکارد به سبک پوسته‌ی Unix که متدهای آزمون برای گنجانده شدن در مجموعه‌های آزمون باید با آن‌ها مطابقت کنند (گزینه‌ی -k را ببینید).

اگر این ویژگی None (پیش‌فرض) نباشد، تمام متدهای آزمونی که قرار است در مجموعه‌های آزمون گنجانده شوند، باید با یکی از الگوهای این فهرست مطابقت داشته باشند. توجه داشته باشید که عملیات تطبیق همیشه با استفاده از fnmatch.fnmatchcase() انجام می‌شود، بنابراین برخلاف الگوهایی که به گزینه‌ی -k داده می‌شوند، الگوهای زیررشته‌ی ساده باید با استفاده از وایلدکارد * تبدیل شوند.

این بر تمام متدهای loadTestsFrom* تأثیر می‌گذارد.

اضافه شده در نسخه‌ی 3.7.

class unittest.TestResult

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

یک شیء TestResult نتایج مجموعه‌ای از آزمون‌ها را ذخیره می‌کند. کلاس‌های TestCase و TestSuite تضمین می‌کنند که نتایج به‌درستی ثبت شوند؛ نویسندگان آزمون نیازی نیست نگران ثبت نتیجه آزمون‌ها باشند.

چارچوب‌های آزمون ساخته‌شده بر پایه‌ی unittest ممکن است بخواهند برای اهداف گزارش‌دهی، به شیء TestResult تولیدشده با اجرای مجموعه‌ای از آزمون‌ها دسترسی داشته باشند؛ برای همین منظور، یک نمونه TestResult توسط متد TestRunner.run() برگردانده می‌شود.

نمونه‌های TestResult دارای ویژگی‌های زیر هستند که هنگام بررسی نتایج اجرای مجموعه‌ای از آزمون‌ها مورد توجه خواهند بود:

errors

فهرستی شامل تاپل‌های دوتایی از نمونه‌های TestCase و رشته‌های حاوی ردگیری‌های قالب‌بندی‌شده. هر تاپل نمایانگر آزمونی است که استثنای غیرمنتظره‌ای را پرتاب کرده است.

failures

فهرستی شامل تاپل‌های دوتایی از نمونه‌های TestCase و رشته‌های حاوی ردگیری‌های پشته قالب‌بندی‌شده. هر تاپل نشان‌دهنده آزمونی است که در آن شکستی به‌صراحت با استفاده از متدهای assert* اعلام شده است.

skipped

فهرستی شامل تاپل‌های دوتایی از نمونه‌های TestCase و رشته‌هایی که دلیل رد کردن آزمون را در بر دارند.

اضافه شده در نسخه‌ی 3.1.

expectedFailures

فهرستی شامل تاپل‌های دوتایی از نمونه‌های TestCase و رشته‌های حاوی ردگیری‌های پشته قالب‌بندی‌شده. هر تاپل نشان‌دهنده‌ی یک شکست یا خطای مورد انتظار برای آزمون مربوطه است.

unexpectedSuccesses

فهرستی شامل نمونه‌های TestCase که به‌عنوان شکست‌های مورد انتظار علامت‌گذاری شده بودند، اما موفق شدند.

collectedDurations

فهرستی شامل تاپل‌های دوتایی از نام‌های موارد آزمون و اعداد اعشاریی که زمان سپری‌شده‌ی هر آزمون اجراشده را نشان می‌دهند.

اضافه شده در نسخه‌ی 3.12.

shouldStop

هنگامی که اجرای آزمون‌ها باید توسط stop() متوقف شود، روی True تنظیم می‌شود.

testsRun

تعداد کل آزمون‌های اجراشده تاکنون.

buffer

اگر روی true تنظیم شود، sys.stdout و sys.stderr بین فراخوانی startTest() و stopTest() بافر می‌شوند. خروجی جمع‌آوری‌شده تنها در صورتی روی sys.stdout و sys.stderr واقعی بازتاب داده می‌شود که آزمون شکست بخورد یا خطا دهد. هرگونه خروجی نیز به پیام شکست / خطا پیوست می‌شود.

اضافه شده در نسخه‌ی 3.2.

failfast

اگر روی true تنظیم شود، در نخستین شکست یا خطا، stop() فراخوانی می‌شود و اجرای آزمون متوقف می‌شود.

اضافه شده در نسخه‌ی 3.2.

tb_locals

اگر روی true تنظیم شود، متغیرهای محلی در ردگیری‌های پشته نمایش داده می‌شوند.

اضافه شده در نسخه‌ی 3.5.

wasSuccessful()

اگر تمام آزمون‌هایی که تاکنون اجرا شده‌اند موفق بوده باشند، True برمی‌گرداند، در غیر این صورت False برمی‌گرداند.

تغییر یافته در نسخه‌ی 3.4: اگر هرگونه unexpectedSuccesses از آزمون‌هایی که با دکوراتور @expectedFailure علامت‌گذاری شده‌اند وجود داشته باشد، False را برمی‌گرداند.

stop()

این متد را می‌توان برای اعلام اینکه بدنه آزمون‌های در حال اجرا باید با تنظیم ویژگی shouldStop روی True متوقف شود، فراخوانی کرد. اشیای TestRunner باید این پرچم را رعایت کنند و بدون اجرای هیچ آزمون اضافی‌ای بازگردند.

برای مثال، این قابلیت توسط کلاس TextTestRunner برای توقف چارچوب آزمون زمانی استفاده می‌شود که کاربر وقفه‌ای را از صفحه‌کلید اعلام می‌کند. ابزارهای تعاملی که پیاده‌سازی‌های TestRunner را ارائه می‌دهند، می‌توانند به‌صورت مشابهی از این قابلیت استفاده کنند.

متدهای زیر از کلاس TestResult برای نگهداری ساختارهای داده‌ی داخلی استفاده می‌شوند و می‌توانند در زیرکلاس‌ها برای پشتیبانی از نیازمندی‌های گزارش‌دهی بیشتر گسترش یابند. این کار به‌ویژه هنگام ساخت ابزارهایی که از گزارش‌دهی تعاملی در حین اجرای آزمون‌ها پشتیبانی می‌کنند، مفید است.

startTest(test)

هنگامی فراخوانی می‌شود که مورد آزمون test در شرف اجرا باشد.

stopTest(test)

پس از اجرای مورد آزمون test، صرف‌نظر از نتیجه، فراخوانی می‌شود.

startTestRun()

یک بار پیش از اجرای هر آزمونی فراخوانی می‌شود.

اضافه شده در نسخه‌ی 3.1.

stopTestRun()

یک بار پس از اجرای همه‌ی آزمون‌ها فراخوانی می‌شود.

اضافه شده در نسخه‌ی 3.1.

addError(test, err)

هنگامی فراخوانی می‌شود که کیس آزمون test یک استثنای غیرمنتظره را پرتاب کند. err یک تاپل با قالبی است که توسط sys.exc_info() برگردانده می‌شود: (type, value, traceback).

پیاده‌سازی پیش‌فرض یک تاپل (test, formatted_err) را به ویژگی errors نمونه اضافه می‌کند، که در آن formatted_err یک ردگیری پشته‌ی قالب‌بندی‌شده است که از err به‌دست آمده است.

addFailure(test, err)

هنگامی فراخوانی می‌شود که مورد آزمون test شکستی را اعلام کند. err یک تاپل با قالبی است که توسط sys.exc_info() برگردانده می‌شود: (type, value, traceback).

پیاده‌سازی پیش‌فرض یک تاپل (test, formatted_err) را به ویژگی failures نمونه می‌افزاید، که در آن formatted_err یک ردگیری پشته قالب‌بندی‌شده است که از err به‌دست آمده است.

addSuccess(test)

هنگامی که مورد آزمون test موفق باشد، فراخوانی می‌شود.

پیاده‌سازی پیش‌فرض هیچ کاری انجام نمی‌دهد.

addSkip(test, reason)

هنگامی که مورد آزمون test رد می‌شود، فراخوانی می‌شود. reason دلیلی است که آزمون برای رد شدن ارائه کرده است.

پیاده‌سازی پیش‌فرض یک تاپل (test, reason) را به ویژگی skipped نمونه اضافه می‌کند.

addExpectedFailure(test, err)

هنگامی فراخوانی می‌شود که مورد آزمون test شکست بخورد یا خطا بدهد، اما با دکوراتور @expectedFailure علامت‌گذاری شده باشد.

پیاده‌سازی پیش‌فرض، یک تاپل (test, formatted_err) را به ویژگی expectedFailures نمونه می‌افزاید، که در آن formatted_err یک ردگیری پشته‌ی قالب‌بندی‌شده گرفته از err است.

addUnexpectedSuccess(test)

هنگامی فراخوانی می‌شود که مورد آزمون test با دکوراتور @expectedFailure علامت‌گذاری شده باشد، اما موفق شود.

پیاده‌سازی پیش‌فرض، آزمون را به ویژگی unexpectedSuccesses نمونه اضافه می‌کند.

addSubTest(test, subtest, outcome)

هنگامی که یک زیرآزمون به پایان می‌رسد، فراخوانی می‌شود. test مورد آزمون متناظر با متد آزمون است. subtest یک نمونه‌ی سفارشی از TestCase است که زیرآزمون را توصیف می‌کند.

اگر outcome برابر None باشد، زیرآزمون موفق شده است. در غیر این صورت، با یک استثنا شکست خورده است، که در آن outcome یک تاپل به‌شکلی است که sys.exc_info() برمی‌گرداند: (type, value, traceback).

پیاده‌سازی پیش‌فرض در صورت موفقیت‌آمیز بودن نتیجه، کاری انجام نمی‌دهد و شکست‌های زیرآزمون را به‌عنوان شکست‌های عادی ثبت می‌کند.

اضافه شده در نسخه‌ی 3.4.

addDuration(test, elapsed)

هنگامی که مورد آزمون به پایان می‌رسد، فراخوانی می‌شود. elapsed زمان بر حسب ثانیه است و شامل اجرای توابع پاک‌سازی نیز می‌شود.

اضافه شده در نسخه‌ی 3.12.

class unittest.TextTestResult(stream, descriptions, verbosity, *, durations=None)

یک پیاده‌سازی مشخص از TestResult که توسط TextTestRunner استفاده می‌شود. زیرکلاس‌ها باید **kwargs را بپذیرند تا با تغییر رابط، سازگاری تضمین شود.

اضافه شده در نسخه‌ی 3.2.

تغییر یافته در نسخه‌ی 3.12: پارامتر کلیدواژه‌ای durations افزوده شد.

unittest.defaultTestLoader

نمونه‌ای از کلاس TestLoader که برای اشتراک‌گذاری در نظر گرفته شده است. اگر نیازی به سفارشی‌سازی TestLoader نباشد، می‌توان به‌جای ایجاد مکرر نمونه‌های جدید، از این نمونه استفاده کرد.

class unittest.TextTestRunner(stream=None, descriptions=True, verbosity=1, failfast=False, buffer=False, resultclass=None, warnings=None, *, tb_locals=False, durations=None)

یک پیاده‌سازی پایه‌ی اجراکننده‌ی آزمون که نتایج را به یک جریان خروجی می‌دهد. اگر stream برابر None باشد (مقدار پیش‌فرض)، از sys.stderr به‌عنوان جریان خروجی استفاده می‌شود. این کلاس چند پارامتر قابل‌پیکربندی دارد، اما اساساً بسیار ساده است. برنامه‌های گرافیکی که مجموعه‌های آزمون را اجرا می‌کنند، باید پیاده‌سازی‌های جایگزین ارائه دهند. چنین پیاده‌سازی‌هایی باید **kwargs را بپذیرند، زیرا وقتی قابلیت‌هایی به unittest اضافه می‌شود، رابط ساخت اجراکننده‌ها تغییر می‌کند.

به‌طور پیش‌فرض، این اجراکننده DeprecationWarning، PendingDeprecationWarning، ResourceWarning و ImportWarning را نمایش می‌دهد، حتی اگر به‌طور پیش‌فرض نادیده گرفته شوند. می‌توان این رفتار را با استفاده از گزینه‌های -Wd یا -Wa پایتون (به کنترل هشدار مراجعه کنید) و قرار دادن warnings روی None لغو کرد.

تغییر یافته در نسخه‌ی 3.2: پارامتر warnings افزوده شد.

تغییر یافته در نسخه‌ی 3.2: جریان پیش‌فرض در زمان نمونه‌سازی روی sys.stderr تنظیم می‌شود، نه در زمان ایمپورت.

تغییر یافته در نسخه‌ی 3.5: پارامتر tb_locals افزوده شد.

تغییر یافته در نسخه‌ی 3.12: پارامتر durations افزوده شد.

_makeResult()

این متد نمونه‌ای از TestResult را برمی‌گرداند که run() از آن استفاده می‌کند. این متد برای فراخوانی مستقیم در نظر گرفته نشده است، اما می‌توان آن را در زیرکلاس‌ها بازنویسی کرد تا یک TestResult سفارشی فراهم شود.

_makeResult() کلاس یا فراخوانی‌پذیر گذرانده‌شده در سازنده‌ی TextTestRunner به‌عنوان آرگومان resultclass را نمونه‌سازی می‌کند. اگر resultclass ارائه‌نشده باشد، به‌طور پیش‌فرض TextTestResult استفاده می‌شود. کلاس نتیجه با آرگومان‌های زیر نمونه‌سازی می‌شود:

stream, descriptions, verbosity
run(test)

این متد رابط عمومی اصلی برای TextTestRunner است. این متد یک نمونه از TestSuite یا TestCase دریافت می‌کند. یک TestResult با فراخوانی _makeResult() ایجاد می‌شود و آزمون(ها) اجرا می‌شوند و نتایج در stdout چاپ می‌شوند.

unittest.main(module='__main__', defaultTest=None, argv=None, testRunner=None, testLoader=unittest.defaultTestLoader, exit=True, verbosity=1, failfast=None, catchbreak=None, buffer=None, warnings=None)

برنامه‌ای خط‌فرمانی که مجموعه‌ای از آزمون‌ها را از module بارگذاری می‌کند و آن‌ها را اجرا می‌کند؛ این موضوع عمدتاً برای این است که ماژول‌های آزمون به‌راحتی قابل اجرا شوند. ساده‌ترین استفاده از این تابع، گنجاندن خط زیر در پایان یک اسکریپت آزمون است:

if __name__ == '__main__':
    unittest.main()

می‌توانید با ارسال آرگومان verbosity، آزمون‌ها را با اطلاعات پرجزئیات‌تر اجرا کنید:

if __name__ == '__main__':
    unittest.main(verbosity=2)

آرگومان defaultTest یا نام یک آزمون منفرد است یا یک پیمایش‌پذیر از نام‌های آزمون برای اجرا، در صورتی که هیچ نام آزمونی از طریق argv مشخص نشده باشد. اگر مشخص نشده باشد یا None باشد و هیچ نام آزمونی از طریق argv ارائه نشده باشد، تمام آزمون‌های یافت‌شده در module اجرا می‌شوند.

آرگومان argv می‌تواند فهرستی از گزینه‌های ارسال‌شده به برنامه باشد، که اولین عنصر آن نام برنامه است. اگر مشخص‌نشده باشد یا None باشد، مقادیر sys.argv استفاده می‌شوند.

آرگومان testRunner می‌تواند یک کلاس اجراکننده‌ی آزمون یا نمونه‌ای از پیش ایجادشده‌ی آن باشد. به‌طور پیش‌فرض، main sys.exit() را با کد خروجی‌ای فراخوانی می‌کند که نشان‌دهنده‌ی موفقیت (۰) یا شکست (۱) آزمون‌های اجراشده است. کد خروجی ۵ نشان می‌دهد که هیچ آزمونی اجرا نشده یا رد شده است.

آرگومان testLoader باید نمونه‌ای از TestLoader باشد، و مقدار پیش‌فرض آن defaultTestLoader است.

main از فراخوانی در مفسر تعاملی با فرستادن آرگومان exit=False پشتیبانی می‌کند. این کار نتیجه را در خروجی استاندارد بدون فراخوانی sys.exit() نمایش می‌دهد:

>>> from unittest import main
>>> main(module='test_module', exit=False)

پارامترهای failfast، catchbreak و buffer همان اثر command-line options هم‌نام را دارند.

آرگومان warnings فیلتر هشدار را مشخص می‌کند که باید هنگام اجرای آزمون‌ها استفاده شود. اگر مشخص نشده باشد، چنانچه گزینه‌ی -W به python داده شود، None باقی می‌ماند (به کنترل هشدار مراجعه کنید)، در غیر این صورت روی 'default' تنظیم می‌شود.

فراخوانی main شیءای را بازمی‌گرداند که دارای ویژگی result است و نتیجه‌ی آزمون‌های اجراشده را به‌صورت یک unittest.TestResult در بر دارد.

تغییر یافته در نسخه‌ی 3.1: پارامتر exit افزوده شد.

تغییر یافته در نسخه‌ی 3.2: پارامترهای verbosity، failfast، catchbreak، buffer و warnings افزوده شدند.

تغییر یافته در نسخه‌ی 3.4: پارامتر defaultTest تغییر کرد تا یک پیمایش‌پذیر از نام آزمون‌ها را نیز بپذیرد.

پروتکل load_tests

اضافه شده در نسخه‌ی 3.2.

ماژول‌ها یا بسته‌ها می‌توانند با پیاده‌سازی تابعی به نام load_tests، نحوه بارگذاری آزمون‌ها از آن‌ها را در حین اجراهای عادی آزمون یا کشف آزمون سفارشی کنند.

اگر یک ماژول آزمون load_tests را تعریف کند، توسط TestLoader.loadTestsFromModule() با آرگومان‌های زیر فراخوانی می‌شود:

load_tests(loader, standard_tests, pattern)

که در آن pattern بدون تغییر از loadTestsFromModule ارسال می‌شود. مقدار پیش‌فرض آن None است.

باید یک TestSuite برگرداند.

loader نمونه‌ای از TestLoader است که بارگذاری را انجام می‌دهد. standard_tests آزمون‌هایی هستند که به‌طور پیش‌فرض از ماژول بارگذاری می‌شوند. رایج است که ماژول‌های آزمون فقط بخواهند آزمون‌هایی را به مجموعه استاندارد آزمون‌ها اضافه یا از آن حذف کنند. آرگومان سوم هنگام بارگذاری بسته‌ها به‌عنوان بخشی از کشف آزمون استفاده می‌شود.

یک تابع معمول load_tests که آزمون‌ها را از مجموعه مشخصی از کلاس‌های TestCase بارگذاری می‌کند، ممکن است به شکل زیر باشد:

test_cases = (TestCase1, TestCase2, TestCase3)

def load_tests(loader, tests, pattern):
    suite = TestSuite()
    for test_class in test_cases:
        tests = loader.loadTestsFromTestCase(test_class)
        suite.addTests(tests)
    return suite

اگر کشف در پوشه‌ای حاوی یک بسته آغاز شود، چه از خط فرمان و چه با فراخوانی TestLoader.discover()، پرونده __init__.py بسته از نظر load_tests بررسی می‌شود. اگر آن تابع وجود نداشته باشد، کشف به‌صورت بازگشتی وارد بسته می‌شود، گویی که صرفاً پوشه‌ای دیگر است. در غیر این صورت، کشف آزمون‌های بسته به load_tests واگذار می‌شود که با آرگومان‌های زیر فراخوانی می‌شود:

load_tests(loader, standard_tests, pattern)

این باید یک TestSuite را برگرداند که تمام آزمون‌های بسته را نشان می‌دهد. (standard_tests فقط شامل آزمون‌های جمع‌آوری‌شده از __init__.py خواهد بود.)

از آنجا که الگو به load_tests پاس داده می‌شود، بسته مختار است که کشف آزمون را ادامه دهد (و احتمالاً آن را تغییر دهد). یک تابع load_tests با عملکرد «هیچ‌کاری نکردن» برای یک بسته آزمون به شکل زیر خواهد بود:

def load_tests(loader, standard_tests, pattern):
    # top level directory cached on loader instance
    this_dir = os.path.dirname(__file__)
    package_tests = loader.discover(start_dir=this_dir, pattern=pattern)
    standard_tests.addTests(package_tests)
    return standard_tests

تغییر یافته در نسخه‌ی 3.5: کشف دیگر نام بسته‌ها را برای تطبیق با pattern بررسی نمی‌کند، زیرا تطبیق نام بسته‌ها با الگوی پیش‌فرض غیرممکن است.

ثابت‌های آزمایشی کلاس و ماژول (fixtures)

ثابت‌های آزمایشی سطح کلاس و ماژول (fixtures) در TestSuite پیاده‌سازی شده‌اند. هنگامی که بدنه آزمون با آزمونی از یک کلاس جدید مواجه می‌شود، tearDownClass() از کلاس پیشین (در صورت وجود) فراخوانی می‌شود و پس از آن setUpClass() از کلاس جدید فراخوانی می‌شود.

به‌طور مشابه، اگر یک آزمون از ماژولی متفاوت از آزمون قبلی باشد، tearDownModule از ماژول قبلی اجرا می‌شود و سپس setUpModule از ماژول جدید اجرا می‌شود.

پس از اجرای همه‌ی آزمون‌ها، در نهایت tearDownClass و tearDownModule اجرا می‌شوند.

توجه داشته باشید که ثابت‌های آزمایشی مشترک (shared fixtures) با قابلیت‌های [بالقوه] مانند موازی‌سازی آزمون‌ها سازگاری خوبی ندارند و جداسازی آزمون‌ها را نقض می‌کنند. باید با احتیاط از آن‌ها استفاده شود.

ترتیب پیش‌فرض آزمون‌های ایجادشده توسط بارگذارهای آزمون unittest، گروه‌بندی همه آزمون‌های مربوط به ماژول‌ها و کلاس‌های یکسان در کنار یکدیگر است. این موضوع باعث می‌شود setUpClass / setUpModule (و غیره) دقیقاً یک‌بار برای هر کلاس و ماژول فراخوانی شوند. اگر ترتیب را تصادفی کنید، به‌طوری که آزمون‌هایی از ماژول‌ها و کلاس‌های مختلف مجاور یکدیگر قرار بگیرند، ممکن است این توابع ثابت آزمایشی (fixture) مشترک چندین بار در یک اجرای آزمون فراخوانی شوند.

ثابت‌های آزمایشی مشترک برای کار با مجموعه‌های آزمونی که ترتیب غیراستاندارد دارند در نظر گرفته نشده‌اند. BaseTestSuite همچنان برای چارچوب‌هایی که نمی‌خواهند از ثابت‌های آزمایشی مشترک پشتیبانی کنند وجود دارد.

اگر در حین یکی از توابع ثابت آزمایشی (fixture) مشترک، استثنایی پرتاب شود، آزمون به‌عنوان خطا گزارش می‌شود. از آنجا که هیچ نمونه آزمون متناظری وجود ندارد، یک شیء _ErrorHolder (که همان رابط TestCase را دارد) برای نمایش خطا ایجاد می‌شود. اگر صرفاً از اجراکننده‌ی آزمون استاندارد unittest استفاده می‌کنید، این جزئیات اهمیتی ندارد، اما اگر نویسنده یک چارچوب هستید، ممکن است مرتبط باشد.

setUpClass و tearDownClass

این‌ها باید به‌صورت متدهای کلاس پیاده‌سازی شوند:

import unittest

class Test(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls._connection = createExpensiveConnectionObject()

    @classmethod
    def tearDownClass(cls):
        cls._connection.destroy()

اگر می‌خواهید setUpClass و tearDownClass در کلاس‌های پایه فراخوانی شوند، باید خودتان آن‌ها را فراخوانی کنید. پیاده‌سازی‌ها در TestCase خالی هستند.

اگر یک استثنا در حین setUpClass پرتاب شود، آنگاه آزمون‌های درون کلاس اجرا نمی‌شوند و tearDownClass نیز اجرا نمی‌شود. برای کلاس‌های ردشده، setUpClass یا tearDownClass اجرا نخواهد شد. اگر استثنا یک استثنای SkipTest باشد، کلاس به‌جای خطا به‌عنوان ردشده گزارش می‌شود.

setUpModule و tearDownModule

این موارد باید به‌صورت تابع پیاده‌سازی شوند:

def setUpModule():
    createConnection()

def tearDownModule():
    closeConnection()

اگر در setUpModule استثنایی پرتاب شود، هیچ‌کدام از آزمون‌های ماژول اجرا نخواهند شد و tearDownModule اجرا نخواهد شد. اگر استثنا یک استثنای SkipTest باشد، ماژول به‌جای آن‌که به‌عنوان خطا گزارش شود، به‌عنوان ردشده گزارش خواهد شد.

برای افزودن کد پاک‌سازی که باید حتی در صورت وقوع استثنا نیز اجرا شود، از addModuleCleanup استفاده کنید:

unittest.addModuleCleanup(function, /, *args, **kwargs)

یک تابع برای فراخوانی پس از tearDownModule() اضافه کنید تا منابع استفاده‌شده در طول کلاس آزمون پاک‌سازی شوند. توابع به ترتیب معکوس نسبت به ترتیبی که اضافه شده‌اند فراخوانی خواهند شد (LIFO). این توابع با هر آرگومان و آرگومان کلیدواژه‌ای که هنگام اضافه شدن آن‌ها به addModuleCleanup() ارسال شده باشد، فراخوانی می‌شوند.

اگر setUpModule() با شکست مواجه شود، به این معنا که tearDownModule() فراخوانی نمی‌شود، هر تابع پاک‌سازی که اضافه‌شده باشد همچنان فراخوانی خواهد شد.

اضافه شده در نسخه‌ی 3.8.

unittest.enterModuleContext(cm)

وارد context manager ارائه‌شده می‌شود. در صورت موفقیت، متد __exit__() آن را نیز به‌عنوان تابع پاک‌سازی از طریق addModuleCleanup() اضافه می‌کند و نتیجه‌ی متد __enter__() را برمی‌گرداند.

اضافه شده در نسخه‌ی 3.11.

unittest.doModuleCleanups()

این تابع بدون شرط پس از tearDownModule()، یا پس از setUpModule() در صورتی فراخوانی می‌شود که setUpModule() استثنایی را پرتاب کند.

این تابع مسئول فراخوانی همه‌ی توابع پاک‌سازی افزوده‌شده توسط addModuleCleanup() است. اگر نیاز دارید توابع پاک‌سازی پیش از tearDownModule() فراخوانی شوند، می‌توانید خودتان doModuleCleanups() را فراخوانی کنید.

doModuleCleanups() متدها را یکی‌یکی از پشته‌ی توابع پاک‌سازی برمی‌دارد، بنابراین می‌توان آن را در هر زمانی فراخوانی کرد.

اضافه شده در نسخه‌ی 3.8.

مدیریت سیگنال

اضافه شده در نسخه‌ی 3.2.

گزینه‌ی خط فرمان -c/--catch برای unittest، به‌همراه پارامتر catchbreak برای unittest.main()، مدیریت مناسب‌تری برای control-C در طول اجرای آزمون فراهم می‌کنند. با فعال بودن رفتار catch break، control-C اجازه می‌دهد آزمون در حال اجرا کامل شود و سپس اجرای آزمون پایان می‌یابد و تمام نتایج تا آن لحظه را گزارش می‌دهد. دومین control-c، KeyboardInterrupt را به روش معمول پرتاب می‌کند.

هندلر سیگنال رسیدگی به control-c تلاش می‌کند با کد یا آزمون‌هایی که هندلر signal.SIGINT خودشان را نصب می‌کنند سازگار باقی بماند. اگر هندلر unittest فراخوانی شود اما هندلر signal.SIGINT نصب‌شده نباشد، یعنی سیستم تحت آزمون آن را جایگزین کرده و به آن واگذار کرده باشد، آنگاه هندلر پیش‌فرض را فراخوانی می‌کند. این معمولاً رفتار مورد انتظار کدی خواهد بود که یک مدیر نصب‌شده را جایگزین می‌کند و به آن واگذار می‌نماید. برای آزمون‌های تکی که نیاز دارند رسیدگی unittest به control-c غیرفعال شود، می‌توان از دکوراتور removeHandler() استفاده کرد.

چند تابع کاربردی برای نویسندگان چارچوب وجود دارد تا قابلیت مدیریت control-c را در چارچوب‌های آزمون فعال کنند.

unittest.installHandler()

هندلری control-c را نصب کنید. هنگامی که signal.SIGINT دریافت می‌شود (معمولاً در پاسخ به فشرده‌شدن control-c توسط کاربر)، برای همه‌ی نتایج ثبت‌شده، stop() فراخوانی می‌شود.

unittest.registerResult(result)

یک شیء TestResult را برای مدیریت control-c ثبت می‌کند. ثبت یک نتیجه، ارجاع ضعیفی به آن ذخیره می‌کند، بنابراین از زباله‌روبی شدن نتیجه جلوگیری نمی‌کند.

ثبت یک شیء TestResult در صورتی که مدیریت control-c فعال نباشد، هیچ عارضه‌ی جانبی ندارد؛ بنابراین چارچوب‌های آزمون می‌توانند به‌صورت غیرمشروط تمام نتایجی را که ایجاد می‌کنند، مستقل از فعال بودن یا نبودن مدیریت، ثبت کنند.

unittest.removeResult(result)

حذف یک نتیجه ثبت‌شده. پس از حذف یک نتیجه، stop() دیگر روی آن شیء نتیجه در پاسخ به control-c فراخوانی نخواهد شد.

unittest.removeHandler(function=None)

هنگامی که این تابع بدون آرگومان فراخوانی شود، هندلر control-c را در صورت نصب‌شده بودن حذف می‌کند. این تابع همچنین می‌تواند به‌عنوان دکوراتور آزمون برای حذف موقت هندلر در حین اجرای آزمون استفاده شود:

@unittest.removeHandler
def test_signal_handling(self):
    ...