数据驱动(ddt),在我的印象中,属于参数化的一种,将某些只需要修改数据就可以反复利用的场景适用于数据驱动,减少了代码量,提高了工作效率
拿一个登录来说,平时我们在写测试用例要考虑账号正确、密码正确来登录、账号为空,密码正确、使用不存在的账号进行登录、密码为空登录,在输入账号前有空格。。。。太多太多,那么,我们在自动化测试中,只需要设计好这些数据、场景,这些就可以拿来批量执行
测试apk:一家民宿
使用数据驱动的场景: 账号密码登录
流程:
进入一家民宿-----点击我的----点击登录/注册-----点击密码登录----输入手机号----输入密码—点击登录—获取登录以后的昵称来断言是否登录成功
前提条件: 已用adb命令连接模拟器,appium已启动会话,并连接我们要测试apk
引言
在数据驱动中,我们还需要选择用哪种读取数据的方式?
在这里,我简单介绍下Excel表读取(当然不止这一种,json读取、csv读取、yaml读取…)
Excel表形式
设计6组数据
封装读取Excel类方法
import os
class ReadExcel():
def __init__(self):
base_path = os.path.abspath(os.path.join(os.path.dirname(__file__))) #获取基准路径,就是当前路径的父路径
self.DataList = [] # 准备一个空列表,用于当前目录下的所有Excel表,这里包含全部路径
self.ExcelList = [] #准备一个空列表,用来收集所有Excel的文件名,这里仅包含文件名字
for file_path,dir_name,file_name in os.walk(base_path):
# 使用os内置方法将路径拆分为文件路径、文件夹名字、文件名字
for file in file_name: # 做文件名字的循环
if file[-5:] in '.xlsx': # 如果文件的后五位是.xlsx的
self.ExcelList.append(file) #将符合if条件的文件名装进列表内
xlsxfile = os.path.join(base_path,file) # 做完整路径拼接
self.DataList.append(xlsxfile) # 将完整路径拼接好的excel文件放入列表内
def GetExcel(self,file_name): # 传入你具体要做操作的excel表
for j in self.ExcelList: # 循环 所有excel文件名
if j == file_name: # 如果某一个文件名与我传入的文件名对应
for i in self.DataList: # 继续做循环完整文件路径
if j in i: # 如果我传入的文件名字在某一个完整文件路径中
self.Excelfile = i # 那就就把他在类里声明一个变量
def ReadExcelSetType(self): # 做数据处理,将其整理成{}字典状态,有键和值
import xlrd # 导入模块
work = xlrd.open_workbook(self.Excelfile) # 打开一个xlsx
Datalist = [] # 准备一个空列表,用于接收全部的表数据
sheets = work.sheet_names() # 获取表的所有扉页
for sheet in sheets: # 循环每一个扉页
sheet = work.sheet_by_name(sheet)
hang = sheet.nrows # 拿到每一个sheet页的行数
for i in range(0,hang): # 用行数来做循环
values = sheet.row_values(i) # 拿到每一行的数据
Datalist.append(values) # 将每一行的数据装进列表
title_ = Datalist[0] # 拿到列表中的标题,也就是excel的第一行
content_ = Datalist[1:] # 拿到除了第一行以外的全部数据
new = [] # 准备一个空列表,用于返回数据
for c in content_: # 循环全部数据除了第一行
dic = {} # 准备一个空字典
for i in range(len(c)): # 已全部内容的行数为循环次数做循环
try:
dic[title_[i]] = int(c[i]) # 尝试将数据转化为int,因为excel默认的纯数字为浮点型
except:
dic[title_[i]] = c[i] # 如果不是int 就把他正常传入字典中
new.append(dic) # 将有键和值的字典传入新列表
return new # 返回列表
数据驱动实现:
from appium import webdriver
from ddt import ddt,unpack,data
import unittest
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from csdn.Excel_Read import ReadExcel
s = ReadExcel()
s.GetExcel('登录.xlsx')
caps = {}
caps["platformName"] = "Android"
caps["platformVersion"] = "5.1.1"
caps["deviceName"] = "127.0.0.1:62001"
caps["appPackage"] = "me.onehome.app"
caps["appActivity"] = ".activity.ActivitySplash_"
@ddt
class YJMS(unittest.TestCase):
def setUp(self) -> None:
self.driver = webdriver.Remote("http://localhost:4723/wd/hub",caps)
self.driver.implicitly_wait(20) # 隐式等待,会等元素加载完去寻找
self.driver.find_element_by_id('me.onehome.app:id/immediately').click()
def tearDown(self) -> None:
self.driver.quit()
@data(*s.ReadExcelSetType()) #用*读取全部的表数据
def test_login(self,parms):
# 点击我的
self.driver.find_element_by_id('me.onehome.app:id/tv_guid3').click()
#点击登录/注册
self.driver.find_element_by_id('me.onehome.app:id/tv_user_name').click()
# 点击账号密码登录
self.driver.find_element_by_id('me.onehome.app:id/rb_pw_login').click()
#账号输入 拿到键为user的值
time.sleep(5)
self.driver.find_element_by_id('me.onehome.app:id/et_login_number').send_keys(parms['user'])
#密码输入 拿到键为pwd的值输入
time.sleep(5)
self.driver.find_element_by_id('me.onehome.app:id/et_login_password').send_keys(parms['pwd'])
# 点击登录
time.sleep(5)
self.driver.find_element_by_id('me.onehome.app:id/bt_fulfill').click()
#获取登录后的信息进行断言
userendlogin = self.driver.find_element_by_id('me.onehome.app:id/tv_user_name').get_attribute('text')
useryuqi = '遇上方知友'
self.assertEqual(userendlogin,useryuqi)
if __name__ == '__main__':
unittest.main(verbosity=6)
运行结果:
运行结果全都失败,因为这个app做了防"灌水"操作,在输入完账号,继续输入密码的时候app就会崩溃,我也很无奈
如果说大家有什么好的app可以在评论下方留言,我之后会更新相关app
因为出现了这种情况,所以没有考虑到如果说登录成功以后会怎样
这样简单说下我的思路:
1、导入os模块,用adb shell pm clear 包名 的方式来清除应用的登录信息
2、用try语句+if语句来尝试,如果登录成功,那么后续就再做退出操作,否则pass