首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

使用 Python 在 Linux 上实现一键回归测试-2

使用 Python 在 Linux 上实现一键回归测试-2

也谈界面设计 ---- getopt 的使用在日常的测试过程中,我们并不是每次都要迁出代码,编译代码,运行测试用例和收集测试结果。这样就需要我们能够有选择的运行部分程序功能,例如只运行测试用例和收集结果。这里我们提供了 4 个运行选泽:
     选项 1:迁出代码-->编译版本-->运行测试用例-->收集测试结果
     选项 2:更新代码-->编译版本-->运行测试用例-->收集测试结果
     选项 3:编译版本-->运行测试用例-->收集测试结果
     选项 4:运行测试用例-->收集测试结果
当然我们还需要提供帮助信息,以方便不熟悉该脚本实现的人员使用。python 也提供了 getopt 模块让我们轻松实现上述功能。实现代码参见清单 9
清单 9. 命令行写解析代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
try:
   opts, args = getopt.getopt(sys.argv[1:], 'bchu', ['build', 'checkout', 'help', 'update'])
    except getopt.error, msg:
        self.usage()
        sys.exit(2)

    build_flag = 0 #构建选项
    for o, a in opts:
        if o in ('-h', '--help'):
            self.usage()
            sys.exit()
        elif o in ('-c', '--checkout'):
            print "执行操作:迁出代码-->编译版本-->运行测试用例-->收集测试结果"
            build_flag = 1
            break
        elif o in ('-u', '--update'):
            print "执行操作:更新代码-->编译版本-->运行测试用例-->收集测试结果"
            build_flag = 2
            break
        elif o in ('-b', '--build'):
            print "执行操作:编译版本-->运行测试用例-->收集测试结果"
            build_flag = 3
            break
        else:
            self.usage()
            sys.exit()
     if (0 == build_flag) :
        if 2 <= len(sys.argv):
            self.usage()
            sys.exit()

    raw_input('\n 按 Enter 键继续。。。(Ctrl+C 退出)\t')
        
    if (1 == build_flag) : #迁出代码,并编译代码
        self.checkout_code()
        self.build_code()
    elif (2 == build_flag) : #更新代码,并编译代码
        self.update_code()
        self.build_code()
    elif (3 == build_flag) : #编译代码
        self.build_code()

    #运行测试用例并收集运行结果
    self.set_python()
    self.run_testsuite()
    self.store_logs()




如果我们在运行的过程中想中断(如利用 Ctrl+C)一键回归测试进程的执行时,有时我们会发现虽然主进程已经被终止,但子进程仍在运行。我们能否在中断主进程的同时也中断子进程呢?答案当然是肯定的,我们可以用信号处理函数捕获信号(如捕获 Ctrl+C 产生的中断信号),然后在显式终止对应的子进程。这里就需要我们在创建子进程的时候,先保存子进程 ID,当然把子进程 ID 保存到初始化函数中,是个不错的选择,清单 10 是相关实现。
清单 10. 信号处理代码
1
2
3
4
5
# 终止子进程的运行
def handler(self, signum, frame):
    if (-1 != self.subproc_id) : #subproc_id 定义在初始化函数中,用来存储当前子进程的 ID
        os.killpg(self.subproc_id, signal.SIGINT)
    sys.exit(-1)




这里我们需要在初始化函数中注册要捕获的信号,并且创建成员变量用来保存子进程的 ID,详细实现请参见清单 11。
基于对象的设计 ---- class 的使用最后终于轮到 class 登场了,提到 class 我们就不能不谈构造函数(初始化函数)和析构函数。之前我们多次提到初始化函数,初始化函数允许我们定义一些变量,这些变量在整个类对象的生存周期内均有效。由于本文没有向系统申请资源,就再不定义析构函数了。
清单 11. 初始化处理代码
1
2
3
4
5
6
7
8
9
def __init__(self):
    signal.signal(signal.SIGINT, self.handler) #注册需要捕获的信号量
    self.myafs_dir = os.getenv('myafs')
    self.subproc_id = -1 #子进程 ID,用来在终止主进程时也同时终止子进程
    self.debug_log = 'log.txt' #存储详细运行日志的文件名
    self.debug_fullname = os.getcwd() + os.sep + self.debug_log #全路径文件名(假设产生在该目录下)
    self.sum_log = 'summary' #存储汇总日志的文件名
    self.sum_fullname = os.getcwd() + os.sep + self.sum_log #全路径文件名(假设产生在当前目录下)
    self.share_dir = self.utafs_dir + '/SharedFiles' #共享目录文件名




通常我们不需要太关注设计风格,只要 Python 脚本能完成我们的测试要求即可。对于较小的脚本,几条 Python 指令顺序执行即可。为了模块功能复用和可读性,我们通常会把功能模块封装成函数。本文将实现的所有函数都封装到一个类中,使得该脚本更加一体化。
清单 12. class 框架结构代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class COneClickRegTest:
    #设定一些经常使用的变量,如当前工作目录,日志名称、存储路径等
    def __init__(self):

    #设定 python 环境变量,实现参见代码文件
    def set_python(self):

    #更新代码,实现参见代码文件
    def update_code(self):

    #迁出代码,实现参见第 2 章代码
    def checkout_code(self):
     
    #编译版本,实现参见清单 1 代码
    def build_code(self):

    #运行测试集,实现参见代码文件
    def run_testsuite(self):

    #存储运行结果,实现参见清单 7 和清单 8 代码
    def store_logs(self):
  
    #信号处理,实现参见清单 10 代码
    def handler(self, signum, frame):

    #脚本使用说明,实现参见代码文件
    def usage(self):

    #命令行解析以及执行对应的功能,实现参见清单 9 代码
    def main(self):




结束语Python 语言是一个易学易用的脚本语言,笔者没有多久的 Python 开发经验,不过其他语言有的功能在 Python 中大都可以找到对应的实现,这也是笔者能够在很短的时间内完成该测试脚本的原因。因此,笔者把该语言和使用该语言完成一键回归测试介绍给大家,希望对大家有所帮助。正像笔者说的其他语言有的功能在 Python 中大都可以找到对应的实现,同样,如果大家对某一种特定的脚本语言或者开发语言特别熟悉,也完全可以采用所熟悉的语言来完成一键回归测试的工作。
返回列表