



测试用例的设计通常由测试环境、业务场景、输入数据、执行步骤和预期结果五部分构成。测试用例定义了测试的范围和目标,即对哪个功能点进行测试,测试步骤是什么,以及期望得到什么样的结果。测试用例设计是测试开发过程中至关重要的一环,在测试用例的设计文档中需要清晰地描述出上述五个部分,并确保测试用例的可重复性和准确性。
测试脚本是测试用例的实现,脚本编写需要遵循测试用例的描述,同时还需要考虑满足测试环境设置、测试数据准备、测试操作执行、测试结果验证和测试报告生成等需求。一个好的测试脚本应该能够准确无偏差地完成所有测试步骤,并做好过程记录(日志、统计信息等),最后给出可靠的测试结果。
下面例举一个基于PyNVMe的测试用例设计及脚本实现,以便读者理解测试用例与脚本的关系。
测试用例目标 :验证SSD在PS3/PS4状态下的Reset功能。
测试用例设计 :测试步骤如下。
步骤1 :主机给SSD下发命令,令其进入PS3或PS4状态。
步骤2 :等待SSD的CQ应答。
步骤3 :收到CQ信息后,再随机等待一定的毫秒级时长(0,1,2,3,…,100)。
步骤4 :主机给SSD下发Reset命令,Reset类型可随机为Controller Reset/Subsystem Reset/D3 Reset/Link Down Reset/PERST等。
步骤5 :等待一定时长,然后重新扫描SSD,如果能找到SSD,并且期间日志无异常(ERR、ASSERT等),则认为本轮测试通过,进入下一轮(重复步骤1到步骤5),直到完成预定的循环次数。如果测试期间发现日志异常或者无法识别SSD,则测试终止,测试结果被认定为FAIL。
脚本实现,具体如下。
def test_ps3_ps4_reset(pcie, nvme0, subsystem):
test_round = 10000
for i in range(0, test_round):
logging.info(f'Round {i} ')
logging.info('1. Set PS3 or PS4')
ps = random.randint(3, 4)
logging.info(f'set to ps {ps}')
# conf igure into PS3 and sleep 30s
nvme0.setfeatures(0x2, cdw11=ps).waitdone()
logging.info('2. Wait cq')
logging.info('3. Delay ms(0,1,2,3….100ms)')
delay_ms = i % 101
logging.info(f'delay {delay_ms} ms')
time.sleep(0.01 * delay_ms)
logging.info('4. Random send one reset(controller reset/subsystem reset/d3 reset/link down reset/perst)')
reset_type = random.randint(0, 4)
if reset_type == 0:
logging.info('controller reset')
# issue controller reset
nvme0.reset()
elif reset_type == 1:
logging.info('subsystem reset')
subsystem.reset()
nvme0.reset()
elif reset_type == 2:
logging.info('hot reset')
# issue hot reset
pcie.reset()
nvme0.reset()
elif reset_type == 3:
logging.info('linkdown reset')
# linkdown reset
pass
elif reset_type == 4:
logging.info('perst')
# perst
pass
如果测试用例描述不够清晰,会导致不同的测试开发人员针对同一个测试用例的脚本实现有差异,这就是为什么不同的人写的同一个测试用例的脚本,测试结果有时却不相同。应该避免这种现象,在测试用例设计阶段就应该尽量详细,避免理解误差。一个良好的测试用例设计是实现一个正确脚本的前提。
需要说明的是,并不是所有测试用例都可能被脚本实现,有些测试用例需要测试人员手动操作,比如笔记本计算机的开合盖测试。