自動化テスト環境の柔軟な構成


概要
自動化テストの環境は変わらないわけではありません.良い設計がなければ、環境が変化すると、修正作業量が膨大になります.良い設計では、数行のコードを変更するだけです.ネットワークデバイスのテストでは、環境構成を個別のテキストファイルに配置し、自動化スクリプトを使用して読み込むことを考慮できます.テキストの設計は簡単で分かりやすく、拡張しやすく、スクリプトは使いやすく、例えば名前が短いと進度を速め、エラーを減らすことができます.例えば、pcのあるNICのIpを読み取るには、pc 1を用いることができる.port1.ipは、別途PCを設けるNIC IPがpc 2であってもよい.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()