如何在pytest的parametrize中传入函数名并精简测试用例代码
问题描述
当前异步测试脚本中,RegisterClientCabinMovementDetection(x)、RegisterClientOccupantInSeatDetection(x)等函数调用无法参数化,导致需要重复编写相似代码来测试不同检测类型,希望通过pytest的parametrize功能实现参数化,精简冗余代码。测试脚本如下:
import pytest # 假设UNDEFINED、INPROGRESS等常量已定义 # 假设driver_not_detected_in_seat等辅助函数已定义 @pytest.mark.asyncio @pytest.mark.parametrize('Qf, expected',[(UNDEFINED,"Invalid"),(INPROGRESS,"InProgress"),(NOTSPECIFIED,"NotOk"),(DATAOK,"DataOK")]) @pytest.mark.parametrize('Detection, expected_Detection',[(UNDEFINED,"Undefined"),(NOTDETECTED,"NotDetected"),(DETECTED,"Detected")]) @pytest.mark.parametrize('AvailabilityStatus,expected_availablity',[(UNDEFINED,"Undefined"),(NOTAVAILABLE,"NotAvailable"),(AVAILABLE,"Available"),(FAULT,"Fault"),(POSITIONNOTPRESENT,"PositionNotPresent")]) async def test_occupant_presence(snok,Qf,expected,Detection,expected_Detection,AvailabilityStatus,expected_availablity): """ Function to test occupant presence condition with driver available available scenario""" #setup occupant_presence_mock = snok.get_service("occupant_presence_hal") occupant_presence_service = snok.get_service("OccupantPresenceProvider") #Act await occupant_presence_service.RegisterClientCabinMovementDetection(0) #await occupant_presence_service.RegisterClientOccupantInSeatDetection(0) snok.async_sleep(1) seat_sensor_status =driver_not_detected_in_seat(occupant_presence_mock,Qf,Detection,AvailabilityStatus) await occupant_presence.set_DriverSeatCabinMovementDetection(seat_sensor_status) snok.async_sleep(1) response = await occupant_presence_service.get_DriverSeatCabinMovementDetection() #response = await occupant_presence_service.get_DriverSeatOccupantInSeatDetection() response_quality_factor=str(response.quality_factor) quality_factor_value = response_quality_factor.split('.') presence_detection_value= str(response.presence_detection).split('.') detector_status_value = str(response.detector_status).split('.') #assert assert quality_factor_value[1] == expected assert presence_detection_value[1] == expected_Detection assert detector_status_value[1] == expected_availablity
解决方案
完全可以通过pytest的parametrize功能实现函数调用的参数化,核心思路是把不同检测类型对应的注册函数、状态设置函数、结果获取函数作为参数传入测试用例,让同一套测试逻辑适配不同场景。
具体步骤:
- 新增检测类型的参数化配置:定义一个包含不同检测类型对应函数的参数列表,每个元素是一个元组,包含注册函数、设置函数、获取函数。
- 修改测试函数参数:在测试函数中接收这些函数参数,替换原有的硬编码函数调用。
- 保留原有参数化配置:原有的
Qf、Detection、AvailabilityStatus等参数化配置可以继续保留,和新增的函数参数化组合生成所有测试场景。
修改后的完整代码:
import pytest # 假设UNDEFINED、INPROGRESS等常量已定义 # 假设driver_not_detected_in_seat等辅助函数已定义 @pytest.mark.asyncio @pytest.mark.parametrize('Qf, expected',[(UNDEFINED,"Invalid"),(INPROGRESS,"InProgress"),(NOTSPECIFIED,"NotOk"),(DATAOK,"DataOK")]) @pytest.mark.parametrize('Detection, expected_Detection',[(UNDEFINED,"Undefined"),(NOTDETECTED,"NotDetected"),(DETECTED,"Detected")]) @pytest.mark.parametrize('AvailabilityStatus,expected_availablity',[(UNDEFINED,"Undefined"),(NOTAVAILABLE,"NotAvailable"),(AVAILABLE,"Available"),(FAULT,"Fault"),(POSITIONNOTPRESENT,"PositionNotPresent")]) @pytest.mark.parametrize('register_func, set_status_func, get_result_func', [ ( lambda service: service.RegisterClientCabinMovementDetection(0), lambda mock, status: mock.set_DriverSeatCabinMovementDetection(status), lambda service: service.get_DriverSeatCabinMovementDetection() ), ( lambda service: service.RegisterClientOccupantInSeatDetection(0), lambda mock, status: mock.set_DriverSeatOccupantInSeatDetection(status), lambda service: service.get_DriverSeatOccupantInSeatDetection() ) ]) async def test_occupant_presence(snok, Qf, expected, Detection, expected_Detection, AvailabilityStatus, expected_availablity, register_func, set_status_func, get_result_func): """ Function to test occupant presence condition with driver available available scenario""" # setup occupant_presence_mock = snok.get_service("occupant_presence_hal") occupant_presence_service = snok.get_service("OccupantPresenceProvider") # Act await register_func(occupant_presence_service) snok.async_sleep(1) seat_sensor_status = driver_not_detected_in_seat(occupant_presence_mock, Qf, Detection, AvailabilityStatus) await set_status_func(occupant_presence_mock, seat_sensor_status) snok.async_sleep(1) response = await get_result_func(occupant_presence_service) # 解析响应 response_quality_factor = str(response.quality_factor) quality_factor_value = response_quality_factor.split('.') presence_detection_value = str(response.presence_detection).split('.') detector_status_value = str(response.detector_status).split('.') # Assert assert quality_factor_value[1] == expected assert presence_detection_value[1] == expected_Detection assert detector_status_value[1] == expected_availablity
说明:
- 使用lambda表达式封装每个检测类型对应的函数调用,把函数作为参数传递给测试用例。
- 原有测试逻辑完全复用,无需重复编写多份代码,新增检测类型时只需在
parametrize的列表中添加对应的函数元组即可。 - pytest会自动组合所有参数化的维度,生成覆盖所有场景的测试用例。
内容的提问来源于stack exchange,提问作者SATHISH BABU
相关产品推荐
相关产品推荐

