如何按自定义顺序执行telenium测试用例并解决端口占用报错
问题定位与解决方案
问题根因
端口占用报错
报错OSError: [Errno 98] address already in use的核心原因是:
- 你通过
os.system('python server.py')启动的服务是独立的子进程,包裹它的daemon线程退出时不会自动销毁该子进程 second_test执行后服务进程一直在后台运行,占用5000端口,third_test再次调用enable_server()启动服务时,端口冲突直接报错
测试用例顺序不匹配
Telenium的测试用例基于Python unittest框架实现,框架默认会按照测试方法名的字典序排序执行,不会按你编写代码的顺序执行。
解决方案
1. 解决测试用例顺序问题
统一修改测试方法命名格式为test_序号_业务标识,框架会自动按序号从小到大的顺序执行,示例如下:
# 原命名 first_test 改为 test_01_first # 原命名 second_test 改为 test_02_second # 原命名 third_test 改为 test_03_third
2. 解决端口占用问题
重构服务启停逻辑,改用subprocess管理服务进程,用完主动销毁释放端口,根据你的使用场景二选一即可:
场景A:所有测试用例复用同一个服务实例(推荐,性能更高)
通过setUpClass在整个测试类初始化时启动一次服务,所有用例执行完成后通过tearDownClass销毁服务:
首先重构服务启停工具代码:
import subprocess server_process = None def enable_server(): global server_process # 启动服务,返回进程对象方便后续管理 server_process = subprocess.Popen( ["python", "server.py"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL ) def disable_server(): global server_process if server_process: # 杀死服务进程,释放端口 server_process.kill() server_process.wait() server_process = None
修改测试类代码:
class UITestCase(TeleniumTestCase): # 注意去掉main.py前的多余空格,避免执行报错 cmd_entrypoint = ["main.py"] @classmethod def setUpClass(cls): super().setUpClass() # 整个测试类启动时只启一次服务 enable_server() @classmethod def tearDownClass(cls): # 所有用例执行完成后关闭服务 disable_server() super().tearDownClass() def test_01_first(self): """code to test""" def test_02_second(self): """code to test""" def test_03_third(self): """code to test"""
场景B:每个测试用例都需要全新的服务实例
通过setUp和tearDown在每个用例执行前后启停服务:
class UITestCase(TeleniumTestCase): cmd_entrypoint = ["main.py"] def setUp(self): super().setUp() # 每个用例执行前启动服务 enable_server() def tearDown(self): # 每个用例执行后关闭服务释放端口 disable_server() super().tearDown() def test_01_first(self): """code to test""" def test_02_second(self): """code to test""" def test_03_third(self): """code to test"""
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

