导语

        在探索框架(二)--框架设计及使用HTMLTestRunner生成测试报告中总结框架的设计,本次记录在此基础上来设计驱动程序,后续只需要执行驱动程序,即可运行相关的脚本。

一、回顾框架运行过程

        框架的运行过程:由框架驱动层中的测试驱动程序运行,依据配置层相关的设置,调用对应的脚本层,执行脚本,相关脚本运行时,如果需要测试数据,则会读取数据层的对应文件,测试结束后,会输出相应的测试报告存放于报告层。

二、设计思路

        对于能力不强的小白来说,无论是编写脚本还是设计程序,核心要点都是由简入繁,在这里,要实现框架驱动程序,需要先选定一种框架程序调用的方式,这次决定选用“defaultTestLoader”来调用脚本,在探索框架(一)--unittest框架(Python)中也总结了具体的用法,这里不再多记录了。

        选定了调用脚本模式,再思考调用的脚本问题,脚本依据框架目录,存放在不同的目录中,文件名也并不一样,这样可以先用固定的常量值来进行脚本调试,调试成功后,再将常量值改为变量值。(注:这里所说的常量值,主要是指驱动程序需要调用的测试用例脚本的路径和文件名)

三、使用常量值编写驱动程序

        先准备好相关测试用例脚本,比如以下的样例脚本,用于调试工作:

import unittest


class test_login(unittest.TestCase):
    def test_case1(self):
        print("登录脚本")


if __name__ == '__main__':
    unittest.main()

        接下来编写驱动程序来调用此脚本,代码如下:

import unittest

if __name__ == '__main__':
    scriptpath = "C:\\Users\84187\PycharmProjects\pythonProject\\test_script\ind_test"
    scriptname = "test_login.py"
    discover = unittest.defaultTestLoader.discover(scriptpath, pattern=scriptname)
    working = unittest.TextTestRunner()
    working.run(discover)

        运行以后,脚本并无问题,可以看到打印的“登录脚本”字样,接下来进行下一步。

四、使用变量值编写驱动程序

1、变更驱动程序脚本

        本次使用读取CSV文件方式来动态读取脚本路径和脚本文件名,设计如下的CSV文件(图1),并存放于config层中:


python开发pcie驱动 python驱动层开发_python

图1 config1

        关于读取CSV文件中的数据,在之前做接口自动化测试中已经反复练习过,这里可以直接编写了,代码如下:

import csv
import unittest

if __name__ == '__main__':
    projectpath = "C:\\Users\84187\PycharmProjects\pythonProject"
    configfile = open(projectpath + "\config\config1.csv", "r")
    table = csv.reader(configfile)
    num = 0
    for ele in table:
        num = num + 1
        if num > 1:
            scriptpath = ele[0]
            scriptname = ele[1]
            discover = unittest.defaultTestLoader.discover(scriptpath, pattern=scriptname)
            working = unittest.TextTestRunner()
            working.run(discover)
    configfile.close()

        这里说明一下设置num这个变量,是为了跳过第一行,实际的脚本路径和文件名是从第二行开始编写的。运行程序,结果报错了,报错信息如下:


python开发pcie驱动 python驱动层开发_文件名_02

图2 报错信息1

         看报错信息"Path must be within the project"觉得一头雾水,在文件中是写明了完整的脚本路径的呀,为什么会有这样的报错呢?现在尝试将CSV文件中只保留一行登录的路径和文件名数据,再次运行驱动程序,结果运行成功了,再次加上其他的数据后运行驱动程序,仍然提示相同的报错信息,这是什么原因呢?

2、Python中的discover函数

        经过查找资料可知,目前我使用了discover(scriptpath, pattern=scriptname)中的两个参数,其实还有一个参数top_level_dir=None,默认为None,如果discover中没有传top_level_dir时,则在第一次运行时会取当前传入的文件路径作为top_level_dir,并保存下来,在第二次运行时仍然使用上次的路径,这样就会报错。

        回头再次查看相关脚本的情况,脚本层如图3所示,“test_forgetpassword.py”和“test_login.py”脚本在不同的目录中。


python开发pcie驱动 python驱动层开发_python_03

图3 脚本层

         规避这样的方法,给top_level_dir赋值脚本层的路径,即top_level_dir=projectpath + "\\test_script",加上这个参数以后,程序就可以成功运行了。

        这样就实现了驱动程序的动态参数,以后只需要维护config.csv文件即可,那再加上一个真实的业务脚本(加上之前接口自动化中已经编写好的脚本test_updateinform2.py),再来执行驱动程序验证一下。

3、注意脚本中的调用数据层目录问题

        加入了test_updateinform2.py脚本数据以后,运行驱动程序,又报错了o(╥﹏╥)o,报错不可怕,再来分析分析,报错内容如下(图4):


python开发pcie驱动 python驱动层开发_驱动程序_04

图4 报错信息2

         问题确实是出在新加的test_updateinform2.py脚本数据上,单独去运行test_updateinform2.py这个脚本,是可以正确运行的,但是利用驱动程序来调用此脚本,则报错,报错指向的这个不存在的文件是数据层中的一个CSV文件,看样子是读取的目录有问题,回头查看一下test_updateinform2.py中的部分代码如下:

class test_updateinform2(unittest.TestCase):
    def setUp(self):
        curpath = os.getcwd()
        print("curpath=", curpath)
        farpath = os.path.abspath(os.path.dirname(curpath) + os.path.sep + "..")
        print("farpath=", farpath)
        self.filepath = farpath + "\\test_data\ind_data\\test_updateinform.csv"
        print("self.filepath=", self.filepath)
        userinfo = {}
        updatefile = open(self.filepath, "r")
......
......

        在脚本中加入了一些print语句,来查看此脚本中正确的文件路径是什么,结果如下:


python开发pcie驱动 python驱动层开发_python开发pcie驱动_05

图5 测试用例输出的正确的文件路径

         再来执行驱动程序,查看运行驱动程序时,输出的错误路径是什么,结果如下:


python开发pcie驱动 python驱动层开发_驱动程序_06

图6 驱动程序输出的错误的文件路径

         对比图5和图6,就可以发现问题所在了,利用驱动程序来调用脚本时,curpath这个参数获取的当前路径是以驱动程序的位置来获取的,而在独立脚本test_updateinform2.py中curpath这个参数获取当前路径是以独立脚本所在的位置来获取的,这样去获取父路径farpath就存在路径的差别。定位到了问题所在,只需要修改一下fapath即可,独立脚本中获取farpath需要往上倒两层(“..”),而驱动程序在框架设计中少一层,只需要往上找一层即可(“.”),修改如下:

farpath = os.path.abspath(os.path.dirname(curpath) + os.path.sep + ".")

        再次运行驱动程序,即可正确运行了,从这个例子中可以看出,驱动程序的调试中,需要格外注意调用路径的问题,遇到报错时不要慌,不清楚的时候将相关内容print出来,对比找出问题原因即可。

4、优化config.csv文件

        实际中,可能不需要每次都执行所有的测试用例,那么可以再优化一下confing.csv的设计,修改如下:


python开发pcie驱动 python驱动层开发_自动化_07

图7 config.csv优化

         增加了“是否执行”一列,关于“是否执行”这个参数的程序判断较为简单,后续只需要维护config.csv文件,即可方便的管理运行哪些程序。驱动程序的修改部分,只需要修改循环读取文件的判断语句即可,代码如下:

......
......
table = csv.reader(configfile)
    num = 0
    for ele in table:
        num = num + 1
        if num > 1 and ele[2] == "yes":
......
......

五、总结

        本次总结记录了基于框架编写驱动程序的过程,由简入繁,并重新学习了Python中的discover函数的参数,以及发现了驱动程序调试的一个难点,关于调用脚本时涉及到相关路径问题。

        每次遇到一个问题,尝试去解决这个问题,又会进步一点点,后续会继续记录总结学习之路的情况。