首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Watchdog + Pytest + Allure :文件变化自动触发测试及实时报告生成

Watchdog + Pytest + Allure :文件变化自动触发测试及实时报告生成

作者头像
用户12558604
发布2026-06-17 17:55:23
发布2026-06-17 17:55:23
70
举报

Watchdog 是 Python 生态中一款轻量、跨平台的文件系统变化监控库,支持实时检测文件 / 目录的创建、修改、删除、移动等操作,将 watchdogpytestallure 结合,可以实现测试文件变化时自动触发测试并生成最新报告的自动化工作流,尤其适合开发过程中实时验证代码改动对测试的影响。

  • • 在开发或调试时,当测试文件(test_*.py)或被测试代码(如 src/ 下的业务逻辑)发生修改时,自动重新执行 pytest 测试,并生成 / 更新 allure 报告。
  • • 减少手动执行 pytest --alluredir=reportallure serve report 的重复操作,实时查看测试结果
  • 以下是示例代码
代码语言:javascript
复制
import os
import time
import subprocess
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

class TestAutoRunHandler(FileSystemEventHandler):
    def __init__(self, test_dir, report_dir="allure_reports", debounce_seconds=1):
        self.test_dir = os.path.abspath(test_dir)  # 监控的测试目录
        self.report_dir = report_dir  # allure报告输出目录
        self.debounce_seconds = debounce_seconds  # 防抖时间(避免短时间内多次触发)
        self.last_trigger_time = 0# 上次触发时间

    def _should_trigger(self):
        """防抖逻辑:两次触发间隔小于设定值则忽略"""
        current_time = time.time()
        if current_time - self.last_trigger_time < self.debounce_seconds:
            return False
        self.last_trigger_time = current_time
        return True

    def _run_tests(self):
        """执行pytest并生成allure报告"""
        print("\n" + "="*50)
        print(f"[{time.strftime('%H:%M:%S')}] 检测到文件变化,开始执行测试...")
        print("="*50)

        # 1. 清理旧报告(可选,根据需求决定是否保留历史)
        if os.path.exists(self.report_dir):
            subprocess.run(f"rm -rf {self.report_dir}", shell=True, check=True)

        # 2. 执行pytest,指定allure报告目录
        pytest_cmd = (
            f"pytest {self.test_dir} "
            f"--alluredir={self.report_dir} "
            "-v  # 显示详细测试日志"
        )
        try:
            # 运行pytest命令,输出实时打印到控制台
            subprocess.run(pytest_cmd, shell=True, check=True)
            print("\n测试执行完成,正在生成allure报告...")

            # 3. 自动打开allure报告(使用allure serve,会启动临时服务器)
            # 若希望生成静态文件,可替换为 `allure generate`
            allure_cmd = f"allure serve {self.report_dir} --port 8080"
            subprocess.Popen(allure_cmd, shell=True)  # 非阻塞运行,避免占用主线程
            print(f"报告已启动:http://localhost:8080(按 Ctrl+C 停止监控)")
        except subprocess.CalledProcessError as e:
            print(f"\n测试执行失败:{e}")

    def on_modified(self, event):
        """文件/目录被修改时触发"""
        # 过滤条件:仅监控测试目录下的.py文件(可根据需求调整)
        if (
            not event.is_directory 
            and event.src_path.startswith(self.test_dir) 
            and event.src_path.endswith(".py")
            andself._should_trigger()
        ):
            self._run_tests()

    def on_created(self, event):
        """新建文件/目录时触发(如新增测试用例)"""
        if (
            not event.is_directory 
            and event.src_path.startswith(self.test_dir) 
            and event.src_path.endswith(".py")
            andself._should_trigger()
        ):
            self._run_tests()

    def on_deleted(self, event):
        """删除文件/目录时触发(如删除测试用例)"""
        if (
            not event.is_directory 
            and event.src_path.startswith(self.test_dir) 
            and event.src_path.endswith(".py")
            andself._should_trigger()
        ):
            self._run_tests()

if __name__ == "__main__":
    # 配置:监控的测试目录(如./tests)、报告目录、防抖时间
    TEST_DIR = "./tests"# 替换为你的测试目录
    REPORT_DIR = "allure_reports"
    DEBOUNCE_SECONDS = 1# 1秒内多次修改只触发一次

    # 初始化处理器和观察者
    event_handler = TestAutoRunHandler(
        test_dir=TEST_DIR,
        report_dir=REPORT_DIR,
        debounce_seconds=DEBOUNCE_SECONDS
    )
    observer = Observer(daemon=True)
    # 递归监控测试目录(包括子目录)
    observer.schedule(event_handler, path=TEST_DIR, recursive=True)

    # 启动监控
    observer.start()
    print(f"开始监控目录:{TEST_DIR}")
    print(f"当 .py 文件发生修改/创建/删除时,将自动执行 pytest 并生成 allure 报告")
    print("按 Ctrl+C 停止监控...")

    # 保持主进程运行
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
        print("\n监控已停止")
    observer.join()
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-09-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程拾光 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档