python学习重温(1)自动case生成工具

摘要:
因为在最近的工作中,我们需要设计一个小工具,根据Wireshark截获的消息自动生成测试用例。我复习了Python。本说明根据该工具的实现记录了python语法的学习过程。一般变量由第一个赋值生成,当它们超出操作范围时自动消亡。因为Python中没有struct这样的东西,当然,Python可以用类的方法替换struct。

因为最近工作中,需要设计根据wirshark截获的报文自动产生测试case的小工具,我重温了python。这个笔记,就是根据这个工具的实现,来记录python语法的学习过程。

这个工具的功能如下图所示,其中wirshark cap可以通过wirshark自身的功能导出为pmsl格式,也就是一种XML,同时公司使用的case script也是一种XML,只是添加了一些循环,判断等功能。

python学习重温(1)自动case生成工具第1张

所以这个工具涉及文件操作,XML解析和一些python的基本语法功能

一、PYTHON 基本语法概念

1.什么是main函数

if __name__ == "__main__":

上面这个就是python的main函数的声明

2. 变量申明

python对变量申明不像那么严格,但也不像shell那么随便。一般变量通过首次赋值产生,当超出作用范围时自动消亡。这几句话的意思是,变量如果要使用就一定要先给他赋值。比如

print str1

一定会报错

Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    print str1
NameError: name 'str1' is not defined

所以一定要先赋值

str1 = 'hello'
print str1

python一样有全局变量和局部变量的概念。

3. python 常用的变量类型

数值型

value = 12

string

str1 = 'hello'
str1 = "hello"

这里有个双引号还是单引号的问题,我的理解是除非设计转义字符,两者都是一样的。

a = 'let\'s us'
a = "let's us"

list

也就是C语言中的数组

a = ['spam', 'eggs', 100, 1234]

支持下标访问

a[0]
a[1]

Dictionary

大家称呼这个味字典型,其实可以类比为C语言中的结构体。因为python里面是没有struct这类东西的,当然python可以用class的方法替代struct。但Dictionary这个类型也可以在某些时候当做struct这个概念来用

d = {"server":"mpilgrim", "database":"master"}

这个类型是可以作为不同类型数据的container的,但要注意一个问题dictionary在插入的时候是乱序的,也就是说当我做

d["newdata"]='fda'

这个操作后,这个新加入的项会随机加在d中,不一定在最后。
4.Python的层次结构
python依靠代码缩进和:来确定代码的前后层次关系
如下面这个函数,缩进起到了C语言中{}的作用。

def GetEnumName(attribename,valuestr):
    """
    
    @author: limim
    
    @param attribename:attribname 
    @type attribename:str
    @param valuestr:mmt log value
    @type valuestr:str
    @return:the enum name
    @rtype:str
    """
    tree = ReadFromXml('PegasusEnumMapping.xml')
    root = tree.getroot()
    value = str(int(valuestr,16))
    errorret = ''
    for listnode in root.iter('attrib'):
        strlist = listnode.attrib['name'].split('.')
        attriblist = attribename.split('.')
        substrlist = strlist[(len(strlist)-4):]
        subattriblist = attriblist[(len(attriblist)-4):]
        if substrlist == subattriblist:
            for enumlistnode in listnode:
                if enumlistnode[0].text == value:
                  return enumlistnode[1].text
                else:
                  errorret = enumlistnode[1].text
    print "error"
    print attribename
    print 'mmt log value' + ' ' + valuestr
    print 'set default value' + ' ' + errorret
    print '##############'
    return errorret

二、elementTree

这个工具处理的主要文件格式是XML,就用elementTree这个库来处理,下面是要处理文件格式的一部分。

<?xml version="1.0"?>
<pdml version="0" creator="wireshark/1.20.0.1">
<packet>
  <proto name="geninfo" pos="0" showname="General information" size="98">
    <field name="num" pos="0" show="1246" showname="Number" value="4de" size="98"/>
    <field name="len" pos="0" show="98" showname="Frame Length" value="62" size="98"/>
    <field name="caplen" pos="0" show="98" showname="Captured Length" value="62" size="98"/>
    <field name="timestamp" pos="0" show="Mar  6, 2013 18:28:28.729395000 China Standard Time" showname="Captured Time" value="1362565708.729395000" size="98"/>
  </proto>
  <proto name="frame" showname="Frame 1246: 98 bytes on wire (784 bits), 98 bytes captured (784 bits)" size="98" pos="0">
    <field name="frame.time" showname="Arrival Time: Mar  6, 2013 18:28:28.729395000 China Standard Time" size="0" pos="0" show="Mar  6, 2013 18:28:28.729395000"/>
    <field name="frame.time_epoch" showname="Epoch Time: 1362565708.729395000 seconds" size="0" pos="0" show="1362565708.729395000"/>
    <field name="frame.time_delta" showname="Time delta from previous captured frame: 0.000475000 seconds" size="0" pos="0" show="0.000475000"/>
    <field name="frame.time_delta_displayed" showname="Time delta from previous displayed frame: 0.000000000 seconds" size="0" pos="0" show="0.000000000"/>
    <field name="frame.time_relative" showname="Time since reference or first frame: 93.072253000 seconds" size="0" pos="0" show="93.072253000"/>
    <field name="frame.number" showname="Frame Number: 1246" size="0" pos="0" show="1246"/>
    <field name="frame.len" showname="Frame Length: 98 bytes (784 bits)" size="0" pos="0" show="98"/>
    <field name="frame.cap_len" showname="Capture Length: 98 bytes (784 bits)" size="0" pos="0" show="98"/>
    <field name="frame.marked" showname="Frame is marked: False" size="0" pos="0" show="0"/>
    <field name="frame.ignored" showname="Frame is ignored: False" size="0" pos="0" show="0"/>
    <field name="frame.protocols" showname="Protocols in frame: eth:ip:udp:mmtss:sicap" size="0" pos="0" show="eth:ip:udp:mmtss:sicap"/>
    <field name="frame.coloring_rule.name" showname="Coloring Rule Name: SICAP" size="0" pos="0" show="SICAP"/>
    <field name="frame.coloring_rule.string" showname="Coloring Rule String: sicap" size="0" pos="0" show="sicap"/>
  </proto>
  <proto name="eth" showname="Ethernet II, Src: 192.168.254.1 (00:0f:bb:69:93:ee), Dst: DCT-INF (00:10:18:cb:b5:fd)" size="14" pos="0">
    <field name="eth.dst" showname="Destination: DCT-INF (00:10:18:cb:b5:fd)" size="6" pos="0" show="00:10:18:cb:b5:fd" value="001018cbb5fd">
      <field name="eth.addr" showname="Address: DCT-INF (00:10:18:cb:b5:fd)" size="6" pos="0" show="00:10:18:cb:b5:fd" value="001018cbb5fd"/>
      <field name="eth.ig" showname=".... ...0 .... .... .... .... = IG bit: Individual address (unicast)" size="3" pos="0" show="0" value="0" unmaskedvalue="001018"/>
      <field name="eth.lg" showname=".... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)" size="3" pos="0" show="0" value="0" unmaskedvalue="001018"/>
    </field>
    <field name="eth.src" showname="Source: 192.168.254.1 (00:0f:bb:69:93:ee)" size="6" pos="6" show="00:0f:bb:69:93:ee" value="000fbb6993ee">
      <field name="eth.addr" showname="Address: 192.168.254.1 (00:0f:bb:69:93:ee)" size="6" pos="6" show="00:0f:bb:69:93:ee" value="000fbb6993ee"/>
      <field name="eth.ig" showname=".... ...0 .... .... .... .... = IG bit: Individual address (unicast)" size="3" pos="6" show="0" value="0" unmaskedvalue="000fbb"/>
      <field name="eth.lg" showname=".... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)" size="3" pos="6" show="0" value="0" unmaskedvalue="000fbb"/>
    </field>
    <field name="eth.type" showname="Type: IP (0x0800)" size="2" pos="12" show="0x0800" value="0800"/>
  </proto>

1. 文件读取

from xml.etree.ElementTree import ElementTree, Element
import sys

def ReadFromXml(path):
    ''''read from xml and prase it
        author:limin 
        path: the file path
        return ElementTree'''
    tree = ElementTree()
    tree.parse(path);
    return tree

通过

tree = ElementTree()
tree.parse(path);

就获得了XML文件的指针

python学习重温(1)自动case生成工具第2张

在调试模式下,可以看到tree就是根据读入的XML文件用不同层级的NODE构成的结构体。这个时候操作就很方便了,我们可以先拿到root,在遍历整个tree就可以方便的读取XML中任意一个节点的attrib,text,tag这些内容。

    
def ReadPacketContent(tree,framenum):
    '''
    read the packet content
    node:the xml node
    num: the index of the node
    '''
    SicCapMessage = []
    root = tree.getroot()   #check the boundary
    num = 0
    flag = 0
    for node in root:  # proto level node
      if flag == 1:
        break
      num = num + 1
        #print protonode.tag,protonode.attrib
      for protonode in node: 
        if protonode.attrib['name'] == 'frame':
          frameList = parseFrameHead(protonode)
          if frameList[1] != str(framenum):
            break
          else:
            SicCapMessage.insert(0,frameList)
            print "find the frame, number is" + frameList[1] 
            flag = 1
    print num
    print len(root)
    if num == 0 or num > len(root) - 1:
       print "can not find the frame num"
       return SicCapMessage
    
    for protonode in root[num - 1]:
        if protonode.attrib['name'] == 'sicap':
            #dictPrint(parseSiCapMessage(protonode))
            SicCapMessage.extend(parseSiCapMessage(protonode))
        
    return SicCapMessage

可以看到

protonode.attrib

就是一个dictionary类型的变量

2.文件写入

读取的问题解决了,剩下的就是写入了。只用调用

tree.write('test.xml','UTF-8')

就可以将内存中的tree写入文件

免责声明:文章转载自《python学习重温(1)自动case生成工具》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇vc自定义类设置按钮的字体和颜色NTFS多流文件、结构化存储和摘要属性集合下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

五. python 字符串方法函数

一 .字符串方法函数 什么是字符串就是以 单引号或者双引号引起来的任意文本'ancask的库时时刻刻'"ABC事实就是惊声尖叫 1. 创建字符串: str1="abcde骨灰盒fgaa" str2="abcde吾问无为谓fgaa" str3="abcdefg少时诵诗书所所aa" 2.字符串运算连接 str6="SKSDK就是死你KsbDSKDKSKK" s...

Python使用Redis

Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。Redis支持存储的value类型包括字符串(String), 哈希(Hash), 列表(list), 集合(set) 和 有序集合(sorted set)。 Redis官方文档:https://redis.io Red...

Coverage测试代码覆盖(Python)

Coverage 测试代码执行率1、安装coverage 命令行:pip install coverage2、将测试代码放到一个盘符下,如:D:\test测试代码:Calc.py# coding=utf-8class Calc(object): def add(self, x, y, *d):# 加法计算result = x + yfor i in d:r...

NLP常用Python开发工具

一、Numpy NumPy系统是Python的一种开源的数值计算包。 包括: 1、一个强大的N维数组对象Array; 2、比较成熟的(广播)函数 库; 3、用于整合C/C++和Fortran代码的工具包; 4、实用的线性代数、傅里叶变换和随机数生成函数。 numpy和稀疏矩阵运算包scipy配合使用更加方便。 安装: pip install numpy 二...

python3去除行号

问题:在复制一些代码时会同时复制每行的行号,删除比较麻烦,所以利用python3本身的代码进行一键删除。 # 导入re 模块来使用正则表达式 import re """去掉行号""" print('remove application start') # 定义去除行号函数 def remove_line_num(instr): p = re.co...

vsCode如何将结果输入到调试控制台

vsCode编写python代码运行时,结果在终端显示,但是里面结果显示不清楚,有多余信息,那么如何只输出代码结果呢? 点击启动调试,点击下图红圈位置 ,出现launch.json文件,修改launch.json中的console,因为 none 不是 ''console'' 的默认选项, 根据 launch.json 里面对应参数的提示 ''conso...