数据驱动(参数化)
在测试模型一节的数据驱动中我们已经介绍了如何通过python 定于的数组对百度输入数据进行参数化设置,将其它循环的读取vlalues 数组中每一个数据。这里我们将通过读取txt 文件中的数据来实现参数化。
创建data.txt 文件,向文件内写放三行数据,如图4.3
d:\abc\data.txt
图4.3
baidu_read_data.py
代码示例:
#coding=utf-8
from selenium import webdriver
import os,time
source = open("D:\\abc\\data.txt", "r")
values = source.readlines()
source.close()
#执行循环
for serch in values:
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
driver.find_element_by_id("kw").clear()
driver.find_element_by_id("kw").send_keys(serch)
driver.find_element_by_id("su").click()
time.sleep(3)
driver.quit()
open 方法以只读方式(r)打开本地的data.txt 文件,readlines 方法是逐行的读取文件内容。通过for 循环,serch 可以每次获取到文件中的一行数据,在定位到百度的输入框后,将数据传入send_keys(serch)。这样通过循环调用,直到文件的中的所有内容全被读取。
登录参数化(读取txt 文件)
现在按照上面的思路,对自动化脚本中用户、名密码进行参数化,通过python 文档我们发现python读取文件的方式有:整个文件读取、逐行读取、固定字节读取。并没有找到一次读取两条数据的好方法。
创建两个文件,分别存放用户名密码,如图4.4:
图 4.4
打开之前编写的login.py 文件,做如下修改:
代码示例:
#coding=utf-8
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
import unittest, time, os
source=open("D:\\selenium_python\\data\username.txt","r") #用户名文件
un =source.read() #读取用户名
source.close()
source2 = open("D:\\selenium_python\\data\password.txt","r") #密码文件
pw=source2.read() #读取密码
source2.close()
def login(self)
driver = self.driver()
driver.maximize_window()
driver.find_element_by_id("user_name").clear()
driver.find_element_by_id("user_name").send_keys(un)
driver.find_element_by_id("user_pwd").clear()
driver.find_element_by_id("user_pwd").send_keys(pw)
driver.find_element_by_id("dl_an_submit").click()
time.sleep(3)
分别打开两个txt 文件,通过un 和pw 来接收用户名和密码信息,将接收的数据通过send_key(xx)转入到执行程序中。
运行我们前面创建的webcloud.py 文件,程序可以正常的执行。虽然这样做比较丑,但是确实达到了数据与脚本分离的目的。
缺点:
虽然目的达到了这,但这样的实现有很多问题:
1、用户名密码分别在不同的文件里,修改用户名和密码比较麻烦。
2、username.txt 和password.txt 文件中只能保存一个用户密码,无能很好的循环读取。
登录参数化(函数)
函数是我们前面刚介绍的python 知识,函数可以预先给参数化赋值,借助这个特性,我们可以通过调用函数的方式对用户名密码进行参数化.
userinfo.py
代码示例:
def fun(un='testing',pw=123456):
print "success reader username and password!!"
return un,pw
我们为两个参数un 和pw 赋了初值,赋值内容如果是字符串需要加引号,如果是数字可以不需要引号。再次打开login.py 文件,做如下修改:
#coding=utf-8
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
import unittest, time
import userinfo #导入函数
#通过两个变量,来接收调用函数获得用户名&密码
un,pw=uerinfo.fun()
#打印两个变量
print us,pw
def login(self)
driver = self.driver()
driver.maximize_window()
driver.find_element_by_id("user_name").clear()
driver.find_element_by_id("user_name").send_keys(un)
driver.find_element_by_id("user_pwd").clear()
driver.find_element_by_id("user_pwd").send_keys(pw)
driver.find_element_by_id("dl_an_submit").click()
time.sleep(3)
单独运行login.py 文件:
>>> ================================ RESTART ================================
>>>
success reader username and password!!
testing 123456
说明我们对函数的参数调用是成功的,将un、pw 两个变量的值传入用户名密码的send_keys()方法中即可。
登录参数化(读取字典)
既然我们是固定的读取用户名和密码两个值,那么可以借助python 字典的方式来完成这个需求。字典由大括号内的多键值对组成;下面继续在python IDLE 交互模式下演示字典的创建与使用。
>>> data = {'abc':'123','def':'456'}
>>> print data
{'abc': '123', 'def': '456'}
>>> data.keys()
['abc', 'def']
>>> data.values()
['123', '456']
>>> data.items()
[('abc', '123'), ('def', '456')]
创建字典用大括号,数据由key/value 键值对组成,keys()方法返回字典中的键列表。values()返回字典中的值列表,items()返回(key,value)元组。
下面创建一个存放字典的函数文件userinfo.py:
def zidian():
data={'username':'123456','testing360':'123123'}
print "success reader username and password!!"
return data
字典的可以方便的存放k,v 键值对,一个键对应一个值;注意,如果密码中有非数字,需要加引号。需要说明的是我们的需求并不适合循环的读取用户名密码,不过我们可以写一小程序单独验证这种循环读取的方式:
loop_reader.py
代码示例:
#coding=utf-8
import userinfo #导入函数
#获取字典信息
info=userinfo.zidian()
#通过items()循环读取元组(键/值对)
for us,pw in info.items()
print us
print pw
运行结果如下:
>>> ================================ RESTART ================================
>>>
success reader username and password!!
username
123456
testing360
123456
在实际使用中,可以将un、pw 两个变量循环获得的值传入相应的send_keys()方法中。
目前方式解决了两个问题:一次传入两个值,以及循环读取。
表单参数化(csv)
假如我有自动化脚本中要参数化一张表单,表单需要填写用户名、邮箱,年龄,性别等信息,使用上面的方法就很难来解决这个问题,下面通过读取csv 文件的方法来解决这个问题。
创建userinfo.csv 文件,如图5.x
图5.x
通过WPS 或excel 创建表格,文件另存为选择CSV 格式,下面修改loop_reader.py 文件进行循环读取:
#coding=utf-8
import csv #导入csv 包
#读取本地CSV 文件
my_file='D:\\selenium_python\\data\\userinfo.csv'
data=csv.reader(file(my_file,'rb'))
#循环输出每一行信息
for user in data:
print user[0]
print user[1]
print user[2]
print user[3]
运行结果:
>>> ========================= RESTART ==============================
>>>
testing
123456@126.com
23
男
testing2
123123@qq.com
18
女
testing3
456123@gmail.com
29
女
csv.reader()用于读取CSV 文件,user[0] 表示表格中第一列的数据(用户名),user[0]表示表格中第二列的数据(邮箱),后面类推。
通过CSV 读取文件比较灵活,可以循环读取每一条数据,从而又不局限每次所读取数据的个数。
我们这里举例了多种方式来进行参数化,虽然最终看来CSV 的方式最灵活,这里更多的是想告诉读者解决问题的方法是多样的,我们可以用python 的各种技巧来选择最简单的方法来解决问题。从这个过程中我们也学到了不少python 编程技术。
我这里可以说是用python 最基础的知识点解决了问题,这里只算提供一个思路,温习一下python ,你一定可以找到更完美优雅的方法;解决问题的方法是多样的,使用最贴合需求的方法,简单解决问题。这一节写的比较多,对构建自动化框架来说,参数化是非常重要的一个知识点。
脚本的模块化与参数化是我们在自动化脚本开发中用到最多的两个技巧,希望读者能认真体会,灵活的运行到具体的项目中。
posted on 2017-01-09 11:13 chenzx0918 阅读(358) 评论(0) 编辑 收藏 举报