pytest自动化测试 – 我对测试用例超时处理的一点看法

 

 

1 pytest自动化测试 - 我对测试用例超时处理的一点看法

1.1 背景

  用例在执行过程中,可能由于网络等待,或者等待一些特殊的文件,而又由于一些异常,导致这些条件一直不能满足,用例卡死,这种情况在自动化测试中是不允许的,会浪费大量的时间,影响测试任务的进度,甚至导致版本发布周期的延长。
  为了给每个用例都设置上超时时间,有以下几种方法:

1.2 方法1:给每个用例添加@pytest.mark.timeout修饰器

@pytest.mark.timeout在Windows下并不能很好的工作,1 个用例出现超时,整个测试任务就中断了,非常扯淡!

import pytest import time  @pytest.mark.timeout(5) def test_case1():     time.sleep(2)     assert True  @pytest.mark.timeout(5) def test_case2():     time.sleep(6)  # 此用例会超时     assert True  def test_case3():     print("用例3:Windows下不会执行")     assert 3 == 3

1.3 方法2:使用钩子函数给每个用例添加一个timeout修饰器

  然而,下面这个做法,在Windows下并没有什么卵用!,超时的那个用例也执行成功了!

import pytest import time  def pytest_collection_modifyitems(session, config, items):     for item in items:         item.add_marker(pytest.mark.timeout(3))  def setup_function():     print()  def test_case3():     print("用例3:开始")     time.sleep(3)     assert True     print("用例3:结束")  def test_case4():     print("用例4:开始")     time.sleep(5)  # 此用例会超时,但Windows不超时,神奇!     assert True     print("用例4:结束")  def test_case5():     print("用例5: 开始")     assert 3 == 3     print("用例5: 结束")

Windows下的执行结果:

============================= test session starts ============================= platform win32 -- Python 3.13.1, pytest-8.3.4, pluggy-1.5.0 rootdir: D:TYYSOFTStudyPythonpytest configfile: pytest.ini plugins: check-2.4.1, html-4.1.1, metadata-3.1.1, timeout-2.3.1, xdist-3.6.1 collected 3 items  test_timeout_004.py  用例3:开始 用例3:结束 . 用例4:开始 用例4:结束 . 用例5: 开始 用例5: 结束 .  -- Generated html report: file:///D:/TYYSOFT/Study/Python/pytest/report.html -- ============================== 3 passed in 8.03s ==============================

其他所谓的使用timeout标记的超时处理在Windows下都没有什么卵用!

1.4 方法3:介绍一个自己写的使用线程处理用例超时的方法

  用例的超时,其实主要是监控每条任务的超时情况,通过创建1个基础函数base_func这个函数每次调用时都创建1个线程,并给线程设置超时时间,用例中的执行语句都通过这个线程函数base_func来执行,base_func中对超时任务会设置失败。

import pytest import threading import time  # 核心函数:该函数创建1个线程,并执行给定的task,超时后会把用例设置为失败 def base_func(task, timeout=5):     thread = threading.Thread(target=task)     thread.start()     thread.join(timeout) #设置超时      if thread.is_alive():         print(f"::{task.__name__}: 语句执行超时...")         assert False  # 1个长时间任务 def long_time_task():     time.sleep(2)  # 模块发送消息的基础函数 def send_msg(msg):     print(msg)  # 预置条件 def setup_function():     print()     base_func(print("预置条件!"))  # 这是用例1 def test_timeout_001():     base_func(send_msg("用例1开始"))     base_func(long_time_task)     base_func(send_msg("用例1结束"))  def test_timeout_002():     base_func(send_msg("用例2开始"))     base_func(send_msg("用例2结束"))

输出结果:

============================= test session starts ============================= platform win32 -- Python 3.13.1, pytest-8.3.4, pluggy-1.5.0 rootdir: D:TYYSOFTStudyPythonpytest configfile: pytest.ini plugins: check-2.4.1, html-4.1.1, metadata-3.1.1, timeout-2.3.1, xdist-3.6.1 collected 2 items  test_timeout_002.py  预置条件! 用例1开始 ::long_time_task: 语句执行超时... F 预置条件! 用例2开始 用例2结束 .  ================================== FAILURES =================================== ______________________________ test_timeout_001 _______________________________      def test_timeout_001():         base_func(send_msg("用例1开始")) >       base_func(long_time_task)  test_timeout_002.py:31:  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _  task = <function long_time_task at 0x000001AAE4112DE0>, timeout = 5      def base_func(task, timeout=5):         thread = threading.Thread(target=task)         thread.start()         thread.join(timeout) #设置超时              if thread.is_alive():             print(f"::{task.__name__}: 语句执行超时...") >           assert False E           assert False  test_timeout_002.py:13: AssertionError -- Generated html report: file:///D:/TYYSOFT/Study/Python/pytest/report.html -- =========================== short test summary info =========================== FAILED test_timeout_002.py::test_timeout_001 - assert False ========================= 1 failed, 1 passed in 5.11s =========================

两个用例都执行了, 第2个用例并没有因为第1个用例超时而中止执行!

使用基础函数来包装测试执行语句的必要性, 因为实际在测试执行时, 每个语句都有可能执行超时,对其进行封装执行可以保证测试脚本的严谨性。


作者声明:本文用于记录和分享作者的学习心得,可能有部分文字或示例来自AI平台,如:豆包、DeepSeek(硅基流动)(注册链接)等,由于本人水平有限,难免存在表达错误,欢迎留言交流和指教!
Copyright © 2022~2025 All rights reserved.

发表评论

评论已关闭。

相关文章