自动化测试模型(数据参数化方法)以及简单的文件读取方式

时间:2020-01-09
本文章向大家介绍自动化测试模型(数据参数化方法)以及简单的文件读取方式,主要包括自动化测试模型(数据参数化方法)以及简单的文件读取方式使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

一、自动化测试模型

  1.线性测试

  录制或编写对应应用程序操作步骤产生,每个线性脚本相互独立,相互之间不依赖,不调用彼此,即单纯地模拟用户完整操作场景。不易维护。

  2.模块化与类库

  将重复的操作单独封装成公共模块。在测试用例执行过程中,当需要用到模块封装时对其进行调用,如此一来便最大限度的消除了重复,从而提高测试用例的可维护性。

  3.数据驱动测试

  定义:数据的改变驱动自动化测试的执行,最终引起测试结果的改变。简单理解就是把数据驱动所需要的测试数据参数化,可以用多种方式来存储和管理这些参数化的数据(txt,html,csv,xml,json)

  4.关键字驱动测试

  又被称为【表驱动测试】或【基于动作字测试】。这类框架会把自动化操作封装为“关键字”,避免测试人员直接接触代码,多以“填表格”的形式降低脚本的编写难度。

  Robot Framework是主流的关键字驱动测试框架之一,通过它自带的Robot Framework RIDE编写。

二、模块化与参数化

1.简单的一个文件线性测试

  一般需要配合使用,即在创建函数或类方法时为它们设置入参,使其可以根据不同的参数执行相应的操作,下面以一个简单的126邮箱登录为例:

 1 from selenium import webdriver
 2 from time import sleep
 3 
 4 driver = webdriver.Chrome()
 5 driver.maximize_window()
 6 driver.get("http://www.126.com")
 7 # 登录
 8 sleep(5)
 9 
10 login = driver.find_element_by_xpath("/html/body/div[2]/div[3]/div/div[3]/div[3]/div[4]/a[1]")
11 login.click()
12 driver.switch_to.frame(0)
13 """
14 (driver.find_element_by_xpath("/html/body/div[2]/div[3]/div/div[3]/div[4]/div[1]/div/iframe"))
15 """
16 sleep(3)
17 user = driver.find_element_by_name("email")
18 user.clear()
19 user.send_keys("zudangli")
20 driver.find_element_by_name("password").clear()
21 driver.find_element_by_name("password").send_keys("19820818kai")
22 driver.find_element_by_id("dologin").click()
23 # 登录之后的动作
24 sleep(3)
25 # 退出
26 driver.find_element_by_link_text("退出").click()
27 driver.quit()

<这里涉及到一个表单切换的问题,因为打开这个邮箱的网址后主页面显示的是扫码登录,要切换到账户密码登录的表单下,但是在尝试了多种定位iframe的方式之后(name、css_selector、xpath),切换是切换成功无疑了,因为可以找到该iframe下的元素,但就是不能执行操作,报错:(selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable),也搜了很多办法,最终也无疾而终,最后只能在切换表单之前手动切换到账号登录的iframe下,暂时先这样解决吧,随着后面进一步的学习再回来看看是怎么费事!!!>

2.将重复的动作模块化

好了,言归正传,继续来康康如何一步步模块化……要实现邮箱的自动化登录测试项目,那每条测试用例都需要有登录动作和退出动作,此时,需要创建一个新的module.py文件存放登录和退出动作。

 1 from time import sleep
 2 
 3 
 4 class Mail:
 5 
 6     def __init__(self, driver):
 7         self.driver = driver
 8 
 9     def login(self):
10         login = self.driver.find_element_by_xpath("/html/body/div[2]/div[3]/div/div[3]/div[3]/div[4]/a[1]")
11         login.click()
12         self.driver.switch_to.frame(0)
13 14         sleep(3)
15         user = self.driver.find_element_by_name("email")
16         user.clear()
17         user.send_keys("zudangli")
18         self.driver.find_element_by_name("password").clear()
19         self.driver.find_element_by_name("password").send_keys("19820818kai")
20         self.driver.find_element_by_id("dologin").click()
21 
22     def logout(self):
23         self.driver.find_element_by_link_text("退出").click()

  首先创建一个Mail类,在__init__()初始化方法中接收driver驱动并赋值给self.driver,在login()和logout()方法中分别使用self.driver实现邮箱的登录和退出动作,接下来修改test_mail.py测试调用Mail类中的这两个方法:

 1 from selenium import webdriver
 2 from time import sleep
 3 
 4 from files.module import Mail
 5 
 6 driver = webdriver.Chrome()
 7 driver.maximize_window()
 8 driver.get("http://www.126.com")
 9 sleep(5)
10 # 调用Mail类并接受driver驱动
11 mail = Mail(driver)
12 # 登录
13 mail.login()
14 sleep(5)
15 # 退出
16 mail.logout()
17 driver.quit()

3.将模块中的方法参数化

  接着再进一步,如果需求是测试登录功能,虽然测试步骤是固定的,但是测试数据(账号)不同,这时就需要把login()方法参数化。修改的module.py文件代码如下:

 1 from time import sleep
 2 
 3 
 4 class Mail:
 5 
 6     def __init__(self, driver):
 7         self.driver = driver
 8         login = self.driver.find_element_by_xpath("/html/body/div[2]/div[3]/div/div[3]/div[3]/div[4]/a[1]")
 9         login.click()
10         self.driver.switch_to.frame(0)
11         sleep(3)
12 
13     def login(self, username, password):
14         sleep(2)
15         self.driver.find_element_by_name("email").clear()
16         self.driver.find_element_by_name("email").send_keys(username)
17         self.driver.find_element_by_name("password").clear()
18         self.driver.find_element_by_name("password").send_keys(password)
19         self.driver.find_element_by_id("dologin").click()
20         sleep(3)
21 
22     def logout(self):
23         self.driver.find_element_by_link_text("退出").click()

(这里对Mail类中的初始化方法做了微调,由于考虑到各种测试案例下,只需要一次定位到iframe就将iframe的定位操作放到了初始化方法中)

这样就进一步提高了login()方法的可复用性,不再使用一个固定的账号登录,而是根据被调用者传来的用户名和密码执行登录操作,相应的修改测试用例test_mail.py文件:

 1 driver = webdriver.Chrome()
 2 driver.maximize_window()
 3 driver.get("http://www.126.com")
 4 sleep(5)
 5 # 调用Mail类并接受driver驱动
 6 mail = Mail(driver)
 7 # 登录账号为空
 8 mail.login("", "")
 9 
10 # 用户名为空
11 mail.login("", "19820818kai")
12 
13 # 密码为空
14 mail.login("zudangli", "")
15 
16 # 用户名密码错误
17 mail.login("error", "error")
18 
19 # 正确的账号登录
20 mail.login("zudangli", "19820818kai")
21 mail.login("pegawayatstudying", "19970507zudangli")
22 # ……

4.读取数据文件

  • txt文件

Python提供了一下几种读取txt问价的方法:

  1. read():读取整个文件
  2. readline():读取一行数据
  3. readlines():读取所有行的数据

test.txt文件如下:

:19820818kai
zudangli:
error:error
zudangli:19820818kai
pegawayatstudying:19970507zudangli

 创建read_txt.py文件,用于读取txt文件

 1 # 读取文件
 2 with(open("./test.txt", "r")) as user_file:
 3     data = user_file.readlines()
 4 
 5 # 格式化处理
 6 users = []
 7 for line in data:
 8     user = line[:-1].split(":")
 9     users.append(user)
10 
11 # 打印users二维数组
12 print(users)

 首先通过open()以读(“r”)的方式打开test.txt文件,readlines()可读取文件中的所有行并赋值给变量data。接下来循环data中的每一行数据,[:-1]可对字符串进行切片,以省略最后一个字符,因为读取的每一行数据结尾都有一个换行符“\n”。spilt()通过冒号(:)对每行数据进行拆分,会得到数组['','19820818kai'],最后使用append()把每一组用户名和密码追加到users数组中。取users数组中的数据,得到的数组用不同的用户名/密码进行登录,代码如下:

 1 from selenium import webdriver
 2 from time import sleep
 3 from files.module import Mail
 4 from files.read_txt import users
 5 
 6 driver = webdriver.Chrome()
 7 driver.maximize_window()
 8 driver.get("http://www.126.com")
 9 sleep(5)
10 # 调用Mail类并接受driver驱动
11 mail = Mail(driver)
12 # 登录账号为空
13 mail.login(users[0][0], users[0][1])
14 
15 # 用户名为空
16 mail.login(users[1][0], users[1][1])
17 
18 # 密码为空
19 mail.login(users[2][0], users[2][1])
20 
21 # 用户名密码错误
22 mail.login(users[3][0], users[3][1])
23 
24 # 正确的账号登录
25 mail.login(users[4][0], users[4][1])
26 mail.login(users[5][0], users[5][1])
27 # ……
  • CSV文件

注:可以把WPS表格或Excel表格通过文件另存为CSV类型的文件,但不要直接修改文件的后缀名来创建CSV文件,因为这样的文件并非真正的CSV文件。这里遇到一个问题:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd3 in position 0: invalid continuation byte。解决办法:https://blog.csdn.net/moledyzhang/article/details/78978312简单来说就是用记事本打开该文件,另存为时编码格式选择UTF-8即可

 1 import codecs
 2 import csv
 3 from itertools import islice
 4 
 5 # 读取本地CSV文件
 6 data = csv.reader(codecs.open('./csv.csv', 'r', 'utf_8_sig'))
 7 # 存放用户数据
 8 users = []
 9 # 循环输出每行信息
10 for line in islice(data, 1, None):
11     users.append(line)
12 # 打印
13 print(users)

 通过Python读取CSV文件比较简单,但会遇到两个问题:

1.中文乱码问题。codecs是Python标准的模块编码和解码器。首先通过codecs提供的open()方法,在打开文件时可以指定编码类型,如utf_8_sig,然后导入CSV模块,通过reader()方法读取文件,即可避免中文乱码问题。

2.跳过CSV文件的首行。因为一般会在第一行定义测试字段的名字,所以在读取数据时要跳过。Python的内建模块itertools提供了用于操作迭代对象的函数,即islice()函数,可以返回一个迭代器第一个参数指定迭代对象,第二个参数指定开始迭代的位置,第三个参数表示结束位。

  • XML文件

当需要读取的数据是不规则时,可以用XML文件。比如需要用一个配置文件来配置当前自动化测试平台、浏览器、URL、登录的用户名和密码等,这时就需要使用XML文件存放这些数据。其特点是数据保存在标签对之间,或者是作为标签的属性存放。

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <info>
 3     <platforms>
 4         <platform>Windows</platform>
 5         <platform>Linux</platform>
 6         <platform>macOS</platform>
 7     </platforms>
 8     <browsers>
 9         <browser>Firefox</browser>
10         <browser>Chrome</browser>
11         <browser>Edge</browser>
12     </browsers>
13     <url>http:www.xxxx.com</url>
14         <login username="admin" password="123456"/>
15         <login username="guest" password="654321"/>
16 </info>
 1 from xml.dom.minidom import parse
 2 # 打开XML文件
 3 dom = parse('./config.xml')
 4 # 得到文档元素对象
 5 root = dom.documentElement
 6 # 获取一组标签
 7 tag_name = root.getElementsByTagName('platform')
 8 
 9 print(tag_name[0].firstChild.data)
10 print(tag_name[1].firstChild.data)
11 print(tag_name[2].firstChild.data)

 Python自带读取XML文件的模块,通过parse()方法可读取XML文件。documentElement()方法用于获取文档元素对象,getElementsByTagName()方法用于获取文件中的标签。这里不需要指定标签的层级关系,即获取的标签可以是任意层级的。接下来,获取标签数组中的某个元素。firstChild属性可返回被选节点的第一个子节点,data表示获取该节点的数据,它和WebDriver中的text语句作用相似。上面的代码是来获取标签对之间的数据,下面来看看如何获取标签的属性值:

 1 from xml.dom.minidom import parse
 2 dom = parse('./config.xml')
 3 root = dom.documentElement
 4 login_info = root.getElementsByTagName('login')
 5 # 获得login标签的username属性值
 6 username = login_info[0].getAttribute("username")
 7 print(username)
 8 # 获得login标签的password属性值
 9 password = login_info[0].getAttribute("password")
10 print(password)
11 
12 # 获得第二个login标签的username属性值
13 username = login_info[1].getAttribute("username")
14 print(username)
15 # 获得第二个login标签的password属性值
16 password = login_info[1].getAttribute("password")
17 print(password)

 这里主要使用getAttribute()方法获取元素的属性值,它和WebDriver中的get_attribute()方法作用相似

  • JSON文件

JSON是一种轻量级的数据交换格式,层次结构清晰,创建user_info.json文件:

1 [
2   {"username": "", "password": ""},
3   {"username": "", "password": "123"},
4   {"username": "user", "password": ""},
5   {"username": "error", "password": "error"},
6   {"username": "admin", "password": "admin123"}
7 ]

创建read_json.py文件:

1 import json
2 
3 with open("./user_info.json", "r") as f:
4     data = f.read()
5 
6 user_list = json.loads(data)
7 print(user_list)

 通过open()方法可读取user_info.json文件。因为测试数据本身是以列表和字典格式存放的,所以读取整个文件内容后,通过JSON提供的表将str类型转换为list类型即可。

原文地址:https://www.cnblogs.com/pegawayatstudying/p/12166879.html