數據驅動(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