首頁 >後端開發 >Python教學 >測試自動化中的 Python 類型參數化裝飾器

測試自動化中的 Python 類型參數化裝飾器

Patricia Arquette
Patricia Arquette原創
2025-01-22 20:12:14544瀏覽

Python Typed Parameterized Decorators in Test Automation

Python 的裝飾器機制與現代類型提示功能相結合,顯著提高了測試自動化。 這種強大的組合利用了 Python 的靈活性和 typing 模組的類型安全性,產生了更可維護、可讀和健壯的測試套件。本文探討了先進技術,並著重於它們在測試自動化框架中的應用。

利用 typing 模組的增強功能

typing模組進行了重大改進:

  • PEP 585: 對標準集合中泛型類型的本機支援最大限度地減少了對常見類型的 typing 模組的依賴。
  • PEP 604: | 運算子簡化了 Union 型態註解。
  • PEP 647: TypeAlias 澄清型別別名定義。
  • PEP 649:延遲註解評估可加快大型專案的啟動速度。

建造型別參數化裝飾器

以下是如何使用這些更新的輸入功能來建立裝飾器:

<code class="language-python">from typing import Protocol, TypeVar, Generic, Callable, Any
from functools import wraps

# TypeVar for generic typing
T = TypeVar('T')

# Protocol for defining function structure
class TestProtocol(Protocol):
    def __call__(self, *args: Any, **kwargs: Any) -> Any:
        ...

def generic_decorator(param: str) -> Callable[[Callable[..., T]], Callable[..., T]]:
    """
    Generic decorator for functions returning type T.

    Args:
        param:  A string parameter.

    Returns:
        A callable wrapping the original function.
    """
    def decorator(func: Callable[..., T]) -> Callable[..., T]:
        @wraps(func)  # Preserves original function metadata
        def wrapper(*args: Any, **kwargs: Any) -> T:
            print(f"Decorator with param: {param}")
            return func(*args, **kwargs)
        return wrapper
    return decorator

@generic_decorator("test_param")
def test_function(x: int) -> int:
    """Returns input multiplied by 2."""
    return x * 2</code>

此裝飾器使用 Protocol 定義測試函數的結構,以提高測試框架中不同函數簽名的彈性。

將裝飾器應用於測試自動化

讓我們看看這些裝飾器如何增強測試自動化:

1。使用 Literal

進行特定於平台的測試
<code class="language-python">from typing import Literal, Callable, Any
import sys

def run_only_on(platform: Literal["linux", "darwin", "win32"]) -> Callable:
    """
    Runs a test only on the specified platform.

    Args:
        platform: Target platform.

    Returns:
        A callable wrapping the test function.
    """
    def decorator(func: Callable) -> Callable:
        @wraps(func)
        def wrapper(*args: Any, **kwargs: Any) -> Any:
            if sys.platform == platform:
                return func(*args, **kwargs)
            print(f"Skipping test on platform: {sys.platform}")
            return None
        return wrapper
    return decorator

@run_only_on("linux")
def test_linux_feature() -> None:
    """Linux-specific test."""
    pass</code>

Literal 確保類型檢查器識別有效的 platform 值,明確哪些測試在哪些平台上運行——這對於跨平台測試至關重要。

2。帶有線程的超時裝飾器

<code class="language-python">from typing import Callable, Any, Optional
import threading
import time
from concurrent.futures import ThreadPoolExecutor, TimeoutError

def timeout(seconds: int) -> Callable:
    """
    Enforces a timeout on test functions.

    Args:
        seconds: Maximum execution time.

    Returns:
        A callable wrapping the function with timeout logic.
    """
    def decorator(func: Callable) -> Callable:
        @wraps(func)
        def wrapper(*args: Any, **kwargs: Any) -> Optional[Any]:
            with ThreadPoolExecutor(max_workers=1) as executor:
                future = executor.submit(func, *args, **kwargs)
                try:
                    return future.result(timeout=seconds)
                except TimeoutError:
                    print(f"Function {func.__name__} timed out after {seconds} seconds")
                    return None
        return wrapper
    return decorator

@timeout(5)
def test_long_running_operation() -> None:
    """Test that times out if it takes too long."""
    time.sleep(10)  # Triggers timeout</code>

這使用執行緒來實現可靠的超時功能,這在控制測試執行時間時至關重要。

3。聯合型式的重試機制

<code class="language-python">from typing import Callable, Any, Union, Type, Tuple, Optional
import time

def retry_on_exception(
    exceptions: Union[Type[Exception], Tuple[Type[Exception], ...]], 
    attempts: int = 3,
    delay: float = 1.0
) -> Callable:
    """
    Retries a function on specified exceptions.

    Args:
        exceptions: Exception type(s) to catch.
        attempts: Maximum retry attempts.
        delay: Delay between attempts.

    Returns:
        A callable wrapping the function with retry logic.
    """
    def decorator(func: Callable) -> Callable:
        @wraps(func)
        def wrapper(*args: Any, **kwargs: Any) -> Any:
            last_exception: Optional[Exception] = None
            for attempt in range(attempts):
                try:
                    return func(*args, **kwargs)
                except exceptions as e:
                    last_exception = e
                    print(f"Attempt {attempt + 1} failed with {type(e).__name__}: {str(e)}")
                    time.sleep(delay)
            if last_exception:
                raise last_exception
        return wrapper
    return decorator

@retry_on_exception(Exception, attempts=5)
def test_network_connection() -> None:
    """Test network connection with retry logic."""
    pass</code>

這個改進的版本使用全面的類型提示、強大的異常處理和可配置的重試延遲。 Union 類型允許靈活地指定異常類型。

結論

將 Python 的高級類型功能整合到裝飾器中可以提高類型安全性和程式碼可讀性,從而顯著增強測試自動化框架。 顯式類型定義確保測試在正確的條件下運行,並具有適當的錯誤處理和效能限制。這會帶來更健壯、可維護和高效的測試,在大型、分散式或多平台測試環境中尤其有價值。

以上是測試自動化中的 Python 類型參數化裝飾器的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn