1
1.1 仿真模型API
执行仿真模型API的前提是:建立好测试项目,在设计器中设计创建要执行API的对应对象,并且环境设置无误。
执行的结果根据具体的脚本写法和API的功能,可能输出在【IO输入输出中心】,【历史记录】等位置。
1.1.1 通道读(按长度)
原型:通道.Read(length)
功能:从通道读取指定长度的数据内容(字节数组)。
参数:
Length:指定需要读取的数据长度。
返回值:成功则返回指定长度的数据;失败则返回None。
说明:需要判断Read操作是否成功。当通道缓存中的数据大于等于指定读取长度时,读取成功;否则,读取失败。读取成功后,读取到的数据从缓存中取出。
应用场景:测试人员为了验证待测系统是否按照预期向外发送了预期长度的数据内容,需要使用硬件通道从待测系统读取length个字节的数据。
示例:
仿真模型图:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例1:
#待测系统向通道X发送了数据【11,22,33,44,55,66,77,88,99,00】 |
结果:读取成功 |
脚本示例2:
#待测系统向通道X发送了数据【11,22,33,44】 |
结果:读取失败 |
1.1.2 通道阻塞读(按长度)
原型:通道. BlockRead(length)
功能:从指定通道读取指定长度的字节数据,如果没有足够长度数据则一直等待。
参数:
Length:指定需要读取的数据长度。
返回值:通道里的数据长度大于等于length,则返回指定长度的数据 ;否则阻塞调用线程。
说明:不需要判断BlockRead的操作是否成功。读取到的数据从缓存中取出。
应用场景:测试人员为了验证待测是系统是否按照预期向外发送了指定长度的数据,并且,确认收到了正确的数据,后续的测试才有意义,否则,测试脚本应该一直等待,直到收到足够长度的数据为止。需要调用通道. BlockRead(length)。
示例:
仿真模型图:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例1:
#待测系统向通道X发送了数据【11,22,33,44,55,66,77,88,99,00】 |
结果:11,22,33,44,55 |
脚本示例2:
#待测系统向通道X发送了数据【11,22,33,44】 |
结果:BlockRead操作会阻塞调用线程,一直停止在该句,不往下执行。 |
1.1.3 通道读(按头尾标记)
原型:通道. Read([head],[tail])
功能:使用指定的通道从待测系统读取符合头尾标记特征的数据。
参数:
head:开始标识,是一个字节序列。即读取到的数据的必须以[head]开始。
tail:结束标识,是一个字节序列。即读取到的数据的必须以[tail]结束。
返回值:成功则返回[head]XXXXXXXX[tail];失败则返回None。
说明:需要判断Read操作是否成功。读取成功后,读取到的数据和[head]之前的数据从缓存中清除。
应用场景:测试人员为了验证待测系统是否按照预期向外发送了一段用【head】和【tail】标志标记的数据。调用通道.Read([head],[tail])方法达到效果。
示例:
仿真模型图:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例1:
#待测系统向通道X发送了数据【11,22,33,44,55,66,77,88,99,00】 |
结果:读取成功 |
脚本示例2:
#待测系统向通道X发送了数据【11,22,33,44,55,66,77,88,99,00】 |
结果:读取失败 |
1.1.4 通道阻塞读 (按头尾标记)
原型:通道.BlockRead([head],[tail])
功能:使用指定的通道从待测系统阻塞地读取符合头尾标记特征的数据。
参数:
head:开始标识,是一个字节序列。即读取到的数据的必须以[head]开始。
Tail:结束标识,是一个字节序列。即读取到的数据的必须以[tail]结束。
返回值:如果通道接受到的数据里存在符合要求的数据内容,则返回[head]XXXXXXXX[tail]。
说明:不需要判断BlockRead的操作是否成功。读取到的数据和[head]之前的数据从缓存中清除。
应用场景:测试人员为了验证待测系统向外发送了一段用【head】和【tail】标志标记的数据,并且,在读到有效数据之前,执行后续的步骤没有意义,必须等到读取到正确的数据以后才能继续。调用BlockRead([head],[tail])方法达到效果。
示例:
仿真模型图:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例1:
#待测系统向通道X发送了数据【11,22,33,44,55,66,77,88,99,00】 |
结果:22,33,44,55,66,77 |
脚本示例2:
#待测系统向通道X发送了数据【11,22,33,44,55,66,77,88,99,00】 |
结果:BlockRead操作会阻塞调用线程,一直停止在该句,不往下执行。 |
原型:通道.Write(buffer)
功能:使用指定通道向待测系统写入指定的数据
参数:
buffer:需要向待测系统写入的字节内容数组
返回值:成功则返回 True;失败则返回 False。
说明:通道连接异常时(环境设置时提示通道打开失败),写入失败。需要对Write的返回结果进行判断,根据其结果做进一步的验证与测试。
应用场景:测试人员为了向待测系统发送特定的操作指令,写入一段对应的字节数据,需要调用通道.Write (buffer)达到预期的效果。
示例:
仿真模型图:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例:
#通道X向待测系统写入【11,22,33,44,55】 |
结果:根据 b 的结果做进一步的验证与测试 |
原型:通道.Clear(count=-1)
功能:清理通道缓存里的历史数据。
参数:
Count:需要清理的bit数量,默认值-1,代表全部清除;大于0的值有效。
返回值:成功则返回清理操作过程中被丢弃的缓存内容;失败则返回None。
返回值.Value:表示清除成功或失败。
返回值.Data:被清理掉的数据。
返回值.Count:表示Clear掉的数据的个数,以bit为单位。
说明:清除缓存数据,保证下次Read的数据是清除之后的最新数据。
应用场景:测试人员为了在测试某个功能之前,清理之前其他操作遗留下来的垃圾数据,否则,会影响到本次测试的内容,可以调用通道.Clear()方法来实现。
示例:
仿真模型图:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例1:
#通道X的缓存里为【0x11,0x22, 0x33, |
结果: |
脚本示例2:
#通道X的缓存里为【0x11,0x22, 0x33, |
结果: |
原型:通道.Seek(identy)
功能:将通道缓存的数据开始位置定位到指定的标识位置。之前的数据被丢弃。
参数:
Identy:字节序列,需要定位到的标识。
返回值:成功则返回定位操作丢弃掉的缓存内容;失败则返回 None。
返回值.Value:是否查找到字节序列。
返回值.Count:丢弃数据位数。
返回值.Data:丢弃的数据。
说明:移动数据指针,直到匹配标识的字节序列为止。前面的数据被丢弃,缓存中的数据从标识字节序列开始。如果没有匹配到,则返回None。
应用场景:测试人员为了在测试某个功能时,希望接收到特定标志开头(如0XAABB)的帧数据,但是,实际上可能存在之前操作遗留下来的无关的噪音数据,则需要调用通道.Seek(identy),将通道里的数据定位到符合该特征的位置。
示例:
仿真模型图:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例1:
#通道X的缓存里为【11,22,33,44,55,66,77,88,99,00】 |
结果:定位成功 |
脚本示例2:
#通道X的缓存里为【11,22,33,44,55,66,77,88,99,00】 |
结果:定位失败 |
原型:通道. BlockSeek(identy)
功能:将通道缓存的数据开始位置以阻塞的方式定位到指定的标记位置。
参数:
Identy:字节序列,需要定位到的标识。
返回值:如果通道里存在指定特征的数据,则返回定位操作丢弃掉的缓存内容;否则阻塞调用线程。
返回值.Value:是否查找到字节序列。
返回值.Count:丢弃数据位数。
返回值.Data:丢弃的数据。
说明:移动数据指针,直到匹配参数为止。如果收到的数据都无法匹配,则阻塞进程,等待数据,直到收到能够匹配的数据再返回。
应用场景:测试人员为了在测试某个功能时,必须确保后面步骤读到的数据满足特定的特征开头,否则导致测试逻辑错误,但是,实际上可能存在其他的噪音数据,则需要调用通道. BlockSeek(identy),将通道里的数据定位到符合该特征的位置。
示例:
仿真模型图:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例1:
#通道X的缓存里为【11,22,33,44,55,66,77,88,99,00】 |
结果: |
脚本示例2:
#通道X的缓存里为【11,22,33,44,55,66,77,88,99,00】 |
结果:BlockSeek操作会阻塞调用线程,一直停止在该句,不往下执行。 |
原型:ip=通道.HostIP;port=通道.HostPort
功能:获取通道所属的客户端的IP地址和端口。
返回值:通道设备所属的客户端的地址和端口。
说明:通道所属的客户端,在项目的PC规划时设置。一般是在向该客户端发送实时任务时使用。
应用场景:测试人员在测试某个功能时,希望查询某个通道所在的宿主计算机(客户端)的地址和端口信息。
示例:
仿真模型图:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例1:
# PC规划时,通道X所属的设备被规划在【127.0.0.1 :2233】的客户端 |
结果: |
原型:v=协议.协议段.Value
功能:读取指定协议段的当前值。
返回值:测试脚本环境里指定协议段的当前值
应用场景:在使用协议对象进行一次Read或者BlockBlock的操作之后,根据当前某个特定协议段当前的值,对下一步的测试与验证的步骤进行决策,需要使用协议段的Getter,得到想要的实际值。
示例:
仿真模型图及协议定义:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例1:
Protocol_1.name1.Value=10 |
结果:10 |
原型:协议.协议段.Value=v
功能:为某个协议段进行赋值。
返回值:无
应用场景:在使用协议对象向待测系统发送指令之前,设置好各个协议段的当前值,需用协议段Setter达到效果。
示例:
仿真模型图及协议定义:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例1:
#协议X 包含有一个协议段Y |
结果:100 |
原型:协议.Read()
功能:使用指定的协议从待测系统读取一帧内容。
返回值:成功则返回True;失败则返回False。
应用场景:为了验证待测系统是否向外发送了指定DPD协议所规定的内容,需用调用协议.Read()后检查其返回值和协议段的内容是否满足预期。
示例:
仿真模型图及协议定义:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例1:
#通道当前的数据内容为【11,22,33,44,55,66,77,88,99,00】 |
结果:true |
脚本示例2:
#通道当前的数据内容为【11,22】 |
结果:false |
原型:协议.BlockRead ()
功能:使用指定的协议从待测系统阻塞读取一帧内容,直到读取到数据为止。
返回值:如果成功读到数据则返回;否则阻塞调用线程。
应用情景:以阻塞方式读取一帧数据,只有成功读取到数据内容以后,后续的测试步骤才能继续执行,需要调用协议.BlockRead()达到目的效果。
示例:
仿真模型图及协议定义:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例1:
#通道当前的数据内容为【11,22,33,44,55,66,77,88,99,00】 |
结果:true |
脚本示例2:
#通道当前的数据内容为【11,22】 |
结果:BlockRead操作会阻塞调用线程,一直停止在该句,不往下执行。 |
原型:协议.FromBytes(buffer)
功能:使用指定的协议解析一组无格式的字节数组。
参数:
buffer:需要解析到协议上的字节数组。
返回值:成功则返回 True;失败则返回 False。
应用情景:将一组无格式的字节数组翻译成应用层协议(DPD),以便查看其各个协议段代表的真实物理意义,需要调用协议.FromBytes(buffer)。
示例:
仿真模型图及协议定义:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例1:
#给定字节数组 buf 等于【11,22,33】 |
结果:true |
脚本示例2:
#给定字节数组 buf 等于【11,22】 |
结果:true |
原型:协议.Write ()
功能:使用指定的协议向待测系统写入一帧内容。
返回值:成功则返回 True;失败则返回 False。
应用情景:为了向待测系统写入一帧指定DPD协议,需要调用协议.Write()。
示例:
仿真模型图及协议定义:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例1:
协议X.A.Value=11 |
结果:向待测系统发送【11,22,33】 |
原型:协议.ToBytes ()
功能:使用指定的协议根据其字段值编码到一个字节数组。
返回值:返回协议定义长度的字节数组。
应用情景:为了将一组应用协议(DPD)描述的内容编码为字节数组进行处理(加密,压缩等)以后,再向待测系统发送出去,需要调用协议.ToBytes()得到字节数组,然后经过处理以后,调用通道.Write(buffer)发送出去。
示例:
仿真模型图及协议定义:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例1:
协议X.A.Value=11 |
结果:[11,22,33] |
在测试项目中的“内容附件”节点中引用的外部文件,可以从脚本中通过“ExtData.附件名”进行引用。
内容附件分为两种:二进制文件、文本文件。
原型:obj=ExtData.附件名
功能:在脚本环境里引用设计器里添加的二进制文件。
返回值:附件名对应的二进制附件对象。
属性:
FileName:二进制文件名称。
Content:二进制文件内容。
应用情景:测试过程中需要引用外部的二进制文件的数据,但是希望不引用文件路径(文件路径可能会失效。例:在测试脚本里打开文件d:\working\demo.dat,将这个测试方案拷贝到另一个电脑上运行就有可能失败,因为新的电脑上并不存在d:\working\demo.dat),那么在设计器的界面中添加一个二进制文件,导入外部文件的内容,在测试脚本里使用“ExtData.附件名”来访问嵌入在测试方案文件里的二进制文件的内容。
示例:
测试项目:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例1:
#新建一个名称为【二进制文件_1】二进制文件的附件对象,导入一个外部文件【 HistoryDataManager.exe.config 】的内容 |
结果: |
原型:obj=ExtData.附件名
功能:在脚本环境里引用设计器里添加的外部的文本文件。
返回值:附件名对应的文本附件对象。
返回值. FileName:二进制文件名称。
返回值. Content:二进制文件内容。
应用情景:测试过程中需要引用外部的文本文件的内容,但是希望不引用文件路径(文件路径可能会失效,例:在测试脚本里打开文件d:\working\demo.dat,将这个测试方案拷贝到另一个电脑上运行就有可能失败,因为新的电脑上并不存在d:\working\demo.dat),在设计器的界面添加一个文本文件,导入外部文件的内容,在测试脚本里使用“ExtData.附件名”来访问嵌入在测试方案文件里的文本文件的内容。
示例:
测试项目:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例1:
#新建一个名称为【文本文件_1】文本文件的附件对象,导入一个文本文件【aaa.txt 】的内容 |
结果: |
在平台中,为了启动实时任务,需要在Python脚本中通过“RTTask.任务名”调用实时任务,并向下位机下发。
1.3.1 Simulink 仿真任务的定义
原型:obj = RTTask.任务名
功能:获取一个设计器中设计的Simulink的实时任务。
返回值:项目里包含的Simulink任务对象。
应用情景:在设计器界面定义了一个Simulink对象之后,在脚本里引用它,以便将其下载到下位机执行,需要使用“obj = RTTask.任务名”定义一个Simulink任务对象。
示例:
测试项目:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例1:
#在设计器中新建了一个名称为【 Simulink任务_1 】的实时任务对象,导入Simulink模型文件【 |
1.3.2 自定义CPP任务的定义
原型:obj = RTTask.任务名
功能:获取一个自定义C++实时任务。
返回值:项目里包含的实时任务对象。
应用情景:在设计器界面定义了一个C++实时任务之后,在脚本里引用它,以便将其下载到下位机执行,需要使用“obj = RTTask.任务名”定义一个C++实时任务对象。
示例:
测试项目:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例1:
#在设计器中新建了一个名称为【自定义CPP任务_1 】的实时任务对象 |
1.3.3 Simulink任务启动
原型:taskName=StartSimulink( ip , port , sim)
功能:启动一个Simulink模型任务,向下位机发送。
参数:
ip:实时客户端对应的ip地址。
port:实时客户端对应的port端口。
sim:使用“RTTask . 任务名”返回的Simulink对象。
返回值:成功则返回下位机定义的本实时任务的ID;失败则返回None。
应用情景:将一个Simulink任务下载到下位机执行,需要调用StartSimulink方法将任务对象发送到指定的实时客户端。
示例:
测试项目:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例1:
#新建了一个 |
1.3.4 C++任务启动
原型:taskName= StartVXScript ( ip , port , sim)
功能:启动一个自定义CPP任务。
参数:
ip:实时客户端对应的ip地址。
port:实时客户端对应的port端口。
sim:使用RTTask . 任务名返回的自定义CPP对象。
返回值:成功则返回下位机定义的本实时任务的ID;失败则返回None。
应用情景:将一个自定义CPP任务下载到下位机执行,需要调用StartVXScript方法将任务对象发送到指定的实时客户端。
示例:
测试项目:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例1:
#新建了一个 |
原型:b=SetParameters(ip , port , taskName , paramaters)
功能:修改下位机的某个任务的可调节参数。
参数:
ip:实时客户端对应的ip地址。
port:实时客户端对应的port端口。
taskName:使用RTTask . 任务名返回的自定义CPP对象。
paramaters:要修改的参数信息,格式为:('UINT8 a=1','UINT8 b=2','UINT8 c=33')
返回值:成功则返回 True,失败则返回 False。
应用情景:下位机的任务在执行过程中,测试人员希望调节该任务的参数,以达到测试目的,可以调用SetParamater方法进行修改。
示例:
测试项目:
编辑
添加图片注释,不超过 140 字(可选)
脚本示例1:
#下位正在运行一个任务名为【XXX】的任务,该任务具有可调参数: |
结果:true |
为了实现自动化测试,在脚本中添加了“断言”——Assertion,其用途如下:
1、记录某一测试用例的输入信息;
2、记录该测试用例的预期输出信息;
3、记录该测试用例的实际输出信息;
4、对比预期输出和实际输出,自动判断该用例是否通过;
5、不使用自动判断,由测试脚本调用Pass()或者Failed方法决定是否通过;
6、记录断言的历史,为测试报告提供历史依据。
功能:创建一个断言对象。
返回值:断言对象。
应用情景:在测试过程中,记录测试现场数据,自动判断当前测试步骤是否通过,为事后分析提供详细的依据和结论,需要创建一个断言对象,用来记录和判断,并且将详细信息保存到测试记录中。
示例:
Assertor = Assertion.Create() |
结果:assertor内部记录一个名为“参数1”值为100的输入参数 |
原型:assertor . AreEqual(argName , excepted , actual)
功能:记录测试的预期值和实际值,并根据二者是否相等判断是否通过。
参数:
argName:当前测试的输出参数名。
excepted:参数的预期值。
actual:参数的实际值
返回值:无。
应用情景:在测试过程中,需要记录测试的预期值和实际值,以便在查看测试历史记录的时候能得到具体的测试上下文参数信息,并且以默认的相等算法标记当前断言的结果是通过/未通过,可以调用AreEqual方法实现。
示例:
脚本示例1:
Assertor = Assertion.Create() |
结果:assertor内部记录一个名为“参数1”预期值和实际值;并且,判断结果为通过。 |
脚本示例2:
Assertor = Assertion.Create() |
结果:assertor内部记录一个名为“参数1”预期值和实际值;并且,判断结果为不通过。 |
原型:assertor.Pass( )
功能:设置断言的结果为“通过”。
返回值:无。
应用情景:在测试过程中,有的情况下不希望使用默认的行为来决定断言的状态是否通过,比如AreEqual( “参数1”, 100.999,100.998),按照默认的规则来比较的话,状态为“未通过”,但是在具体的测试上下文里,在允许的误差范围的情况下都算“通过”,可以调用Pass使断言结果为通过。
示例:
#给定字节数组 buf 等于【11,22,33】 |
结果:assertor的状态记录为通过。 |
原型:assertor. Failed( )
功能:设置断言的结果为“未通过”。
返回值:无。
应用情景:测试过程中,有的情况下希望标记将断言的状态标记为“未通过”,比如虽然AreEqual(“参数1”,100,100)的结果未“通过”,但是观察到一个异常的现象,可以调用Failed使断言结果为通过。
示例:
#给定字节数组 buf 等于【11,22,33】 |
结果:assertor的状态记录为未通过。 |
原型:assertor.Commit()
功能:将断言的详细信息保存到历史记录里。
返回值:无。
应用情景:在一个断言需要的内容(包含输入参数,预期输出,实际输出…)都准备完毕以后,希望将其存储到历史记录里,以便将来查看测试的历史记录时看到本测试的断言结果,通过调用Commit方法来实现。
示例:
#给定字节数组 buf 等于【11,22,33】 |
结果:历史记录数据文件或数据库中会保存本条断言的记录。 |
测试项目:
假设待测系统为一个加法器,从通道1获取输入参数【被加数】,从通道2获取输入参数【加数】,从通道3输出【和】。
编辑
添加图片注释,不超过 140 字(可选)
Protocol_1定义如下:
编辑
添加图片注释,不超过 140 字(可选)