Automate Test Logging in Python with a Simple Decorator
This guide shows how to replace repetitive print or logging calls in automated test suites by creating a reusable @log_test decorator that automatically records start, success, failure, timestamps, and execution time for each test function.
Why Automatic Logging Is Needed
When a test suite contains many test cases, each test often needs to log a start message, a success message, or a failure message, together with a timestamp, test name, and execution duration. Hard‑coding these log statements makes format changes cumbersome and mixes logging with test logic.
Core Idea: Wrap Test Functions with a Decorator
A Python decorator can inject logging before and after a test runs without modifying the test’s source code.
import functools
import logging
import time
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
datefmt="%Y-%m-%d %H:%M:%S"
)
def log_test(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
logger = logging.getLogger(__name__)
logger.info(f"▶ 开始执行测试: {func.__name__}")
start_time = time.time()
try:
result = func(*args, **kwargs)
elapsed = time.time() - start_time
logger.info(f"✅ 测试通过: {func.__name__} | 耗时: {elapsed:.2f}s")
return result
except Exception as e:
elapsed = time.time() - start_time
logger.error(f"❌ 测试失败: {func.__name__} | 耗时: {elapsed:.2f}s | 错误: {e}")
raise
return wrapperUsage Example
@log_test
def test_user_login_success():
assert login("alice", "123456") is True
@log_test
def test_create_order():
order_id = create_order(user_id=1001, items=["A", "B"])
assert order_id > 0
@log_test
def test_api_timeout_should_fail():
response = call_slow_api(timeout=1)
assert response.status_code == 200 # expected to timeoutSample Output
2026-01-24 21:40:01 - INFO - ▶ 开始执行测试: test_user_login_success
2026-01-24 21:40:01 - INFO - ✅ 测试通过: test_user_login_success | 耗时: 0.05s
2026-01-24 21:40:01 - INFO - ▶ 开始执行测试: test_create_order
2026-01-24 21:40:02 - INFO - ✅ 测试通过: test_create_order | 耗时: 0.82s
2026-01-24 21:40:02 - INFO - ▶ 开始执行测试: test_api_timeout_should_fail
2026-01-24 21:40:05 - ERROR - ❌ 测试失败: test_api_timeout_should_fail | 耗时: 3.01s | 错误: TimeoutError: API call timed outAdvanced Tips
Make the decorator configurable, e.g., @log_test(level="DEBUG"), to allow custom log levels or formats.
It works seamlessly with pytest; the decorator does not interfere with pytest’s assertion handling or reporting.
To write logs to a file, add filename="test.log" to logging.basicConfig.
Capture test arguments for richer context:
logger.info(f"▶ 执行测试: {func.__name__} (参数: {kwargs})").
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
