概述
自动化测试的环境并不是一成不变的,如果没有好的设计,一旦环境发生变化,修改工作量将十分庞大。而好的设计则只需要修改几行代码。
在网络设备的测试中,可以考虑将环境配置放在一个单独的文本文件,再使用自动化脚本读取。
文本的设计要简单易懂,容易扩展,脚本则要使用方便,比如名字短可以加快进度,减少错误。
比如读取pc某个网卡的Ip, 可以用pc1.port1.ip, 设置另外PC的网卡IP可以是pc2.port2.ip = '1.1.1.1'.
难点
代码的难点在于使用文本中的字符串来动态创建实例名。
在其他module调用时可以直接调用实例名,不需要module name.
下面的实现过程感觉并不优美,欢迎大家讨论和指教。
配置文件
# file name config
[pc1]
usr=root
pwd=abc
port0_name=eth0 ; # port0 is manager port
port0_ip=192.168.1.1
port1_name=eth1 ; # portx, test port,
port1_ip=211.1.1.1
port1_mask=16
port1_gateway=211.1.1.2
[pc2]
usr=root
pwd=1234
port0_name=eth0 ; # port0 is manager port
port0_ip=192.168.1.2
port1_name=eth1 ; # portx, test port,
port1_ip=211.2.1.1
port1_mask=16
port1_gateway=211.2.1.2
Port类
# file name port.py
""" define port attribute """
class Port(object):
def __init__(self, **kwargs):
for key in kwargs:
setattr(self, key, kwargs[key])
PC类
# file name pc.py
""" define what ports are contained on pc and exec command on pc """
import port
class PC(object):
def __init__(self, **kwargs):
for key in kwargs:
setattr(self, key, kwargs[key])
def connect(self):
pass
读取配置文件
# file name config.py
"""read environment config file, create pc and port object, """
import ConfigParser
import pc
import port
class ReadConifg(object):
def __init__(self, file):
self.file = file
self.cf = ConfigParser.ConfigParser()
self._read_config()
self.read_config()
def read_config(self):
"""pc object is global object"""
self.cf.read(self.file)
for section in self.cf.sections():
# create global object pcx
exec("%s = pc.PC()" % section) in globals()
options = self.cf.items(section)
port_dict = {}
for option in options:
key = option[0]
value = option[1]
if key.find('_') > -1:
key_list = key.split('_')
port_object_name = key_list[0]
new_key = key_list[1]
if port_object_name in port_dict:
port_dict[port_object_name] = port_dict[port_object_name] + [(new_key, value)]
else:
port_dict[port_object_name] = [(new_key, value)]
else:
# pcx.key = value
# pc1.usr = root
setattr(globals()[section], key, value)
for key in port_dict:
# create port object
exec("%s = port.Port()" % key)
for line in port_dict[key]:
(new_key, new_value) = line
# portx.new_key = new_value
# port1.name = eth1
setattr(locals()[key], new_key, new_value)
# add port objetc to pc object, pcx.portx = portx
setattr(globals()[section], key, locals()[key])
def _read_config(self):
"""add pc object to self"""
self.cf.read(self.file)
for section in self.cf.sections():
options = self.cf.items(section)
port_dict = {}
key_value = ""
for option in options:
key = option[0]
value = option[1]
if key.find('_') > -1:
key_list = key.split('_')
port_object_name = key_list[0]
new_key = key_list[1]
if port_object_name in port_dict:
port_dict[port_object_name] = port_dict[port_object_name] + [(new_key, value)]
else:
port_dict[port_object_name] = [(new_key, value)]
else:
key_value += "%s='%s', " % (key, value)
for key in port_dict:
# create port object
exec("%s = port.Port()" % key)
for line in port_dict[key]:
(new_key, new_value) = line
# portx.new_key = new_value
# port1.name = eth1
setattr(locals()[key], new_key, new_value)
key_value = key_value[:-2]
# create pc object
exec("%s = pc.PC(%s)" % (section, key_value))
for key in port_dict:
# add port object to pc object
setattr(locals()[section], key, locals()[key])
# add pc object to self
setattr(self, section, locals()[section])
使用环境变量
# file name main.py
""" define packet action """
import config
import pc
import port
CONFIG_FILE = 'config'
rc = config.ReadConifg(CONFIG_FILE)
# to use pcx.yy directory
from config import *
class Packet(object):
def __init__(self, **kwargs):
for key in kwargs:
setattr(self, key, kwargs[key])
def send(self):
print pc2.port1.name
if __name__ == "__main__":
p = Packet(a=3)
print pc1.usr
print pc1.port1.ip
p.send()