zoukankan      html  css  js  c++  java
  • (三十五)什么是自动化测试模型之数据驱动测试实例

    随笔记录方便自己和同路人查阅。

    #------------------------------------------------我是可耻的分割线-------------------------------------------

      学习selenium自动化之前,最好先学习HTML、CSS、JavaScript等知识,有助于理解定位及操作元素的原理。关于python和selenium安装请自行搜索别的资料,这里就不多做介绍了,所有例子均使用python3.6+selenium执行的。

    #------------------------------------------------我是可耻的分割线-------------------------------------------

      数据驱动测试实例

      前面提到关于数据驱动的形式有很多,我们既可以通过定义变量的方式进行参数化,也可以通过定义数组、字典的方式进行参数化,还可以通过读取文件(txtcsv]xml)的方式进行参数化,我们通过一些例子来展示数据驱动在自动化测试中的应用。

      参数化邮箱登录

      同样以126邮箱的登入为例,现在的需求是测试不同用户的登录。对于测试用例来说,不变的是登录的步骤,变化的是每次登录的用户名和密码,这种轻卡下就需要用到数据驱动方式来编写测试用例。新建public.py文件

    class Login():
        def user_login(self,driver,username,password):
            #登录
            driver.find_element_by_id('idInput').clear()
            driver.find_element_by_id('idInput').send_keys(username)
            driver.find_element_by_id('pwdInput').clear()
            driver.find_element_by_id('pwdInput').send_keys(password)
            driver.find_element_by_id('loginBtn').click()
    
        def user_logout(self,driver):
            driver.find_element_by_link_text('退出').click()
            driver.quit()

      在user_login()方法中增加usernamepassword的入参,将得到的具体参数作为登录时的数据。

      新建mailTest.py文件

    from selenium import webdriver
    from public import Login
    class LoginTest():
        def __init__(self):
            driver = webdriver.Chrome()
            driver.implicitly_wait(10)
            driver.get("http://www.126.com")
    
        #admin用户登录
        def test_admin_login(self):
            username = 'admin'
            password = '123'
            Login().user_login(self.driver,username,password)
            self.driver.quit()
        
        #guest用户登录
        def test_guest_login(self):
            username = 'guest'
            password = '321'
            Login().user_login(self.driver, username, password)
            self.driver.quit()
            
    LoginTest().test_admin_login()
    LoginTest().test_guest_login()

      创建LoginTest()类,并在__init__()方法中初始化浏览器驱动、等待超时长和URL等。这样test_admin_login()test_guest_login()两个测试方法只需关注登录的用户名和密码,通过调用Login()类的user_login()方法并传入具体的参数来测试不同用户的登录。

      参数化搜索关键字

      再来看一个百度搜索的例子。我们每天上网一般要很多次百度搜索,而我们每次在使用百度搜索时步骤都是一样的,不一样的时每次搜索的“关键字”不同。下面我们就以数组的方式对搜索的关键字进行参数化。

      新建baidu.py

    from selenium import webdriver
    
    serch_text = ['python','中文','text']
    
    for text in serch_text:
        driver = webdriver.Chrome()
        driver.implicitly_wait(10)
        driver.get('http://www.baidu.com')
        driver.find_element_by_id('kw').send_keys(text)
        driver.find_element_by_id('su').click()
        driver.quit()

      这个例子比较简单,首先创建一个数组search_text用来存放搜索的关键字,通过for循环来便利数组,最后把便利的数组元素作为每次百度搜索的关键字。这个例子可以更充分地体现出数据驱动的概念:因为测试数据的不同从而引起测试结果的不同。

      读取txt文件

      Txt文件是我们经常操作的文件类型,python提供了一下几种读取txt文件的方式。

      * read()  读取整个文件。

      * readline()  读取一行数据。

      * readlines()  读取所有行的数据。

      回到前面登录的例子,现在使用txt文件来存放用户名和密码数据,并通过读取该文件中的数据作为用例的测试数据。

      

      首先将用户名和密码按行写入txt文件中,这里把用户名和密码用逗号“,”隔开。

    user_file = open('username_login.txt','r')
    lines = user_file.readlines()
    user_file.close()
    
    for line in lines:
        username = line.split(',')[0]
        password = line.split(',')[1]
        print(username,password)

      运行结果:

     

      首先通过open()方法以读“r”的形式打开username_login.txt文件,使用readlines()方法按行读取txt文件,将获取到的每一行数据通过split()方法拆分出用户名和密码。Split()可以将一个字符串通过某一个字符为分割点拆分成左右两部分,这个以逗号(,)为分割点。Split()拆分出来的左右两部以数组的形式存放,所以[0]可以取到左半部分的字符串,[1]可以取到右半部分的字符串。

      在上面的例子中循环便利出每一行数据的用户名和密码,得到想要的数据后就可以将其用于自动化测试脚本了。

      读取CSV文件

      那么新的问题来了,假设现在每次要读取的是一组用户数据,这一组数据包括用户名、邮箱、年龄、性别等信息,这时在使用txt文件来存放这些数据,读取起来就没那么方便了。对于这类型的数据可以通过CSV文件来存放。

      创建info.csv文件,首先通过WPS表格或Excel创建表格,文件另存为CSV格式进行保存。注意不要通过直接修改文件的后缀名来创建CSV文件,这样创建的并非真正的CSV类型文件。

      下面编写csv_read.py文件进行循环读取

    import csv #导入csv包
    
    #读取本地CSV文件
    date = csv.reader(open('info.csv','r'))
    
    #循环输出每一行信息
    for user in date:
        print(user)

      运行结果:

      首先导入cvs模块,通过reader()方法读取CSV文件;然后通过for循环便利文件中的每一行数据。

      从打印结果可以看出,读取的每一行数据均是以数组的形式存储的。如果向取用户的某一列数据,只需要指定数组下标即可。

    import csv #导入csv包
    
    #读取本地CSV文件
    date = csv.reader(open('info.csv','r'))
    
    #获取用户的邮箱地址
    for user in date:
        print(user[1])

      运行结果:

      假如现在需要所有用户的邮箱地址,那么只需要指定邮箱地址所在列的下标即可。数据的下标是以0开始的,邮箱位于数组的第二列,所以指用户邮箱的下标为[1]

      通过这种CVS文件来存放数据可以方便地解决读取多列数据的问题。当然,用Excel文件来存放这些数据也是一个不存的选择,只是所调用的模块就需要从csv切换为xlrd,针对Excel文件操作的方法也会有所不同。

      读取xml文件

      有时候我们需要读取的数据不是规则的。例如,我们需要一个配置文件来配置当前自动化测试脚本的URL、浏览器、登录的用户名和密码等,这时候就可以考虑选择使用XML文件来存放这些信息。新建info.xml文件

    <?xml version='1.0' encoding='utf-8'?>
    <info>
        <base>
            <platform>Windows</platform>
            <browser>Firefox</browser>
            <url>http://www.baidu.com</url>
                <login username="admin" password="123456" />
                <login username="guest" password="654321" />
        </base>
        <test>
            <province>北京</province>
            <province>广东</province>
                <city>深圳</city>
                <city>珠海</city>
            <province>浙江</province>
                <city>杭州</city>
        </test>
    </info>
    

    下面以info.xml文件为例介绍读取XML文件的方法。  

      1.获得标签信息

    from xml.dom import minidom
    
    #打开xml文档
    dom = minidom.parse('info.xml')
    
    #得到文档元素对象
    root = dom.documentElement
    
    print(root.nodeName)
    print(root.nodeValue)
    print(root.nodeType)
    print(root.ELEMENT_NODE)

      运行结果:

      首先导入xmlminidom模块,用来处理XML文件,parse()用于打开一个XML文件,documentElement用于得到XML文件的唯一根元素。

      每一个节点都有它的nodeNamenodeValuenodeType等属性。nodeName为节点名称;nodeValue为节点的值,支队文本节点有效;nodeType为节点的类型。

      2.获得任意标签名

    from xml.dom import minidom
    
    #打开xml文档
    dom = minidom.parse('info.xml')
    
    #得到文档元素对象
    root = dom.documentElement
    
    tagname = root.getElementsByTagName('browser')
    print(tagname[0].tagName)
    
    tagname = root.getElementsByTagName('login')
    print(tagname[1].tagName)
    
    tagname = root.getElementsByTagName('province')
    print(tagname[2].tagName)

      运行结果:

      getElementsByTagName()可以通过标签名获取标签,它所获取的对象是以数组形式存放。假如“login”和“province”标签在info.xml文件中有多个,则可以通过指定数组的下标方式获取某个具体标签。

      getElementsByTagName(“province”)获得的是标签名为“province”的一组标签;

      getElementsByTagName(“province”).tagname[0]表示一组标签的第一个;

      getElementsByTagName(“province”).tagname[1]表示一组标签的第而个。

      3.获得标签的属性值

    __author__ = 'Mr.Li'
    from xml.dom import minidom
    
    #打开xml文档
    dom = minidom.parse('info.xml')
    
    #得到文档元素对象
    root = dom.documentElement
    
    logins = root.getElementsByTagName('login')
    
    #获得login标签的username属性值
    username = logins[0].getAttribute("username")
    print(username)
    
    #获得login标签的password属性值
    password = logins[0].getAttribute("password")
    print(password)
    
    #获得第二个login标签的username属性值
    username = logins[1].getAttribute("username")
    print(username)
    
    #获得第二个login标签的password属性值
    password = logins[1].getAttribute("password")
    print(password)

      运行结果:

      getAttribute()方法用于获取元素的属性值。它和WebDriver中提供的get_attribute()方法相似。

      4.获得标签对之间的数据

    __author__ = 'Mr.Li'
    from xml.dom import minidom
    
    #打开xml文档
    dom = minidom.parse('info.xml')
    
    #得到文档元素对象
    root = dom.documentElement
    
    provinces = dom.getElementsByTagName('province')
    citys = dom.getElementsByTagName('city')
    
    #获得第二个province标签对的值
    p2 = provinces[1].firstChild.data
    print(p2)
    
    #获得第一个city标签对的值
    c1 = citys[0].firstChild.data
    print(c1)
    
    #获得第二个city标签对的值
    c2 = citys[1].firstChild.data
    print(c2)

      运行结果

      firstChild属性返回被选节点的第一个子节点。data表示获取该节点的数据,它和WebDriver中提供的text方法类似。

  • 相关阅读:
    [题解] [JSOI2011] 任务调度
    [题解] [JSOI2011] 棒棒糖
    [题解] [JSOI2011] 柠檬
    [题解] [JSOI2010] 排名
    [湖南集训] 谈笑风生
    BZOJ 4695 最假女选手 线段树
    HNOI 2010 物品调度 并查集 置换
    Luogu P4299 首都 LCT
    BZOJ 2738 矩阵乘法 整体二分
    51nod 1175 区间第k大 整体二分
  • 原文地址:https://www.cnblogs.com/lirongyang/p/11504933.html
Copyright © 2011-2022 走看看