TouchAction 中 move to 使用相對(duì)坐標(biāo)還是絕對(duì)路標(biāo)的問題
和appium版本號(hào)有關(guān)暇榴,和wait的放置位置有關(guān)
在appium1.7中
TouchAction(driver).press.wait.move_to # swipe 絕對(duì)坐標(biāo)
TouchAction(driver).press.move_to.wait # 相對(duì)坐標(biāo)
在appium1.8中
TouchAction(driver).press.wait.move_to #絕對(duì)坐標(biāo)
TouchAction(driver).press.move_to.wait # 絕對(duì)坐標(biāo)
線程
多任務(wù)的簡單介紹
- 有很多事情在現(xiàn)實(shí)生活的場景中是同時(shí)進(jìn)行的厚棵,比如開車的時(shí)候 手和腳共同來駕駛汽車,再比如唱歌跳舞也是同時(shí)進(jìn)行的跺撼。
- 多任務(wù)窟感,就是能夠在同一時(shí)間同時(shí)進(jìn)行多個(gè)任務(wù)。
import time
import threading
def sing():
for i in range(5):
print("唱歌")
time.sleep(1)
def dance():
for i in range(5):
print("跳舞")
time.sleep(1)
# 主線程在從上往下跑
# 開一個(gè)子線程
t1 = threading.Thread(target=sing)
# 又開一個(gè)子線程
t2 = threading.Thread(target=dance)
t1.start()
t2.start()
多任務(wù)的原理
什么叫“多任務(wù)”呢歉井?簡單地說柿祈,就是操作系統(tǒng)可以同時(shí)運(yùn)行多個(gè)任務(wù)。打個(gè)比方哩至,你一邊在用瀏覽器上網(wǎng)躏嚎,一邊在聽MP3,一邊在用Word趕作業(yè)菩貌,這就是多任務(wù)卢佣,至少同時(shí)有3個(gè)任務(wù)正在運(yùn)行。還有很多任務(wù)悄悄地在后臺(tái)同時(shí)運(yùn)行著箭阶,只是桌面上沒有顯示而已虚茶。
-
單核cpu工作原理
- 現(xiàn)在,多核CPU已經(jīng)非常普及了仇参,但是嘹叫,即使過去的單核CPU,也可以執(zhí)行多任務(wù)诈乒。由于CPU執(zhí)行代碼都是順序執(zhí)行的罩扇,那么,單核CPU是怎么執(zhí)行多任務(wù)的呢怕磨?
- 答案就是操作系統(tǒng)輪流讓各個(gè)任務(wù)交替執(zhí)行喂饥,任務(wù)1執(zhí)行0.01秒,切換到任務(wù)2肠鲫,任務(wù)2執(zhí)行0.01秒员帮,再切換到任務(wù)3,執(zhí)行0.01秒……這樣反復(fù)執(zhí)行下去导饲。表面上看捞高,每個(gè)任務(wù)都是交替執(zhí)行的,但是帜消,由于CPU的執(zhí)行速度實(shí)在是太快了棠枉,我們感覺就像所有任務(wù)都在同時(shí)執(zhí)行一樣浓体。
- 真正的并行執(zhí)行多任務(wù)只能在多核CPU上實(shí)現(xiàn)泡挺,但是,由于任務(wù)數(shù)量遠(yuǎn)遠(yuǎn)多于CPU的核心數(shù)量命浴,所以娄猫,操作系統(tǒng)也會(huì)自動(dòng)把很多任務(wù)輪流調(diào)度到每個(gè)核心上執(zhí)行贱除。
-
多核cpu工作原理
- 和單核類似,相當(dāng)于多了一個(gè)干活的人媳溺。
并發(fā):指的是任務(wù)數(shù)多于cpu核數(shù)月幌,通過操作系統(tǒng)的各種任務(wù)調(diào)度算法,實(shí)現(xiàn)用多個(gè)任務(wù)“一起”執(zhí)行(實(shí)際上總有一些任務(wù)不在執(zhí)行悬蔽,因?yàn)榍袚Q任務(wù)的速度相當(dāng)快扯躺,看上去一起執(zhí)行而已)
- 并行:指的是任務(wù)數(shù)小于等于cpu核數(shù),即任務(wù)真的是一起執(zhí)行的
- 并行和并發(fā)都算是多任務(wù)蝎困,但并行實(shí)際上才是真正的多任務(wù)录语,并發(fā)是假的。
多任務(wù)的實(shí)現(xiàn)方法有多種禾乘,線程只是其中一種
線程的工作原理
以唱歌跳舞的案例說明
-
主線程
- 我們常說的一個(gè)程序代碼會(huì)從上往上執(zhí)行澎埠,默認(rèn)就是主線程來執(zhí)行的。
-
子線程
- 人工開啟的線程始藕。主線程會(huì)等待子線程結(jié)束后再結(jié)束蒲稳。
- 子線程的任務(wù)完成,這個(gè)子線程就會(huì)消失了
線程和線程之間會(huì)進(jìn)行資源的搶奪伍派,誰先執(zhí)行誰后執(zhí)行是不一定的
線程的兩種創(chuàng)建方式
- 直接使用threading模塊的Thread類江耀,指定要執(zhí)行的方法,再調(diào)用start
- 使用繼承的方式拙已,繼承Thread類决记,重新run方法,創(chuàng)建這個(gè)對(duì)象后倍踪,再調(diào)用start
查看當(dāng)前程序線程數(shù)量
- threading.enumerate()
- 獲取所有線程系宫,返回的是一個(gè)列表。
- 如果需要個(gè)數(shù)建车,使用len(threading.enumerate())
為子線程傳遞參數(shù)
- target方式
import time
import threading
def sing(nums):
for i in range(nums):
print("唱歌")
time.sleep(1)
def dance():
for i in range(5):
print("跳舞")
time.sleep(1)
# args后面跟的是參數(shù)元組
# kargs后面跟的是參數(shù)字典扩借,
# 但在這里,如果用的是字典缤至,字典的keys的名字要和target中的函數(shù)的參數(shù)名字一致
t1 = threading.Thread(target=sing, args=(3,))
# 或者 t1 = threading.Thread(target=sing, kargs={"nums" : 3})
t2 = threading.Thread(target=dance)
t1.start()
t2.start()
- 類繼承方式
import threading
class Work1(threading.Thread):
def __init__(self, nums):
# 要重寫父類的__init__方法潮罪,首先要在里面繼承父類的__init__方法
# 或者super().__init__()
threading.Thread.__init__(self)
self.nums = nums
def run(self):
for i in range(self.nums):
print("haha")
def main():
w = Work1(2)
w.start()
if __name__ == "__main__":
main()
多線程的應(yīng)用
在下載事件或者請求涉及到網(wǎng)絡(luò)的時(shí)候,會(huì)是多線程的形式進(jìn)行
點(diǎn)下載以后就會(huì)開一個(gè)線程讓它去下載领斥,主線程可以不用等下載完成了再去做別的操作
隊(duì)列(queue)和棧(stack)的概念
隊(duì)列:先進(jìn)先出嫉到,在手機(jī)應(yīng)用中有個(gè)運(yùn)行循環(huán),在監(jiān)聽事件操作月洛,不是多線程的話何恶,事件在隊(duì)列中過來,只有前一個(gè)事件運(yùn)行完了嚼黔,下一個(gè)事件再進(jìn)去循環(huán)细层,再進(jìn)行下一個(gè)事件
棧:先進(jìn)后出惜辑,----> 名詞概念:進(jìn)==>進(jìn)棧,出==>出棧 或 彈棧疫赎,棧中最上面==>棧頂盛撑,棧中最下面==>棧底
appium多端口
目標(biāo),讓一個(gè)腳本去跑到多臺(tái)手機(jī)捧搞。
實(shí)現(xiàn)的思想:要開多個(gè)appium服務(wù)(對(duì)應(yīng)多個(gè)端口號(hào))抵卫,然后不同的appium服務(wù)去連對(duì)應(yīng)的多個(gè)手機(jī)(對(duì)應(yīng)多個(gè)udid,只是一個(gè)唯一標(biāo)識(shí)的字符串)打開多個(gè)appium服務(wù):命令行打開appium胎撇,
appium -p 4723
陌僵,appium -p 4725
打開多個(gè)bootstrap服務(wù)(bootstrap引導(dǎo)的意思),與多個(gè)手機(jī)一一對(duì)應(yīng)
打開多個(gè)手機(jī):在virtualbox里面创坞,再導(dǎo)入多一個(gè)虛擬電腦碗短,在genymotion里面就會(huì)多一個(gè)手機(jī)模擬器,點(diǎn)start就好了
注意點(diǎn): appium sever端口要不同题涨,開啟多個(gè)偎谁。bootstrap端口要不同,開啟多個(gè)纲堵。udid需要指定巡雨,udid表示設(shè)備的唯一表示符號(hào),通過 adb devices 查看席函。 前半部分都是铐望,比如模擬器的(192.168.57.101:5555)。
appium server 和 bootstrap 和 udid 應(yīng)該是成對(duì)出現(xiàn)的茂附。
命令:
appium -p 4723 -bp 4724 -U 192.168.57.101:5555
p 表示 appium的端口
bp 表示 bootstrap的端口
U 表示設(shè)備的標(biāo)識(shí)符
修改init_driver讓正蛙,init_driver接受port的參數(shù)。并且進(jìn)行對(duì)應(yīng)的連接营曼。
記得乒验,創(chuàng)建的是不同的driver對(duì)象。因?yàn)槿绻褂胻hreading.Thread的這種形式蒂阱,需要指定執(zhí)行的函數(shù)锻全,所以,把需要執(zhí)行的代碼录煤,封裝成一個(gè)函數(shù)鳄厌。然后使用以下代碼:
在base_driver中
from appium import webdriver
def init_driver(port="4723"):
# server 啟動(dòng)參數(shù)
desired_caps = dict()
# 設(shè)備信息
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '5.1'
desired_caps['deviceName'] = '192.168.164.101:5555'
# app信息
desired_caps['appPackage'] = 'com.android.settings'
desired_caps['appActivity'] = '.Settings'
# 中文
desired_caps['unicodeKeyboard'] = True
desired_caps['resetKeyboard'] = True
# 不重置應(yīng)用
desired_caps['noReset'] = True
# toast
# desired_caps['automationName'] = 'Uiautomator2'
# 聲明對(duì)象
driver = webdriver.Remote('http://localhost:' + port + '/wd/hub', desired_caps)
return driver
在test_demo中:
import threading
from selenium.webdriver.common.by import By
from base_driver import init_driver
from base_action import BaseAction
from login_page import LoginPage
def do(port):
driver = init_driver(port)
login_page = LoginPage(driver)
if "4723" == port:
login_page.click((By.XPATH, "text,更多"))
else:
login_page.click((By.XPATH, "text,WLA"))
def main():
ports = ["4723", "4725"]
for i in ports:
threading.Thread(target=do, args=(i,)).start()
# for i in ports:
# driver = init_driver(i)
# login_page = LoginPage(driver)
# login_page.click((By.XPATH, "text,更多"))
if __name__ == '__main__':
main()
來去執(zhí)行創(chuàng)建多個(gè)driver并且進(jìn)行腳本的操作。
Webview
使用inspect檢查元素的好處是可以實(shí)時(shí)更新你在手機(jī)模擬器中的操作妈踊,但要翻墻
iOS
測試一個(gè)iOS項(xiàng)目的方法
開發(fā)ios的應(yīng)用可以用Xcode軟件了嚎,相當(dāng)于開發(fā)安卓軟件的Android studio,要測試ios應(yīng)用也要用Xcode响委,因?yàn)閄code中才有模擬器
拿到這個(gè)項(xiàng)目文件新思,藍(lán)色文件用Xcode打來,選擇好模擬器赘风,先運(yùn)行一下(就會(huì)在模擬器中安裝這個(gè)項(xiàng)目的app了)夹囚,然后可以在模擬器中做相關(guān)操作(home鍵是鍵盤中的command+H),也可以在Xcode中我們可以找到一些項(xiàng)目的信息(例如設(shè)備信息邀窃,app信息荸哟,需要在測試腳本的前置代碼中填寫的)
如果在Xcode中的Products文件夾下的app名字報(bào)紅了(就是還沒有安裝這個(gè)app),就可以先運(yùn)行一下(command+r)瞬捕,或者按著那個(gè)報(bào)紅的文件編譯一下(command+b)
-
還是在pycharm中寫測試腳本鞍历,在pycharm的terminal中pytest運(yùn)行
- 前置信息中,如果沒有安裝這個(gè)app肪虎,可以在Xcode中點(diǎn)Products下的已經(jīng)編譯過的app文件右鍵show in Finder(相當(dāng)于windows中的資源管理器)劣砍,然后復(fù)制一份里面的.app文件,去到你電腦測試項(xiàng)目文件夾下扇救, 然后在前置代碼中的desired_caps['app'] = os.path.abspath("./xxx.app")
- 建議拿到項(xiàng)目后先在Xcode運(yùn)行刑枝,模擬器中安裝了這個(gè)app就不用上面這種形式了
在iOS中,(View)Controller就相當(dāng)于安卓中的activity迅腔,一個(gè)界面對(duì)應(yīng)一個(gè)controller
在Xcode中運(yùn)行iOS項(xiàng)目
iOS前置代碼
對(duì)于已經(jīng)安裝了這個(gè)ios項(xiàng)目装畅,如何在Xcode中獲取它的bundleid信息(前置代碼中app信息,其實(shí)就是bundleid沧烈,相當(dāng)于安卓中的包名)
appium應(yīng)用的另一個(gè)功能掠兄,可以查看頁面元素
appium查看元素-android
appium左側(cè)三個(gè)功能和右側(cè)五個(gè)功能
appium查看元素-iOS
點(diǎn)擊事件
滑動(dòng)
Monkey
Monkey介紹
-
monkey 要用命令啟動(dòng)的話,首先要保證安卓模擬器是開著的
Monkey輸出日志
-
-p后面是要測試的包名锌雀,100是要執(zhí)行多少次動(dòng)作
Monkey基本參數(shù)介紹
- 課外知識(shí):md5加密算法
- 每次做monkey都建議加上-s seed值
- 延時(shí)設(shè)置的是每個(gè)事件之間的時(shí)間間隔蚂夕,并不是每個(gè)動(dòng)作,這里例子中的參數(shù)100腋逆,就是動(dòng)作双抽,100個(gè)動(dòng)作可能就幾個(gè)事件
-
可以通過-- pct-touch <percent> 等去控制想要發(fā)生的事件/動(dòng)作的比例
Monkey日志分析
-
如果出現(xiàn)了Exception,就拿之前設(shè)置的seed去復(fù)現(xiàn)闲礼,看點(diǎn)哪里出現(xiàn)問題牍汹,再拿真機(jī)去試操作,看是不是真的有問題
MonkeyRunner
- MonkeyRunner是一套工具柬泽,一套API慎菲,可以用python代碼去控制Monkey,告訴它去怎么生成這些隨機(jī)的事件
- 本質(zhì)和Monkey做的事情是一樣的锨并,但Monkey是用命令行實(shí)現(xiàn)的露该,一個(gè)使用代碼調(diào)用MonkeyRunner API實(shí)現(xiàn)的(MonkeyRunner底層也是用Monkey)
分辨率
像素
- 像素是長度單位,一個(gè)像素就是一個(gè)小方格第煮,一個(gè)小方格里面會(huì)有幾個(gè)色塊解幼,當(dāng)你在電腦屏幕上看到一個(gè)圖片是紅色的時(shí)候抑党,里面的像素小方格里面的色塊就只有紅色有數(shù)值,其余的色塊都是零撵摆,這就實(shí)現(xiàn)了顯示紅色了
- 但為什么兩臺(tái)設(shè)備有一樣的物理尺寸底靠,不一樣的分辨率,看到的圖片位置大小都一樣特铝?
- 這就涉及像素密(密度暑中,pixels for inch)的問題,在同樣尺寸鲫剿,不同分辨率的兩臺(tái)設(shè)備中鳄逾,項(xiàng)目會(huì)準(zhǔn)備大小不同的圖片(1x,2x灵莲,3x雕凹,安卓項(xiàng)目是在不同的文件夾下有相同的名稱的圖片,ios項(xiàng)目是在同一個(gè)文件夾下有不同名稱的圖片)政冻,讓圖片會(huì)去適配请琳,例如在小分辨率中占30像素的圖片,在分辨率大一倍的設(shè)備中就會(huì)占60像素
- 在功能測試中赠幕,如果要測分辨率俄精,就拿對(duì)應(yīng)的圖片大小去測主流分辨率的屏幕設(shè)備
補(bǔ)充:
- token ---> 在大部分的開發(fā)項(xiàng)目中表示身份,就是表示身份信息
測試流程
- 中斷測試不常見榕堰,但是像游戲這種需求實(shí)時(shí)性的應(yīng)用可能要做一下竖慧,但人工做就可以了
-
密碼MD5算法加密的是不可逆的,存在數(shù)據(jù)庫中的密碼也是加密過的逆屡,用戶請求發(fā)送過來的密碼(加密了)與數(shù)據(jù)庫中的加密過的密碼比對(duì)圾旨,一樣就能登陸