航电实时系统测试平台Python脚本及扩展API

本文详细介绍了Python自动化测试框架ETest中的API使用,涵盖了协议读写、通道操作、实时任务、字节集合操作、数据分发(DDS)、Simulink仿真模型以及第三方引擎(如Matlab)的交互。通过这些API,测试人员可以高效地进行多线程任务调度、协议解析、数据同步以及实时系统交互等操作,从而实现复杂的自动化测试场景。
摘要由CSDN通过智能技术生成

执行仿真模型API的前提是:建立好测试项目,在设计器中设计创建要执行API的对应对象,并且环境设置无误。

执行的结果根据具体的脚本写法和API的功能,可能输出在【IO输入输出中心】,【历史记录】等位置。

      1. 通道读(按长度)

原型:通道.Read(length)

功能:从通道读取指定长度的数据内容(字节数组)。

参数:

Length:指定需要读取的数据长度。

返回值:成功则返回指定长度的数据;失败则返回None。

说明:需要判断Read操作是否成功。当通道缓存中的数据大于等于指定读取长度时,读取成功;否则,读取失败。读取成功后,读取到的数据从缓存中取出。

应用场景:测试人员为了验证待测系统是否按照预期向外发送了预期长度的数据内容,需要使用硬件通道从待测系统读取length个字节的数据。

示例:

仿真模型图:

脚本示例1:

#待测系统向通道X发送了数据【11,22,33,44,55,66,77,88,99,00】

array=CH_232_1.Read(5)

if not array:

        print '读取失败'

else:

        print '读取成功'

        for i in array:

            print '%X'%i

结果:读取成功

11

22

33

44

55

通道中剩余的内容为【66,77,88,99,00】

脚本示例2:

#待测系统向通道X发送了数据【11,22,33,44】

ret=通道X.Read(5)

if not array:

        print ‘读取失败’

else:

        print ‘读取成功’

        for i in array:

            print '%X'%i

结果:读取失败

通道中剩余的内容为【11,22,33,44】

      1. 通道阻塞读(按长度)

原型:通道. BlockRead(length)

功能:从指定通道读取指定长度的字节数据,如果没有足够长度数据则一直等待。

参数:

Length:指定需要读取的数据长度。

返回值:通道里的数据长度大于等于length,则返回指定长度的数据 ;否则阻塞调用线程。

说明:不需要判断BlockRead的操作是否成功。读取到的数据从缓存中取出。

应用场景:测试人员为了验证待测是系统是否按照预期向外发送了指定长度的数据,并且,确认收到了正确的数据,后续的测试才有意义,否则,测试脚本应该一直等待,直到收到足够长度的数据为止。需要调用通道. BlockRead(length)。

示例:

仿真模型图:

脚本示例1:

#待测系统向通道X发送了数据【11,22,33,44,55,66,77,88,99,00】

ret=通道X.BlockRead(5)

for i in array:

       print '%X'%i

结果:11,22,33,44,55

通道中剩余的内容为【66,77,88,99,00】

脚本示例2:

#待测系统向通道X发送了数据【11,22,33,44

ret=通道X.BlockRead(5)

for i in array:

       print '%X'%i

结果:BlockRead操作会阻塞调用线程,一直停止在该句,不往下执行。

      1. 通道读(按头尾标记)

原型:通道. Read([head],[tail])

功能:使用指定的通道从待测系统读取符合头尾标记特征的数据。

参数:

head:开始标识,是一个字节序列。即读取到的数据的必须以[head]开始。

tail:结束标识,是一个字节序列。即读取到的数据的必须以[tail]结束。

返回值:成功则返回[head]XXXXXXXX[tail];失败则返回None。

说明:需要判断Read操作是否成功。读取成功后,读取到的数据和[head]之前的数据从缓存中清除。

应用场景:测试人员为了验证待测系统是否按照预期向外发送了一段用【head】和【tail】标志标记的数据。调用通道.Read([head],[tail])方法达到效果。

示例:

仿真模型图:

脚本示例1:

#待测系统向通道X发送了数据【11,22,33,44,5566,77,88,99,00】

    ret=通道X . Read([22,33], [66,77])

    if ret.Length==0:

           print  “读取失败”

    else:

        print “读取成功”

    for i in ret:

        print '%X'%i

结果:读取成功

22

33

44

55

66

77

【11】被丢弃,通道中剩余的内容为【88,99,00】

脚本示例2:

#待测系统向通道X发送了数据【11,22,33,44,55,66,77,88,99,00】

    ret=通道X . Read([00,11], [97,98,99])

    if ret.Length==0:

           print  “读取失败”

    else:

        print “读取成功”

        for i in ret:

            print '%X'%i

结果:读取失败

通道中剩余的内容为【11,22,33,44,55,66,77,88,99,00】

      1. 通道阻塞读 (按头尾标记)

原型:通道.BlockRead([head],[tail])

功能:使用指定的通道从待测系统阻塞地读取符合头尾标记特征的数据。

参数:

head:开始标识,是一个字节序列。即读取到的数据的必须以[head]开始。

Tail:结束标识,是一个字节序列。即读取到的数据的必须以[tail]结束。

返回值:如果通道接受到的数据里存在符合要求的数据内容,则返回[head]XXXXXXXX[tail]。

说明:不需要判断BlockRead的操作是否成功。读取到的数据和[head]之前的数据从缓存中清除。

应用场景:测试人员为了验证待测系统向外发送了一段用【head】和【tail】标志标记的数据,并且,在读到有效数据之前,执行后续的步骤没有意义,必须等到读取到正确的数据以后才能继续。调用BlockRead([head],[tail])方法达到效果。

示例:

仿真模型图:

脚本示例1:

#待测系统向通道X发送了数据【11,22,33,44,5566,77,88,99,00】

ret=通道X. BlockRead ([12,13], [16,77])

for i in ret:

        print '%X'%i

结果:22,33,44,55,66,77

【11】被丢弃,通道中剩余的内容为【88,99,00】

脚本示例2:

#待测系统向通道X发送了数据【11,22,33,44,55,66,77,88,99,00】

ret=通道X. BlockRead ([12,13], [16,77])

for i in ret:

        print '%X'%i

结果:BlockRead操作会阻塞调用线程,一直停止在该句,不往下执行。

      1. 通道写

原型:通道.Write(buffer)

功能:使用指定通道向待测系统写入指定的数据

参数:

buffer:需要向待测系统写入的字节内容数组

返回值:成功则返回 True;失败则返回 False。

说明:通道连接异常时(环境设置时提示通道打开失败),写入失败。需要对Write的返回结果进行判断,根据其结果做进一步的验证与测试。

应用场景:测试人员为了向待测系统发送特定的操作指令,写入一段对应的字节数据,需要调用通道.Write (buffer)达到预期的效果。

示例:

仿真模型图:

脚本示例:

#通道X向待测系统写入【11,22,33,44,55】

buffer = [0x11,0x22,0x33,0x44,0x55]

b = 通道X.Write(buffer)

print "需要对Write的返回结果进行判断处理"

if b==True:

print "写入成功"

else:

     print "写入失败"

结果:根据 b 的结果做进一步的验证与测试

      1. 通道缓存清理

原型:通道.Clear(count=-1)

功能:清理通道缓存里的历史数据。

参数

Count:需要清理的bit数量,默认值-1,代表全部清除;大于0的值有效。

返回值:成功则返回清理操作过程中被丢弃的缓存内容;失败则返回None。

返回值.Value:表示清除成功或失败。

返回值.Data:被清理掉的数据。

返回值.Count:表示Clear掉的数据的个数,以bit为单位。

说明:清除缓存数据,保证下次Read的数据是清除之后的最新数据。

应用场景:测试人员为了在测试某个功能之前,清理之前其他操作遗留下来的垃圾数据,否则,会影响到本次测试的内容,可以调用通道.Clear()方法来实现。

示例:

仿真模型图:

脚本示例1:

#通道X的缓存里为【0x11,0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00】

ret=通道X.Clear()

print ret.Value

print ret.Count

print ret.Data

结果:

True

40

Array[Byte](( 17,34,51,68,85,102,119,136,153,0))

通道X缓存中不再有数据。

脚本示例2:

#通道X的缓存里为【0x11,0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00】

ret=通道X.Clear(40)

print ret.Value

print ret.Count

print ret.Data

结果:

True

40

Array[Byte]((17,34,51,68,85))

通道X的缓存里数据为【66,77,88,99,00】。

      1. 通道缓存定位

原型:通道.Seek(identy)

功能:将通道缓存的数据开始位置定位到指定的标识位置。之前的数据被丢弃。

参数:

Identy:字节序列,需要定位到的标识。

返回值:成功则返回定位操作丢弃掉的缓存内容;失败则返回 None。

返回值.Value:是否查找到字节序列。

返回值.Count:丢弃数据位数。

返回值.Data:丢弃的数据。

说明:移动数据指针,直到匹配标识的字节序列为止。前面的数据被丢弃,缓存中的数据从标识字节序列开始。如果没有匹配到,则返回None。

应用场景:测试人员为了在测试某个功能时,希望接收到特定标志开头(如0XAABB)的帧数据,但是,实际上可能存在之前操作遗留下来的无关的噪音数据,则需要调用通道.Seek(identy),将通道里的数据定位到符合该特征的位置。

示例:

仿真模型图:

脚本示例1:

#通道X的缓存里为【11,22,33,44,55,66,77,88,99,00】

def Main():

    ret=通道X.Seek([0x44,0x55,0x66])

    if ret ==None:

           print "定位失败"

    else:

        print "定位成功"

Main()

结果:定位成功

ret.Value为true,ret.count=3,ret.Data=11,22,33。

通道X缓存剩余数据为【44,55,66,77,88,99,00】。

脚本示例2:

#通道X的缓存里为【11,22,33,44,55,66,77,88,99,00】

ret=通道X.Seek([144,155,66])

if ret ==None:

           print "定位失败"

else:

        print "定位成功"

结果:定位失败

通道X缓存剩余数据为【11,22,33,44,55,66,77,88,99,00】。

      1. 通道缓存阻塞定位

原型:通道. BlockSeek(identy)

功能:将通道缓存的数据开始位置以阻塞的方式定位到指定的标记位置。

参数:

Identy:字节序列,需要定位到的标识。

返回值:如果通道里存在指定特征的数据,则返回定位操作丢弃掉的缓存内容;否则阻塞调用线程。

返回值.Value:是否查找到字节序列。

返回值.Count:丢弃数据位数。

返回值.Data:丢弃的数据。

说明:移动数据指针,直到匹配参数为止。如果收到的数据都无法匹配,则阻塞进程,等待数据,直到收到能够匹配的数据再返回。

应用场景:测试人员为了在测试某个功能时,必须确保后面步骤读到的数据满足特定的特征开头,否则导致测试逻辑错误,但是,实际上可能存在其他的噪音数据,则需要调用通道. BlockSeek(identy),将通道里的数据定位到符合该特征的位置。

示例:

仿真模型图:

脚本示例1:

#通道X的缓存里为【11,22,33,44,55,66,77,88,99,00】

ret=通道X.BlockSeek([0x44,0x55,0x66])

print ret.Value

print ret.Count

print ret.Data

结果:

True

24

Array[Byte]((17,34,51))

通道X缓存剩余数据为【44,55,66,77,88,99,00】。

脚本示例2:

#通道X的缓存里为【11,22,33,44,55,66,77,88,99,00】

ret=通道X.BlockSeek([0x14,0x15,0x66])

print ret

结果:BlockSeek操作会阻塞调用线程,一直停止在该句,不往下执行。

      1. 通道Host

原型:ip=通道.HostIP;port=通道.HostPort

功能:获取通道所属的客户端的IP地址和端口。

返回值:通道设备所属的客户端的地址和端口。

说明:通道所属的客户端,在项目的PC规划时设置。一般是在向该客户端发送实时任务时使用。

应用场景:测试人员在测试某个功能时,希望查询某个通道所在的宿主计算机(客户端)的地址和端口信息。

示例:

仿真模型图:

脚本示例1:

# PC规划时,通道X所属的设备被规划在【127.0.0.1 :2233】的客户端

ip = 通道X.HostIP

port = 通道X.HostPort

print ip

print port

结果:

127.0.0.1

2233

      1. 协议段Getter

原型:v=协议.协议段.Value

功能:读取指定协议段的当前值。

返回值:测试脚本环境里指定协议段的当前值

应用场景:在使用协议对象进行一次Read或者BlockBlock的操作之后,根据当前某个特定协议段当前的值,对下一步的测试与验证的步骤进行决策,需要使用协议段的Getter,得到想要的实际值。

示例:

仿真模型图及协议定义:

 

脚本示例1:

Protocol_1.name1.Value=10

ret = 协议X.协议段Y.Value

print ret

结果:10

      1. 协议段Setter

原型:协议.协议段.Value=v

功能:为某个协议段进行赋值。

返回值:无

应用场景:在使用协议对象向待测系统发送指令之前,设置好各个协议段的当前值,需用协议段Setter达到效果。

示例:

仿真模型图及协议定义:

 

脚本示例1:

#协议X 包含有一个协议段Y

协议X.协议段Y.Value = 100

v=协议X.协议段Y.Value

print v

结果:100

执行协议X.Write()的时候,写出的内容对应位置就是100

      1. 协议读

原型:协议.Read()

功能:使用指定的协议从待测系统读取一帧内容。

返回值:成功则返回True;失败则返回False。

应用场景:为了验证待测系统是否向外发送了指定DPD协议所规定的内容,需用调用协议.Read()后检查其返回值和协议段的内容是否满足预期。

示例:

仿真模型图及协议定义:

 

脚本示例1:

#通道当前的数据内容为【11,22,33,44,55,66,77,88,99,00】

b = 协议X.Read()

print b   # True

print 协议X.A.Value  #11

print 协议X.B.Value  #22

print 协议X.C.Value  #33

结果:true

      11

      22

      33

通道中剩余数据内容【44,55,66,77,88,99,00】

脚本示例2:

#通道当前的数据内容为【11,22】

b = 协议X.Read()

print b   # False

print 协议X.A.Value  #0

print 协议X.B.Value  #0

print 协议X.C.Value  #0

Main()

结果:false

      0

      0

      0

通道中剩余数据内容【11,22】

      1. 协议阻塞读

原型:协议.BlockRead ()

功能:使用指定的协议从待测系统阻塞读取一帧内容,直到读取到数据为止。

返回值:如果成功读到数据则返回;否则阻塞调用线程。

应用情景:以阻塞方式读取一帧数据,只有成功读取到数据内容以后,后续的测试步骤才能继续执行,需要调用协议.BlockRead()达到目的效果。

示例:

仿真模型图及协议定义:

 

脚本示例1:

#通道当前的数据内容为【11,22,33,44,55,66,77,88,99,00】

b = 协议X.BlockRead()

print b   # True

print 协议X.A.Value  #11

print 协议X.B.Value  #22

print 协议X.C.Value  #33

Main()

结果:true

      11

      22

      33

通道中剩余数据内容【44,55,66,77,88,99,00】

脚本示例2:

#通道当前的数据内容为【11,22】

b = 协议X.BlockRead()

print b   # False

print 协议X.A.Value  #0

print 协议X.B.Value  #0

print 协议X.C.Value  #0

Main()

结果:BlockRead操作会阻塞调用线程,一直停止在该句,不往下执行。

      1. 协议解码

原型:协议.FromBytes(buffer)

功能:使用指定的协议解析一组无格式的字节数组。

参数:

    buffer:需要解析到协议上的字节数组。

返回值:成功则返回 True;失败则返回 False。

应用情景:将一组无格式的字节数组翻译成应用层协议(DPD),以便查看其各个协议段代表的真实物理意义,需要调用协议.FromBytes(buffer)。

示例:

仿真模型图及协议定义:

 

脚本示例1:

#给定字节数组 buf 等于【11,22,33】

buf=[11, 22, 33]

b=协议X.FromBytes(buf)

print b   # True

print 协议X.A.Value  #11

print 协议X.B.Value  #22

print 协议X.C.Value  #33

结果:true

      11

      22

      33

脚本示例2:

#给定字节数组 buf 等于【11,22】

buf=[11, 22]

b=协议X.FromBytes(buf)

print b   # False

print 协议X.A.Value  #0

print 协议X.B.Value  #0

print 协议X.C.Value  #0

Main()

结果:true

      0

      0

      0

      1. 协议写

原型:协议.Write ()

功能:使用指定的协议向待测系统写入一帧内容。

返回值:成功则返回 True;失败则返回 False。

应用情景:为了向待测系统写入一帧指定DPD协议,需要调用协议.Write()。

示例:

仿真模型图及协议定义:

 

脚本示例1:

协议X.A.Value=11

协议X.B.Value=22

协议X.C.Value=33

协议X.Write()

结果:向待测系统发送【11,22,33】

      1. 协议编码

原型:协议.ToBytes ()

功能:使用指定的协议根据其字段值编码到一个字节数组。

返回值:返回协议定义长度的字节数组。

应用情景:为了将一组应用协议(DPD)描述的内容编码为字节数组进行处理(加密,压缩等)以后,再向待测系统发送出去,需要调用协议.ToBytes()得到字节数组,然后经过处理以后,调用通道.Write(buffer)发送出去。

示例:

仿真模型图及协议定义:

 

脚本示例1:

协议X.A.Value=11

协议X.B.Value=22

协议X.C.Value=33

arr=协议X.ToBytes()

print arr

结果:[11,22,33]

    1. 内容附件

在测试项目中的“内容附件”节点中引用的外部文件,可以从脚本中通过“ExtData.附件名”进行引用。

内容附件分为两种:二进制文件、文本文件。

      1. 二进制文件

原型:obj=ExtData.附件名

功能:在脚本环境里引用设计器里添加的二进制文件。

返回值:附件名对应的二进制附件对象。

属性:

FileName:二进制文件名称。

Content:二进制文件内容。

应用情景:测试过程中需要引用外部的二进制文件的数据,但是希望不引用文件路径(文件路径可能会失效。例:在测试脚本里打开文件d:\working\demo.dat,将这个测试方案拷贝到另一个电脑上运行就有可能失败,因为新的电脑上并不存在d:\working\demo.dat),那么在设计器的界面中添加一个二进制文件,导入外部文件的内容,在测试脚本里使用“ExtData.附件名”来访问嵌入在测试方案文件里的二进制文件的内容。

示例:

测试项目:

 

脚本示例1:

#新建一个名称为【二进制文件_1】二进制文件的附件对象,导入一个外部文件【 HistoryDataManager.exe.config 】的内容

T = ExtData.二进制文件_1

print t.FileName     # HistoryDataManager.exe.config

print t.Content      #文件内容

结果:

HistoryDataManager.exe.config

/*文件的内容*/

      1. 文本文件

原型:obj=ExtData.附件名

功能:在脚本环境里引用设计器里添加的外部的文本文件。

返回值:附件名对应的文本附件对象。

返回值. FileName:二进制文件名称。

返回值. Content:二进制文件内容。

应用情景:测试过程中需要引用外部的文本文件的内容,但是希望不引用文件路径(文件路径可能会失效,例:在测试脚本里打开文件d:\working\demo.dat,将这个测试方案拷贝到另一个电脑上运行就有可能失败,因为新的电脑上并不存在d:\working\demo.dat),在设计器的界面添加一个文本文件,导入外部文件的内容,在测试脚本里使用“ExtData.附件名”来访问嵌入在测试方案文件里的文本文件的内容。

示例:

测试项目:

 

脚本示例1:

#新建一个名称为【文本文件_1】文本文件的附件对象,导入一个文本文件【aaa.txt 】的内容

T = ExtData.文本文件_1

print t.FileName    # aaa.txt

print t.Content     #文件内容

结果:

aaa.txt

/*文件的内容*/

    1. 实时任务的调用

在平台中,为了启动实时任务,需要在Python脚本中通过“RTTask.任务名”调用实时任务,并向下位机下发。

      1. Simulink 仿真任务的定义

原型:obj = RTTask.任务名

功能:获取一个设计器中设计的Simulink的实时任务。

返回值:项目里包含的Simulink任务对象。

应用情景:在设计器界面定义了一个Simulink对象之后,在脚本里引用它,以便将其下载到下位机执行,需要使用“obj = RTTask.任务名”定义一个Simulink任务对象。

示例:

测试项目:

 

脚本示例1:

#在设计器中新建了一个名称为【 Simulink任务_1 】的实时任务对象,导入Simulink模型文件【 DemoGenCode.mdl 】

sim = RTTask.Simulink任务_1

print sim.FileName       #模型文件名

print sim.Text           #模型文件的文本形式的内容

print sim.Binary         #模型文件的字节

print sim.SourceFiles    #实时任务的源代码

      1. 自定义CPP任务的定义

原型:obj = RTTask.任务名

功能:获取一个自定义C++实时任务。

返回值:项目里包含的实时任务对象。

应用情景:在设计器界面定义了一个C++实时任务之后,在脚本里引用它,以便将其下载到下位机执行,需要使用“obj = RTTask.任务名”定义一个C++实时任务对象。

示例:

测试项目:

 

脚本示例1:

#在设计器中新建了一个名称为【自定义CPP任务_1 】的实时任务对象

sim = RTTask.自定义CPP任务_1

print sim.SourceFiles    #实时任务的源代码

      1. Simulink任务启动

原型:taskName=StartSimulink( ip , port , sim)

功能:启动一个Simulink模型任务,向下位机发送。

参数:

    ip:实时客户端对应的ip地址。

    port:实时客户端对应的port端口。

    sim:使用“RTTask . 任务名”返回的Simulink对象。

返回值:成功则返回下位机定义的本实时任务的ID;失败则返回None。

应用情景:将一个Simulink任务下载到下位机执行,需要调用StartSimulink方法将任务对象发送到指定的实时客户端。

示例:

测试项目:

 

脚本示例1:

#新建了一个 名称为【VX_A 】的Simulink实时任务对象,导入正确的Simulink模型,点击【生成C++代码】,适当调整代码,将输入输出映射绑定到硬件通道,编译检查确认没有语法错误

ip = 通道_2.HostIP

port = 通道_2.HostPort

sim = RTTask.VX_A

taskName = API.Platform.VXWorks.StartSimulink(ip,port,sim)

print taskName  #下位机返回的任务名

      1. C++任务启动

原型:taskName= StartVXScript ( ip , port , sim)

功能:启动一个自定义CPP任务。

参数:

    ip:实时客户端对应的ip地址。

    port:实时客户端对应的port端口。

    sim:使用RTTask . 任务名返回的自定义CPP对象。

返回值:成功则返回下位机定义的本实时任务的ID;失败则返回None。

应用情景:将一个自定义CPP任务下载到下位机执行,需要调用StartVXScript方法将任务对象发送到指定的实时客户端。

示例:

测试项目:

 

脚本示例1:

#新建了一个 名称为【VX_A 】的自定义CPP实时任务对象,编译检查确认没有语法错误

ip = 通道_2.HostIP

port = 通道_2.HostPort

sim = RTTask.VX_A

taskName = API.Platform.VXWorks.StartVXScript (ip,port,sim)

print taskName  #下位机返回的任务名

      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方法进行修改。

示例:

测试项目:

 

脚本示例1:

#下位正在运行一个任务名为【XXX】的任务,该任务具有可调参数: int  A,当前值为 0。该任务循环打印A的值0

def Main():

    ip = 通道_2.HostIP

    port = 通道_2.HostPort

    sim = RTTask.自定义CPP任务_1

    paramaters=('int A=100')

    b=API.Platform.VXWorks.SetParameters(ip,port,sim,paramaters)

    print b

Main()

结果:true

下位机任务打印的内容变为100

    1. 自动化测试

为了实现自动化测试,在脚本中添加了“断言”——Assertion,其用途如下:

1、记录某一测试用例的输入信息;

2、记录该测试用例的预期输出信息;

3、记录该测试用例的实际输出信息;

4、对比预期输出和实际输出,自动判断该用例是否通过;

5、不使用自动判断,由测试脚本调用Pass()或者Failed方法决定是否通过;

6、记录断言的历史,为测试报告提供历史依据。

      1. Assertion.Create

功能:创建一个断言对象。

返回值:断言对象。

应用情景:在测试过程中,记录测试现场数据,自动判断当前测试步骤是否通过,为事后分析提供详细的依据和结论,需要创建一个断言对象,用来记录和判断,并且将详细信息保存到测试记录中。

示例:

Assertor = Assertion.Create()

assertor.RecordInput("参数1 ",100)

结果:assertor内部记录一个名为“参数1”值为100的输入参数

      1. AreEqual

原型:assertor . AreEqual(argName , excepted , actual)

功能:记录测试的预期值和实际值,并根据二者是否相等判断是否通过。

参数:

    argName:当前测试的输出参数名。

    excepted:参数的预期值。

    actual:参数的实际值

返回值:无。

应用情景:在测试过程中,需要记录测试的预期值和实际值,以便在查看测试历史记录的时候能得到具体的测试上下文参数信息,并且以默认的相等算法标记当前断言的结果是通过/未通过,可以调用AreEqual方法实现。

示例:

脚本示例1:

Assertor = Assertion.Create()

assertor.AreEqual("参数1",100, 100)

结果:assertor内部记录一个名为“参数1”预期值和实际值;并且,判断结果为通过。

脚本示例2:

Assertor = Assertion.Create()

assertor.AreEqual("参数1",100,101)

Main()

结果:assertor内部记录一个名为“参数1”预期值和实际值;并且,判断结果为不通过。

      1. Pass

原型:assertor.Pass( )

功能:设置断言的结果为“通过”。

返回值:无。

应用情景:在测试过程中,有的情况下不希望使用默认的行为来决定断言的状态是否通过,比如AreEqual( “参数1”,  100.999,100.998),按照默认的规则来比较的话,状态为“未通过”,但是在具体的测试上下文里,在允许的误差范围的情况下都算“通过”,可以调用Pass使断言结果为通过。

示例:

#给定字节数组 buf 等于【11,22,33】

Assertor = Assertion.Create()

assertor.AreEqual("参数1",100,101)  #assertor的状态记录为未通过

assertor.Pass()

结果:assertor的状态记录为通过。

      1. Failed

原型:assertor. Failed( )

功能:设置断言的结果为“未通过”。

返回值:无。

应用情景:测试过程中,有的情况下希望标记将断言的状态标记为“未通过”,比如虽然AreEqual(“参数1”,100,100)的结果未“通过”,但是观察到一个异常的现象,可以调用Failed使断言结果为通过。

示例:

#给定字节数组 buf 等于【11,22,33】

Assertor = Assertion.Create()

assertor.AreEqual("参数1",100,100)  #assertor的状态记录为通过

assertor.Failed ()

结果:assertor的状态记录为未通过。

      1. Commit

原型:assertor.Commit()

功能:将断言的详细信息保存到历史记录里。

返回值:无。

应用情景:在一个断言需要的内容(包含输入参数,预期输出,实际输出…)都准备完毕以后,希望将其存储到历史记录里,以便将来查看测试的历史记录时看到本测试的断言结果,通过调用Commit方法来实现。

示例:

#给定字节数组 buf 等于【11,22,33】

Assertor = Assertion.Create()

assertor.AreEqual("参数1 ",100,101)  #assertor的状态记录未不通过

assertor.Commit()

结果:历史记录数据文件或数据库中会保存本条断言的记录。

      1. 断言示例

测试项目:

假设待测系统为一个加法器,从通道1获取输入参数【被加数】,从通道2获取输入参数【加数】,从通道3输出【和】。

Protocol_1定义如下:

Protocol 协议名
    Segment 结果 StandardInt8 Default=0 Format=Complement
End

Protocol_2定义如下:

Protocol 协议名
    Segment 被加数 StandardInt8 Default=0 Format=Complement
End

Protocol_3定义如下:

Protocol 协议名
    Segment 加数 StandardInt8 Default=0 Format=Complement
End

测试1:验证10+20=30

Protocol_2.被加数.Value = 10
bool=Protocol_2.Write()
Protocol_3.加数.Value = 20
bool=Protocol_3.Write()
bool=Protocol_1.Read()

expected = 30
assertor=API.Platform.Assertion.Create()
assertor.RecordInput('被加数',Protocol_2.被加数.Value)
assertor.RecordInput('加数',Protocol_3.加数.Value)
assertor.AreEqual('结果', expected,Protocol_1.结果.Value)
assertor.Commit()

       执行脚本,打开历史数据记录程序,【Kiyun.EmbedTest.APP.Tools.HistoryData.exe】,导出Word文档。在文档中可以看到如下内容:

1,与待测系统进行通信的数据内容

2,断言的结果(绿勾代表通过)

测试2:验证测试用例表包含的测试

创建Python脚本,如下:

# coding:utf-8
############标准测试模板#######################
## Test:测试数据执行函数体,【测试数据】每一行数据调用一次Test
## arg:输入参数
## exp:预期输出
def Test(arg,exp):
      Protocol_2.被加数.Value=arg[0]
      bool=Protocol_2.Write()
      Protocol_3.加数.Value = arg[1]
      bool=Protocol_3.Write()
      bool=Protocol_1.Read()
      
      assertor=API.Platform.Assertion.Create()
      assertor.RecordInput('被加数',arg[0])
      assertor.RecordInput('加数',arg[1])
      assertor.AreEqual('',exp[0],arg[0]+arg[1])
      if abs(exp[0] - (arg[0]+arg[1]))<0.1:
        assertor.Pass()
      else:
        assertor.Failed()
      b=assertor.Commit()

## Standard_Test:标准测试的方法入口,使用【测试数据】表循环调用Test方法
Standard_Test(Test)
#############################################

在测试用例表页面,创建如下测试用例:

执行脚本,打开历史数据记录程序,【Kiyun.EmbedTest.APP.Tools.HistoryData.exe】,导出Word文档,可以在文档中看到如下内容:

可以看出,其中有一条测试用例失败(红框标示),需要检查待测系统的代码。

    1. 多线程
      1. 创建并启动任务

原型:Task = TaskFactory.StartTask(action)

功能:创建一个新的线程并执行action。

参数:

    action:新线程需要执行的函数,或者lambda表达式。

返回值:返回任务对象。

应用情景:在测试过程中,创建一个新的后台的线程(比如等待某个信号),但是测试的主线程还需要继续往前执行,调用StartTask来实现。

示例:

脚本示例1:

def func():  #定义一个函数
    for i in range(1,500):
      print  '-'

    def Main():
    API.Common.Task.TaskFactory.StartTask(func)
    for i in range(1,500):
      print '|'

    Main()

结果:屏幕上随机打印-,|。

脚本示例2:

def  func():  #定义一个函数

for i in range(1,500):

        print ‘A’

def Main():

    ac = lambda :func()

    API.Common.Task.TaskFactory.StartTask(ac)

for i in range(1,500):

        print ‘B’

Main()

结果:屏幕上随机打印A,B。

      1. 创建任务

原型:Task = TaskFactory.CreateTask(action)

功能:创建一个新的线程,但是不执行action。

参数:

    action:新线程需要执行的函数,或者lambda表达式。

返回值:返回任务对象。

应用情景:测试过程中,希望创建一个新的任务但是不立即执行,在后续测试步骤中通知其运行,调用CreateTask来创建一个等待执行的任务对象。

示例:

脚本示例1:

def  func():  #定义一个函数

for i in range(1,500):

        print ‘A’

def Main():

    API.Common.Task.TaskFactory.CreateTask(func)

for i in range(1,500):

        print ‘B’

Main()

结果:屏幕循环打印B,不打印A。

脚本示例2:

def  func():  #定义一个函数

for i in range(1,500):

        print ‘A’

def Main():

    ac = lambda :func()

    API.Common.Task.TaskFactory.CreateTask(func)

for i in range(1,500):

        print ‘B’

Main()

结果:屏幕循环打印B,不打印A。

      1. 等待任务结束

原型:Task.Wait()

功能:等待任务执行完毕。

返回值:如果任务还在执行中,则阻塞调用线程,直至任务完成后,继续执行后续代码。

应用场景:测试人员为了等待一个后台的任务线程结束后执行后续代码,需要调用该任务的Wait方法。

示例:

def  func():  #定义一个函数

for i in range(10):

        print "A"

        API.Common.Timere.Normal.Sleep(1000)  #1000毫秒

def Main():

    task=API.Common.Task.TaskFactory.StartTask(func)

task.Wait()

print "B"

Main()

结果:连续打印10个字符A,大约10秒以后打印字符B。

      1. 等待任务结束超时

原型:Task.Wait(timeout)

功能:等待任务执行完毕,timeout时长后,结束等待,执行后续代码。

参数:

    timeout:等待的最大时间。

返回值:如果任务还在执行中,而且等待的时间没超过timeout,则阻塞调用线程。Timeout内任务结束,后超过timeout时长,则停止等待,继续执行后面的代码。

应用场景:测试人员为了等待一个后台的任务线程结束后执行后续代码,但只能等待timeout时间,调用该任务的Wait(timeout)方法。

示例:

def  func():  #定义一个函数

for i in range(10):

        print "A"

        API.Common.Timere.Normal.Sleep(1000)  #1000毫秒

def Main():

    task = API.Common.Task.TaskFactory.StartTask(func)

task.Wait(5000)  #5秒

print "B"

Main()

结果:连续打印5个字符A,大约5秒以后打印字符B。

      1. 启动任务

原型:Task = TaskFactory. Start(action)

功能:启动一个由CreateTask创建的任务对象。

返回值:无。

应用情景:启动一个之前已经准备好的任务对象,则调用Task.Start()。

示例:

def  func():  #定义一个函数

for i in range(10):

        print 'A'

def Main():

    task=API.Common.Task.TaskFactory.CreateTask(func)

task.Start()

task.Wait()

print 'B'

Main()

结果:连续打印10个字符A,大约10秒以后打印字符B。。

      1. 任务后继

原型:Task. ContinueWith (func)

功能:为一个任务附加一个后继的任务。

参数:

    func:新线程需要执行的函数,或者lambda表达式。

返回值:新的任务对象。

应用情景:在一个后台任务(比如正在执行协议读)执行完后,立即执行另外一项任务(比如把数据记录到文件里),则调用Task. ContinueWith (func)。

示例:

def  funcA():  #定义一个函数

    b = 协议C.BlockRead

def  funcB():  #定义一个函数

    bool = 协议B.Write()

task=API.Common.Task.TaskFactory.StartTask(funcA)

task.ContinueWith (funcB)

task.Wait()

结果:与直接在funcA方法的BlockRead()之后加Write()的不同之处在于,ContinueWith的代码动态指定,类似与动态设置中断函数的效果,而不是由预先写好的funcA方法的逻辑来决定。

      1. 任务的错误消息

原型:msg=Task.Error

功能:获取任务执行过程的错误消息。

返回值:如果任务发生异常,则返回错误消息;否则返回None。

      1. 任务的状态

原型:status=Task.Status

功能:获取任务当前状态。

返回值:任务状态,包括:运行中,已停止,异常等。

      1. 创建任务列表

原型:tasks=TaskFactory. CreateTasks()

功能:创建一个可以容纳多个任务的列表对象。

返回值:任务列表对象。

应用情景:测试过程中,希望一个任务列表,可以集中管理(开始执行,同步等),调用CreateTasks实现。

示例:

tasks=API.Common.Task.TaskFactory.CreateTasks()

结果:tasks为一个空的任务对象。

      1. 任务列表操作

原型:Tasks.AddTask(task)    往任务集合里增加一个新任务

Tasks.Start()    按照集合顺序启动所有任务(并行)

Tasks.WaitAll()    等待所有任务完成

Tasks.WaitAny()    等待其中任意一个任务完成

Tasks.ContinueWhenAll(action)    所有任务完成后启动新任务

Tasks.ContinueWhenAny(action)    任意一个任务完成后启动新任务

Tasks.IsAllCompleted    任意一个任务完成后启动新任务

应用实例见“多任务示例”章节。

      1. 创建同步锁

原型:TaskFactory. CreateLockor()

功能:创建一个同步锁对象。

返回值:返回一个用来同步执行方法的锁对象。

应用情景:测试过程中,希望执行多个任务线程,但是其中有些步骤需要同步,使用CreateLockor返回的同步对象来执行同步代码段。

示例:

lockor=API.Common.Task.TaskFactory.CreateLockor()

结果:lockor为一个同步对象。

应用实例见“多任务示例”章节

      1. 安全执行任务

原型:Lockor.Invoke(action) (Locker为TaskFactory. CreateLockor()返回的同步对象)

功能:以同步方式执行action动作,同一个lockor执行任意多个action都会被排队依次执行。

参数:

    action:新线程需要执行的函数,或者lambda表达式。

返回值:无。

应用情景:按顺序执行多个任务中的部分关键代码,比如访问同一个通道进行读写,调用Lockor.Invoke(action)实现。

应用实例见“多任务示例”章节。

      1. 删除同步锁

原型:Lockor.Delete()

功能:删除由TaskFactory. CreateLockor()返回的同步对象。

返回值:无。

应用实例见 “多任务示例”章节。

      1. 多任务示例

实例1 :简单多任务

def  funcA():  #定义一个函数

    While True:

        print ‘A’

def  funcB():  #定义一个函数

    While True:

        print ‘B’

API.Common.Task.TaskFactory.StartTask(funcA)

API.Common.Task.TaskFactory.StartTask(funcB)

task. ContinueWith (funcB)

While True:

     print ‘C’

结果:结果时屏幕随机打印A,B,C.

假如将print语句替换为对同一个通道或协议的读写,因为线程的随机调度,会导致不可预知的结果,例如下面代码会随机打印ABC。

实例2:任务同步

def  funcA():  #定义一个函数

    for i in range(5):

        print i

        API.Common.Timere.Normal.Sleep(100)

def  funcB():  #定义一个函数

    for i in range(‘A’,’B’,’C’,’D’,’E’):

        print i

        API.Common.Timere.Normal.Sleep(100)

lockor=API.Common.Task.TaskFactory.CreateLockor()

task1=API.Common.Task.TaskFactory.StartTask(lamda:lockor.Invoke(funcA)

task2=API.Common.Task.TaskFactory.StartTask(lamda:lockor.Invoke(funcB)

结果:输出可能是01234ABCDE,也可能时ABCDE01234,但不会交错出现数字和字母。

有时候需要对任务中的部分关键区域进行同步保护,比如通道正在读写的时候,避免其他的线程使用同一个通道进行读写,则可使用一个lockor来执行需要同步保护的相关代码。

实例3:任务集合同步 (等待任意一个结束)

def  funcA():  #定义一个函数

    CH_232_1.Clear()

    b = Protocol_1.BlockRead()

def  funcB():  #定义一个函数

    bool = Protocol_2.Write()

task1=API.Common.Task.TaskFactory.CreateTask(funcA)

task2=API.Common.Task.TaskFactory.CreateTask(funcB)

tasks=API.Common.Task.TaskFactory.CreateTasks()

tasks.AddTask(task1)    #往任务集合里增加一个新任务

tasks.AddTask(task2) 

tasks.Start()    #按照集合顺序启动所有任务(并行)

tasks.WaitAny()   # 等待其中任意一个任务完成

print tasks.IsAllCompleted

结果:列表里的任意一个任务结束以后,则打印。。。。。。

假如后台执行了一些列竞争性的任务,比如任何一个任务读到一个 给定的信号以后,主测试线程就继续往下执行,则可以使用tasks.WaitAny()来达到效果。

实例4:任务集合同步 (等待所有任务结束)

def  funcA():  #定义一个函数

    CH_232_1.Clear()

    b = Protocol_1.BlockRead()

def  funcB():  #定义一个函数

    bool = Protocol_2.Write()

task1=API.Common.Task.TaskFactory.CreateTask(funcA)

task2=API.Common.Task.TaskFactory.CreateTask(funcB)

tasks=API.Common.Task.TaskFactory.CreateTasks()

tasks.AddTask(task1)    #往任务集合里增加一个新任务

tasks.AddTask(task2) 

tasks.Start()    #按照集合顺序启动所有任务(并行)

tasks.WaitAll()    #等待所有任务完成

print tasks.IsAllCompleted

结果:列表里的所有任务结束以后,则打印。。。。。。

假如后台执行了一些列任务,需要等到所有的任务执行完毕以后,主测试线程才能继续往下执行,则可以使用tasks.WaitAll()来达到效果。

    1. 字节集合操作
      1. 替换子序列

原型:newArr=Replace( arr,  flag , target)

功能:将指定序列(arr)中的子序列(flg)替换为新的目标序列(target),返回新的序列:

参数:

arr:源字节集合。

flag:需要被替换掉的子序列。

target:用来替换的目标子序列。

应用场景:希望将一组字节里的指定子序列替换为另外的内容,调用Replace方法来达到目的效果。

示例:

def Main():

    print 'Test Start'

    arr=[1,2,3,4,5,6,7,8,9]

    flag=[2,3,4]

    target=[11,12,13]

    v=API.Common.Collection.Bytes.Replace(arr,flag,target)

    print v

Main()

结果: (1,11,12,13,4,5,6,7,8,9)

      1. 映射字节集合

原型:newArr=Map(arr, func)

功能:将指定序列(arr)中的值逐个按照指定规则(func)映射到一个新的等长序列,返回新的序列。

参数:

arr:待映射的源序列

func:针对每个字节的映射规则

应用场景:将一组字节内容映射为另一组数据时(比如对所有的元素都翻倍),使用Map(arr, func)。

示例:

def Main():

    print 'Test Start'

    arr=[1,2,3,4,5]

    func=lambda a:a*2

    v=API.Common.Collection.Bytes.Map(arr, func)

    print v

Main()

结果:(2,4,6,8,10]

      1. Map方法的映射规则

原型:def func(a):

         return a*2

功能:定义Map方法的映射规则。使用Map方法时,必须定义其映射规则。

参数:

a:Map方法将为源序列中的每个元素a调用该方法进行映射。

示例:

def Main():

    print 'Test Start'

    arr=[1,2,3,4,5]

    def func(a):

      return a*2

    v=API.Common.Collection.Bytes.Map(arr, func)

Main()

结果:(2,4,6,8,10)

      1. 多规则映射

原型:Transform(arr, func)

功能:将指定序列(arr)中的逐个按照指定规则(func)输出到一个新序列,返回信息的序列:

参数:

arr:源数组

func:转换规则

应用场景:将一组字节内容映射按照多个规则为另一组数据时,使用Transform (arr, func)。   

示例:

def Main():

    print 'Test Start'

    arr=[1,2,3]

    def func(lst):

        for idx in lst:

            yield idx+1

            yield idx+2

    v=API.Common.Collection.Bytes.Transform(arr, func)

Main()

结果:(2,3,3,4,4,5)

每个原来的字节映射为两个不同的字节。

      1. Transform方法的映射规则

原型:def func(lst):

        for idx in lst:

          yield idx+1

          yield idx+2

功能:定义Transform方法的映射规则。使用Transform方法时,必须定义其映射规则。

参数:

lst:Transform方法将为源序列中的每个元素调用该方法进行映射,生成序列lst,代替原来的元素。

示例:

def Main():

    print 'Test Start'

    arr=[1,2,3]

    def func(lst):

        for idx in lst:

            yield idx+1

            yield idx+2

    v=API.Common.Collection.Bytes.Transform(arr, func)

Main()

结果:(2,3,3,4,4,5)

每个原来的字节映射为两个不同的字节。

      1. 字符串转换

原型:API.Common.Collection.Bytes.GetString(arr)

功能:将字节数组转换为对应的字符串。

参数:

arr:待转换的字节数组

示例:

def Main():

    print 'Test Start'

    arr=[55,56,57]

    str=API.Common.Collection.Bytes.GetString(arr)

    print '%s'%str

Main()

结果:789

    1. 类型转换
      1. 浮点数转字符串

原型:v= Double.ToDefaultString(d)

功能:将双精度数转换为默认的字符串格式。

参数:

d:需要转换的浮点数

返回值:该浮点数对应的默认的字符串形式。

应用场景:为了得到浮点数的默认字符串的表示形式。

示例:

def Main():

   d = 1.1

   v= API.Common.Convert.Double.ToDefaultString(1.1)

print v

Main()

结果:V的值为“1.1”

      1. 浮点数转格式后的字符串

原型:v=ToFormatString(d , format)

功能:按照指定的格式将浮点数转换为字符串

参数:

d:需要转换的字符串

format :希望转换的格式,如下格式都是有效的格式:

"C", "E", "e", "F", "G", "N", "P", "R", "#,000.000", "0.###E-000",

"000,000,000,000.00###"

返回值:格式化后的字符串

应用场景:为了得到指定格式的浮点数的字符串的表示,用来对齐,截断等处理,调用ToFormatString(d , format)获得预期的字符串。

示例:

str = Common.Convert.Double.ToFormat(11.1111D, "0000.000000")

结果:str的值为“0011.111100”

str = Common.Convert.Double.ToFormat(11.1111D, "0.0")

结果:str的值为“11.1”

执行str = Common.Convert.Double.ToFormat(11.1111D, "E")

结果:str的值为“1.111110E+001”

      1. 字符串转浮点数

原型:v=ToDouble(str)

功能:将字符串转换为双精度格式

参数:

Str:需要转换的字符串

返回值:浮点数

应用场景:为了将指定的字符串转换为对应的浮点数。

示例:

d =API.Common.Convert.String.ToDouble("-0.5")

结果:d的值为-0.5

    1. 时间调度
      1. 执行规定次数

原型:ExecuteCount(count, us, lambda:ac())

功能:在指定的时间(ms毫秒)期间执行ac指定的次数(count),返回True

参数:

count:待执行的次数

us:总时间

ac:需要执行的操作

示例:

def func():

    print 'Hello World'

def Main():

    print 'Test Start'

    count=100

    us=1000   

b=API.Common.Dispatcher.Plan.ExecuteCount(count, us, lambda:func())

Main()

结果:在1000微秒内打印100次“Hello World”

      1. 创建时间线

原型:TimeLine.Create()

功能:创建一个时间线,返回TimeLine:

示例:

def Main():

    print 'Test Start'

    tl=API.Common.Dispatcher.TimeLine.Create()

Main()

结果:生成一个空的TimeLine

      1. 增加时间节点

原型:timeline.AddSlot(ms,lambda:ac())

功能:对时间线上的指定时间点(ms)增加一个节点动作(ac):

参数:

us:时间点(微秒)

ac:在该时间点上需要执行的操作

示例:

def Print(str):

  print str

def Main():

  print 'Test Start'

  timeline=API.Common.Dispatcher.TimeLine.Create()

  timeline.AddSlot(0,lambda:Print('111'))

  timeline.AddSlot(2000,lambda:Print('222'))

  timeline.AddSlot(3000,lambda:Print('333'))

Main()

结果:在timeline的第0,2,3秒各自注册相应的操作

      1. 顺序运行

原型:timeline.Run()

功能:按照时间线上的时间顺序依次运行注册的动作。

示例:

def Print(str):

  print str

def Main():

  print 'Test Start'

  timeline=API.Common.Dispatcher.TimeLine.Create()

  timeline.AddSlot(0,lambda:Print('111'))

  timeline.AddSlot(2000,lambda:Print('222'))

  timeline.AddSlot(3000,lambda:Print('333'))

  timeline.Run()

Main()

结果:在随后的第0,2,3秒分别打印:‘111’,‘222’,‘333’。

注:从第一个点开始计时。

    1. 文件操作
      1. 打开文件

原型:TxtFileReader.Open(filename)

功能:以文本方式打开指定的文件(filename),返回打开的文件。

参数:

filename:文件名

示例:

def Main():

  print 'Hello World!'

  file=API.Common.IO.TxtFileReader.Open('D:/11.txt')

  print file

Main()

结果:file指向打开的文件

      1. 关闭文件

原型:file.Close()

功能:关闭打开的文件(file)。

示例:

def Main():

  print 'Hello World!'

  file=API.Common.IO.TxtFileReader.Open('D:/11.txt')

  file.Close()

Main()

结果:关闭file打开的文件

      1. 读取文件行

原型:file.ReadLine(base)

功能:按指定的进制(base:2,8,10,16)读取一行,返回读取到的字节数据。

示例:

# filename对应的文件内容为:

# 11 22 33 44 55 66

# 22 33 44 77 88

def Main():

  print 'Hello World!'

  file=API.Common.IO.TxtFileReader.Open('D:/11.txt')

  arr1=file.ReadLine(10)

  arr2=file.ReadLine(10)

  print arr1

  print arr2

  file.Close()

Main()

结果:[11,22,33,44,55,66]

      [22,33,44,77,88]

      1. 读取文件行

原型:arr=file.ReadLine(format)

功能:按指定的格式(format)读取一行,返回读取到的字节数组。

示例:

# filename对应的文件内容为:

# 11,22,33.22,44

# 22,33.21,12,98

# 12.3,22.4,43.21

def Main():

  print 'Hello World!'

  file=API.Common.IO.TxtFileReader.Open('D:/11.txt')

  arr1=file.ReadLine('%D,%D,%F,%D')

  arr2=file.ReadLine('%D %F %D,%D')

  arr3=file.ReadLine('X=%F,Y=%F,Z=%F')

  file.Close()

Main()

结果:[11,22,33,44]

      [22,33.21,12,98]

      [12.3,22.4,43.21]

      1. 跳过行

原型:line=file.SkipLine()

功能:跳过一行,返回跳过的内容。

示例:

# 11,22,33.22,44

# 22,33.21,12,98

# 12.3,22.4,43.21

def Main():

  print 'Hello World!'

  file=API.Common.IO.TxtFileReader.Open('D:/11.txt')

  arr1=file.ReadLine('%D,%D,%F,%D')

  arr2=file.ReadLine('%D %F %D,%D')

  line=file.SkipLine()

  print line

  file.Close()

Main()

结果:[12.3,22.4,43.21]

    1. 时钟
      1. 重置计时器

原型:API.Common.Timer.HighTimer.Reset()

示例:

def Main():

    print 'Test Start'

    API.Common.Timer.HighTimer.Reset()

    Print 'test end'

Main()

结果:时钟重置

      1. 重新开始计时

原型:API.Common.Timer.HighTimer.Restart()

示例:

def Main():

    print 'Test Start'

    API.Common.Timer.HighTimer.Restart()

    print'test end'

Main()

结果:重新开始计时

      1. 开启计时

原型:API.Common.Timer.HighTimer.Start()

示例:

def Main():

    print 'Test Start'

    API.Common.Timer.HighTimer.Start()

    print'test end'

Main()

结果:开始计时

      1. 停止计时

原型:API.Common.Timer.HighTimer.Stop()

示例:

def Main():

    print 'Test Start'

    API.Common.Timer.HighTimer.Start()

    print'111'

    API.Common.Timer.Normal.Sleep(2000)

    API.Common.Timer.HighTimer.Stop()

Main()

结果:暂停2秒后,停止计时

      1. 已经计算的时间

原型:timespan=API.Common.Timer.HighTimer.Elapsed()

格式:hh:mm:ss.XXXXXX

示例:

def Main():

    print 'Test Start'

    API.Common.Timer.HighTimer.Start()#开启计时

    API.Common.Timer.Normal.Sleep(2000)#延时2秒

    API.Common.Timer.HighTimer.Stop()  #停止计时

    b=API.Common.Timer.HighTimer.Elapsed()#已经计算的时间

    print b

    API.Common.Timer.HighTimer.Reset() #重置计时器

    a=API.Common.Timer.HighTimer.Elapsed()

    print a

Main()

结果:00:00:02.0203207

      00:00:00

      1. 当前时间

原型:time=API.Common.Timer.Normal.Now()

示例:

def Main():

    print 'Test Start'

    a = API.Common.Timer.Normal.Now()

    print a

    b = API.Common.Timer.Normal.Now()

    print b

    print b-a

Main()

结果:a为2016/9/1 11:05:23;b为2016/9/1 11:05:24;b-a为00:00:00.0560398(时间差精确到毫秒)

      1. 暂停指定时间

原型:API.Common.Timer.Normal.Sleep(ms)

参数:ms:暂停的时间,单位毫秒

应用场景:让脚本运行休眠一段时间(以毫秒为单位),多用于间断性测试。

示例:

def Main():

    print 'Test Start'

    for i in range(10):

        print hello word’

        API.Common.Timer.Normal.Sleep(2000)   

Main()

结果:每隔2秒打印一次‘hello word’,共打印10次。

    1. 工业标准(Industry

工业标准包提供工业标准相关的一些操作,包含在ETest 的API.Industry包下。

      1. 数据分发(DDS
  1. Open:初始化DDS环境

语法:b=API.Industry.DDS.Open()

返回值:True,初始化DDS环境成功;False,初始化DDS环境失败。

  1. Close:关闭清理DDS环境

语法:b=API.Industry.DDS.Close()

返回值:True,关闭清理DDS环境成功;False,关闭清理DDS环境失败。

  1. Pulish:发布主题

语法:topicID=API.Industry.DDS.Publish(topicName)

topicName:主题名,用户在使用前做个声明,如:

topicName=“开关数据”

topicID:主题ID

  1. CancelPublish:取消发布主题

语法:b=API.Industry.DDS.CancelSubscribe(topicName)

返回值:True,取消发布主题成功;False,取消发布主题失败。

  1. SendData:向指定主题写入数据

语法:b=API.Industry.DDS.SendData(topicID, buffer)

返回值:True,向指定主题写入数据成功;False,向指定主题写入数据失败。

Buffer:数组。例如:[11,22,33]。

  1. Subscribe:订阅制定的主题

语法:b=API.Industry.DDS.Subscribe(topicName, SubscribeFunc_1)

返回值:True,订阅制定的主题成功;False,订阅制定的主题失败。

  1. SubscribeFunc:订阅数据处理方法

示例:

def SubscribeFunc_1(topicName,data):

  print '主题名:%s'%topicName

  print '数据长度%d'%data.Length

  1. CancelSubscribe:取消订阅制定的主题

语法:b=API.Industry.DDS.CancelSubscribe(topicName)

返回值:True,取消订阅制定的主题成功;False,取消订阅制定的主题失败。

      1. SLIP协议编解码
  1. 将字节数据(data)转换为编码为SLIP格式:

语法:arr=API.Industry.Slip.Encode(data, startC0)

示例:

def Main():

  print 'Test Start'

  startC0=True

  data=[0XFE, 0X00, 0XFF, 0XDB, 0XFF, 0XC0]

  arr=API.Industry.Slip.Encode(data, startC0)

  print arr

Main()

操作结果:Arr内容为字节数组[C0,FE,00,FF,DB,DD,FF,DB,DC,C0]

  1. 将SLIP数据解码:

语法:arr=API.Industry.Slip.Decode(data, startC0)

示例:

def Main():

  print 'Test Start'

  startC0=True

  data=[0XC0, 0XFE, 0X00, 0XFF, 0XDB, 0XDD, 0XFF, 0XDB,0XDC, 0X04, 0XB3, 0XC0]

  arr=API.Industry.Slip.Decode(data, startC0)

  print arr

Main()

操作结果:Arr内容为字节数组[FE,00,FF,DB,FF,C0,04,03]

    1. 第三方相关(ThirdParty

第三方相关包提供第三方引擎常用操作,包含在ETest 的API.Thirdparty包下。

      1. Matlab引擎
  1. Open打开Matlab引擎

语法:API.ThirdParty.Matlab.Engine.Open()

  1. Close关闭Matlab引擎

语法:API.ThirdParty.Matlab.Engine.Close()

  1. Excute执行Matlab脚本

语法:b=API.ThirdParty.Matlab.Engine.Excute(script)

Script为matlab脚本(命令)。

  1. GetVariable从Matlab引擎环境中获取变量

语法:v=API.ThirdParty.Matlab.Engine.GetVariable(name)

Name表示变量名称

      1. Simulink仿真模型
  1. SourceInput启动平台侧的输入组件

语法:task=API.ThirdParty.Matlab.Simulink.SourceInput(SourceHandler)

  1. SourceHandler输入组件的模板函数

示例:

def SourceHandler(arr)

  #为arr[0],arr[1]...设置对应的浮点值

  arr[0]=1.0

  arr[1]=2.0

  arr[2]=3.0

  …

  

  1. SinkOutput启动平台侧的输出组件

语法:task=API.ThirdParty.Matlab.Simulink.SinkOutput(SinkHandler)

  1. SinkHandler输入组件的模板函数

示例:

def SinkHandler(arr)

  #使用arr[0],arr[1]...里的值(浮点)

  print arr[0]

  print arr[1]

  print arr[2]

  …

  1. StartModel启动Simulink模型

语法:b=API.ThirdParty.Matlab.Simulink.StartModel(filename, content)

示例:

#jp = 0;
def SourceHandler(arr):
  #参数1是从ETestRT发过来的数,形成闭环
  print '1'
  bool=Protocol_In.BlockRead()
  arr[1]= Protocol_In.name.Value
  #参数0是手动从调试助手发过来的数,是信号激励
  bool=Protocol_1.Read()
  if(bool):
       arr[0]=Protocol_1.name.Value
#       arr[0] =jp
       
def SinkHandler(arr):
  print '2'
  Protocol_Out.name.Value=arr[0]
  bool=Protocol_Out.Write()

def sim():
      extdata=ExtData.二进制文件_1
      print extdata
      b=API.ThirdParty.Matlab.Simulink.StartModel('quikdemo', extdata.Content)
      print b

def main():           
      task=API.Common.Task.TaskFactory.StartTask(sim)
      task2=API.ThirdParty.Matlab.Simulink.SourceInput(SourceHandler)
      task3=API.ThirdParty.Matlab.Simulink.SinkOutput(SinkHandler)
      task2.Wait()
      task3.Wait()
main()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值