名詞解釋:
appium:是個web接口服務(wù),接受http請求诺擅,可以開啟多個端口晨横,默認4723
appium desktop:內(nèi)嵌了appium,還提供了屬性配置鸠天、腳本錄制等功能
Appium Client:appium為其提供服務(wù)端口讼育,他就是請求的發(fā)送者
appium是什么?
appium是自動化測試工具稠集,可以用來測試iOS和Android平臺的應(yīng)用奶段、Web應(yīng)用和Web混合應(yīng)用。在測試中主要用于流程測試剥纷。
他有一個比較重要的特點痹籍,支持跨平臺,下面的工作原理會提到為什么可以跨平臺的
工作原理
appium選擇了Client/Server的設(shè)計模式晦鞋。
我們使用自己所熟知的語言編寫腳本蹲缠,通過相應(yīng)語言環(huán)境的Client,發(fā)送http請求到Server端鳖宾,Server端得到腳本吼砂,通過解析,驅(qū)動設(shè)備執(zhí)行appium腳本鼎文。
1渔肩、Client端針對不同的語言開發(fā)了相應(yīng)的appium庫,那么我們寫腳本就可以根據(jù)自己所熟悉的語言下載自己熟悉的appium庫拇惋。我們所熟知的語言有:Ruby周偎、Python、Java撑帖、JavaScript (Node.js)蓉坎、Objective C、PHP胡嘿、C# (.NET)蛉艾、RobotFramework。后面附加相應(yīng)語言的客戶端衷敌。
2勿侯、Server端支持兩大平臺MAC和Windows。我們針對不同的平臺安裝使用缴罗。
3助琐、移動設(shè)備支持iOS、Android兩大真機和分別對應(yīng)的模擬器面氓。
總結(jié):多語言兵钮、跨平臺蛆橡。appium的腳本支持多語言開發(fā)、同時可以在不同的平臺運行掘譬。
搭建環(huán)境
作為小白泰演,從搭建環(huán)境到用來做一些簡單的測試,期間遇到各種奇葩問題屁药,繞了很多彎路粥血。在這稍作總結(jié),希望像我一樣的小白們都能有所收獲酿箭。
目前我在Mac系統(tǒng)下复亏,使用Python開發(fā)測試腳本,測試iOS項目(Android項目目前還有問題缭嫡。缔御。。)妇蛀。
Mac系統(tǒng)搭建環(huán)境
Android項目環(huán)境
Node.js耕突,下載地址:https://nodejs.org/en/download/,為什么要裝node.js呢评架?appium server 是用node.js寫的眷茁,安裝node.js可以直接用npm命令安裝appium,或相關(guān) ? ? ? ? ? ?driver、server纵诞。
android SDK上祈、jdk
appium
大體安裝過程是這樣的,brew(mac 套件管理器浙芙,包含很多實用工具)->node->npm->appium
命令行運行:appium-doctor登刺,看看缺什么就裝上什么
iOS項目環(huán)境
Mac系統(tǒng):10.12.6
xCode開發(fā)工具(命令行Xcode Command Line Tools)大多開發(fā)iOS的同學環(huán)境應(yīng)該都是正常的
Appium-Server:目前最新的1.6.2版本
按照上面的工作原理圖 “client->server->移動設(shè)備”分步講解安裝過程。
appium client
不太清楚明明支持多種語言嗡呼,為啥Python和Java測試腳本成為主流纸俭。不過前人栽樹后人乘涼,從網(wǎng)上看了下Python這些例子南窗,最終還是選擇了appium client揍很,其中還有一個最重要的原因,使用appium desktop 可以生成python腳本万伤,試想窒悔,作為小白,把生成的腳本拿來簡單一改就可以使用壕翩,這應(yīng)該算是入門最快的捷徑了蛉迹。
廢話不多說傅寡,直接上python client地址:https://github.com/appium/python-client放妈,下載完成進入到python-clinet目錄執(zhí)行python setup.py install就可以北救,操作如下
git clone git@github.com:appium/python-client.git
cd python-client
python setup.py install
擴展,附贈其他腳本語言的client下載地址芜抒,安裝大同小異珍策,自行百度
Ruby???????????????????????????https://github.com/appium/ruby_lib
Python????????????????????????https://github.com/appium/python-client
Java ? ? ? ? ? ? ? ? ? ? ? ? ? ??https://github.com/appium/java-client
JavaScript (Node.js)???https://github.com/admc/wd
Objective C??????????????????https://github.com/appium/selenium-objective-c
PHP???????????????????????????????https://github.com/appium/php-client
C# (.NET)??????????????????????https://github.com/appium/appium-dotnet-driver
RobotFramework??????????https://github.com/jollychang/robotframework-appiumlibrary
appium server
appium desktop下載地址
https://github.com/appium/appium-desktop/releases/tag/v1.6.2
下面是Appium Server,地址和端口號都是默認的
點擊啟動Start Server就會開啟監(jiān)聽宅倒,可以看到4723在監(jiān)聽中攘宙,之后運行腳本的所有日志都會在這里展示出來。
點擊放大鏡(Start Inspector Session)拐迁,設(shè)置相應(yīng)的Capabilities蹭劈,為接入設(shè)備做準備。下面是我根據(jù)自己設(shè)備和公司項目的配置的Capabilities
關(guān)于Capabilities的配置有很多线召,你想要的都在這里
http://appium.io/docs/en/writing-running-appium/caps/
iOS程序是如何通過server傳遞指令控制界面的铺韧??缓淹?
WebDriverAgent哈打,是實現(xiàn)自動化測試工作的實施者(實施者,我自己起的名)讯壶。他可以在iOS平臺為服務(wù)器實現(xiàn)控制遠端設(shè)備料仗。比如啟動、殺死程序和界面點擊伏蚊、拖拽等立轧。通過連接XCTest.framework和調(diào)用蘋果的API直接在設(shè)備上執(zhí)行命令。
下載地址:https://github.com/facebook/WebDriverAgent
下面是我錄制的腳本
#-*- coding: UTF-8 -*-
# This sample code uses the Appium python client
# pip install Appium-Python-Client
# Then you can paste this? into a file and simply run with Python
import time
from appium import webdriver
caps = {}
caps["platformName"] = "iOS"
caps["deviceName"] = "iPhone"
caps["udid"] = "7e0d8f2dcfbcf64612ae93b087d51bff1f431"
caps["noReset"] = "true"
caps["bundleId"] = "com.yz.spacebridge"
caps["platformVersion"] = "11.2"
caps["xcodeOrgId"] = "<2MUJFSGB46>"
caps["xcodeSigningId"] = "iPhone Developer"
driver = webdriver.Remote("http://localhost:4723/wd/hub", caps)
el1=driver.find_element_by_xpath("http://XCUIElementTypeButton[@name=\"登錄\"]")
el1.click()
time.sleep( 5 )
els4 = driver.find_elements_by_name("千喜鶴美食廣場")
els4[0].click()
time.sleep( 5 )
els5 = driver.find_elements_by_name("4dc370c7")
els5[0].click()
el2 = driver.find_element_by_accessibility_id("back")
el2.click()
el3 = driver.find_element_by_accessibility_id("back")
el3.click()
driver.quit()
值得注意的是丙挽,我們經(jīng)常會遇到編碼問題肺孵,如上面添加注釋,注意颜阐,此注釋一定要放在最頂端否則不起作用
#-*- coding: UTF-8 -*-
appium desktop平窘,基本使用
要操作或者查看某個(某組)元素,必須事先知道該元素的id或者xpath凳怨,通過appium desktop可以很方便的定位獲取頁面元素id 和xpath瑰艘。另外還有一些基礎(chǔ)的頁面操作,如下圖:
縱橫客云小盒收銀接入
好長一段時間的調(diào)研和學習肤舞,最終都要落實到工作和項目中紫新,在云小盒收銀,我們會有所體現(xiàn)李剖。
簡單講下收銀模塊如下:設(shè)置芒率、交易統(tǒng)計、收款篙顺、訂單
使用appium進行測試偶芍,說白了充择,就是測試整個流程通不通,然后按照“登錄->交易統(tǒng)計->收銀->核對統(tǒng)計結(jié)果->退款”這個主流程一直循環(huán)跑下去匪蟀。
據(jù)上模塊所講椎麦,按照測試流程按照模塊在測試工程中依次劃分下面這四個模塊loginModel(從設(shè)置進入,主測登錄)材彪、cashierModel(收銀)观挎、refundModel(訂單統(tǒng)計、退款)段化、statisticsModel(交易統(tǒng)計)嘁捷。
主模塊:jinyuanbao,統(tǒng)籌管理
threads = []
t1 = threading.Thread(target=runloop)
threads.append(t1)
if __name__ == '__main__':
? ? for t in threads:
? ? ? ? t.start()
總業(yè)務(wù)流程
def task1():
? ? driver = webdriver.Remote("http://localhost:4723/wd/hub", API.desired_caps)
? ? time.sleep(2)
? ? RefundClass().refundAction(driver)
? ? # # 切換賬號
? ? account = LoginClass().loginAction(driver)
? ? API.user_account = account
? ? # 查看賬單
? ? total_dic = StatisticsClass().statisticsAction(driver)
? ? if account != API.account2:
? ? ? ? # 微信支付
? ? ? ? dic = CashierClass().cashier_weixin_Action(driver)
? ? ? ? # # 對比交易賬單
? ? ? ? if dic != None:
? ? ? ? ? ? print dic
? ? ? ? if dic != None and total_dic != None:
? ? ? ? ? ? total_dic = StatisticsClass().payment_data_contrast(driver, total_dic, dic)
? ? ? ? else:
? ? ? ? ? ? print total_dic
? ? ? ? ? ? return
? ? ? ? # 退款
? ? ? ? RefundClass().refundAction(driver)
? ? # 支付寶支付
? ? dic = CashierClass().cashier_alipay_Action(driver)
? ? # 對比交易賬單
? ? if dic != None:
? ? ? ? print dic
? ? if dic != None and total_dic != None:
? ? ? ? total_dic = StatisticsClass().payment_data_contrast(driver, total_dic, dic)
? ? else:
? ? ? ? print total_dic
? ? ? ? return
? ? # 退款
? ?RefundClass().refundAction(driver)
通用模塊 basemethod
主要實現(xiàn)如下功能:
1显熏、本地記錄日志
def report_log(self,content):
? ? ? ? date_current = time.strftime("%Y-%m-%d", time.localtime())
? ? ? ? time_current = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
? ? ? ? log_name = 'log/'+date_current+'.txt'
? ? ? ? logfile = open(log_name, 'a+')
? ? ? ? logfile.write('\n')
? ? ? ? logfile.write('時間:'+time_current+'===')
? ? ? ? logfile.write(content)
? ? ? ? logfile.close()
2普气、通過id查找元素
def get_id(self,id,driver):
? ? ? ? try:
? ? ? ? ? ? element = WebDriverWait(driver,2).until(lambda driver: driver.find_element_by_id(id))
? ? ? ? ? ? return element
? ? ? ? except:
? ? ? ? ? ? print '未定位到元素:'+id
? ? ? ? ? ? return None
3、通過xpath查找元素
def get_xpath(self,xpath,driver):
? ? ? ? try:
? ? ? ? ? ? element = WebDriverWait(driver,2).until(lambda driver: driver.find_element_by_xpath(xpath))
? ? ? ? ? ? return element
? ? ? ? except:
? ? ? ? ? ? print '未定位到元素:'+xpath
? ? ? ? ? ? return None
4佃延、釘釘webhook服務(wù)上報
def dingtalk(self,text):
? ? ? ? self.report_log(text)
? ? ? ? webhook = kwebhook
? ? ? ? xiaoding = DingtalkChatbot(webhook)
? ? ? ? content = text
? ? ? ? xiaoding.send_text(msg=content,is_at_all=True)
5现诀、釘釘webhook error上報
def ding_talk_error(self,text):
? ? ? ? self.report_log(text)
? ? ? ? webhook = kwebhook
? ? ? ? xiaoding = DingtalkChatbot(webhook)
? ? ? ? content = '收銀賬號:' + API.user_account + '\n' + text
? ? ? ? xiaoding.send_text(msg=content, is_at_all=True)