استفاده از Doctest در پایتون: راهنمای جامع

استفاده از Doctest در پایتون: راهنمای جامع

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

چرا از Doctest استفاده کنیم؟

Doctest چندین مزیت کلیدی دارد:

  • سادگی: نوشتن تست‌ها با استفاده از Doctest بسیار ساده است. شما نیازی به یادگیری یک فریم‌ورک تست پیچیده ندارید.
  • مستندسازی و تست در یکجا: تست‌ها به عنوان بخشی از docstringها نوشته می‌شوند، بنابراین هم به عنوان مستندات و هم به عنوان تست عمل می‌کنند. این امر باعث می‌شود کد شما بهتر مستند شده و قابل فهم‌تر باشد.
  • نگهداری آسان: تست‌ها در کنار کد مربوطه قرار دارند، بنابراین هنگام تغییر کد، به راحتی می‌توانید تست‌ها را نیز به‌روزرسانی کنید.
  • قابلیت اجرا از طریق خط فرمان: Doctest را می‌توان به راحتی از طریق خط فرمان اجرا کرد، که این امر آن را برای تست‌های خودکار و CI/CD مناسب می‌سازد.

نحوه استفاده از Doctest

برای استفاده از Doctest، باید تست‌های خود را در docstringهای توابع و کلاس‌های خود بنویسید. فرمت تست‌ها به این صورت است:

>>> function_name(arguments)
expected_output

در اینجا:

  • >>> نشان‌دهنده خط ورودی به پایتون است.
  • function_name(arguments) توابعی است که می‌خواهید تست کنید.
  • expected_output خروجی مورد انتظار از تابع است.

مثال ساده

بیایید یک مثال ساده را در نظر بگیریم:

def add(a, b):
  """
  این تابع دو عدد را با هم جمع می‌کند.

  >>> add(2, 3)
  5
  >>> add(-1, 1)
  0
  >>> add(0, 0)
  0
  """
  return a + b

در این مثال، docstring تابع add شامل سه تست است. هر تست یک خط ورودی (add(2, 3)) و خروجی مورد انتظار (5) دارد. Doctest این تست‌ها را اجرا می‌کند و بررسی می‌کند که آیا خروجی واقعی با خروجی مورد انتظار مطابقت دارد یا خیر.

اجرای Doctest

برای اجرای Doctest، می‌توانید از یکی از روش‌های زیر استفاده کنید:

  • از طریق خط فرمان: با استفاده از دستور python -m doctest your_module.py
  • از داخل کد پایتون: با استفاده از ماژول doctest

مثال اجرای Doctest از داخل کد پایتون:

import doctest

doctest.testmod()

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

نکات پیشرفته Doctest

Doctest قابلیت‌های پیشرفته‌تری نیز دارد که می‌توانند به شما در نوشتن تست‌های پیچیده‌تر کمک کنند.

استفاده از Ellipsis (…)

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

def greet(name):
  """
  این تابع یک پیام خوشامدگویی را برمی‌گرداند.

  >>> greet("Alice")
  'Hello, Alice!...'
  """
  return f"Hello, {name}! Welcome to the world of Doctest."

در این مثال، ... نشان می‌دهد که بقیه خروجی مهم نیست و Doctest فقط بررسی می‌کند که قسمت ابتدایی خروجی صحیح باشد.

استفاده از Flags

Doctest از flags برای کنترل نحوه اجرای تست‌ها استفاده می‌کند. برخی از flags رایج عبارتند از:

  • -v (verbose): نمایش اطلاعات دقیق‌تری در مورد تست‌ها.
  • -x (exit on first failure): خروج از برنامه پس از اولین شکست تست.
  • -i (ignore whitespace): نادیده گرفتن فاصله‌های خالی در خروجی.
  • -f (file): مشخص کردن فایل حاوی تست‌ها.

مثال استفاده از flag verbose:

python -m doctest -v your_module.py

تست کلاس‌ها و متدها

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

class Calculator:
  """
  یک کلاس ساده برای انجام عملیات ریاضی.

  >>> calculator = Calculator()
  >>> calculator.add(2, 3)
  5
  >>> calculator.subtract(5, 2)
  3
  """
  def add(self, a, b):
    return a + b

  def subtract(self, a, b):
    return a - b

در این مثال، docstring کلاس Calculator شامل تست‌هایی برای ایجاد یک شیء از کلاس و فراخوانی متدهای add و subtract است.

استفاده از setUp و tearDown

در برخی موارد، ممکن است نیاز داشته باشید قبل از اجرای هر تست، یک سری عملیات را انجام دهید (setUp) و پس از اجرای هر تست، یک سری عملیات را انجام دهید (tearDown). Doctest به طور مستقیم از setUp و tearDown پشتیبانی نمی‌کند، اما می‌توانید از توابع helper برای شبیه‌سازی این رفتار استفاده کنید.

def setup():
  """
  این تابع قبل از اجرای هر تست اجرا می‌شود.
  """
  global data
  data = []

def teardown():
  """
  این تابع بعد از اجرای هر تست اجرا می‌شود.
  """
  global data
  data = None

def append_to_list(value):
  """
  این تابع یک مقدار را به لیست اضافه می‌کند.

  >>> setup()
  >>> append_to_list(1)
  >>> data
  [1]
  >>> teardown()
  """
  global data
  data.append(value)

در این مثال، توابع setup و teardown قبل و بعد از اجرای تست append_to_list اجرا می‌شوند.

محدودیت‌های Doctest

Doctest با وجود مزایای فراوان، محدودیت‌هایی نیز دارد:

  • پیچیدگی: برای تست‌های بسیار پیچیده، Doctest ممکن است مناسب نباشد.
  • عدم انعطاف‌پذیری: Doctest انعطاف‌پذیری کمتری نسبت به فریم‌ورک‌های تست پیشرفته‌تر دارد.
  • خطاها: خطاهای موجود در docstringها ممکن است به سختی تشخیص داده شوند.

نتیجه‌گیری

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

بدون دیدگاه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *