MQC功能測試大揭秘(4)- MQC 功能測試 DEMO
MQC為大家提供了海量的適配真機、強大的在線錄製、遍曆的用例管理、定製化的報告展示等功能,這篇文章將會通過一個 DEMO 教會大家如何利用好 MQC 提供的這些服務來回歸測試自己的 App。
如何使用 MQC 功能測試服務?
Appium 基礎篇有提到,desired capabilities 會提供 appium 運行時的各項環境參數,MQC 在功能測試開始前會動態生成desired capabilities類,用戶腳本隻需要調用相關 api 即可快速啟動 Appium。
import desired_capabilities
def setUp():
desired_caps = desired_capabilities.get_desired_capabilities()
uri = desired_capabilities.get_uri()
driver = webdriver.Remote(uri, desired_caps)
除此之外,MQC 提供了許多定製化的操作,隻需要按照格式進行簡單的 log 打印,就可以實現記錄步驟、截圖、記錄執行狀態等等操作,使得報告更加完善。當然,不打日誌同樣可以使用功能測試服務,隻需要上傳一個可執行的 main.py 文件(打包成zip文件)。
# 步驟1: 等待5s
print "STEP : 等待5s"
# 判斷該步驟執行狀態,FATAL : exception, 表示該步驟失敗; ASSERT : true, 表示該步驟成功; ASSERT : false, 表示該步驟失敗且該用例也失敗
print "FATAL : element not found"
# 為該步驟截圖
print "SCREENSHOT : 1"
一個合理且容易被解析的日誌結構應該如下:
STEP : 等待5s
SCREENSHOT : 0
STEP : 點擊控件:com.hexin.plat.android.ShenWanHongYuanSecurity:id/launch_ad
FATAL : element not found
SCREENSHOT : 1
STEP : 等待5s
SCREENSHOT : 2
STEP : 點擊控件:請輸入您有效的手機號
ASSERT : true
SCREENSHOT : 3
那麼,我們可以把上篇文章的 DEMO 進行改造,腳本如下:
# -*- coding: UTF-8 -*-
import unittest
import time
import sys
from appium import webdriver
from time import sleep
from unittest import TestCase
from appium.webdriver.common.touch_action import TouchAction
from selenium.webdriver.common.touch_actions import TouchActions
class MqcAppium(TestCase):
#設備寬高
global width
global height
#unittest 啟動
def setUp(self):
desired_caps = self.get_desired_capabilities()
uri = "https://localhost:4723/wd/hub"
retry = 0
while retry < 2:
try:
self.driver = webdriver.Remote(uri, desired_caps)
break
except Exception, e:
retry += 1
if retry == 2:
raise e
sleep(10)
# 獲取當前設備分辨率
self.window_size = self.driver.get_window_size()
self.width = self.window_size["width"]
self.height = self.window_size["height"]
# unittest 用例,用 test_**** 命名
def test_login(self):
#大部分app啟動後會有動畫,啟動延遲等,視情況預留啟動延遲
sleep(5)
#通過 resource-id 與 index 查找 個人中心 控件
navPerson = self.wait_for_element(, index=3);
navPerson.click()
#通過 text 查找 尚未登錄
noLogin = self.wait_for_element(xpath=("//*[@text='%s']" % ("尚未登錄")));
noLogin.click()
#通過 xpath、resource-id 多種方式定位登錄控件,避免有些手機上 xpath 失效或者不一致的情況
inputUsername = self.wait_for_element(xpath="//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]\
/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]/android.widget.EditText[1]", )
inputUsername.click()
inputUsername.send_keys("mqc_test")
inputPassword = self.wait_for_element(xpath="//android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/\
android.widget.FrameLayout[1]/android.widget.LinearLayout[1]/android.widget.LinearLayout[1]/android.widget.EditText[2]", )
inputPassword.click()
inputPassword.send_keys("123456")
login = self.wait_for_element()
login.click()
#返回 廣場 並且向下滑動
navGround = self.wait_for_element(, index=0);
navGround.click()
#與前文 swipe 函數不同的是,為了兼容不同分辨率的手機,滑動操作應當使用 比例 而非 絕對坐標,當然,若是需要精確地滑動操作,建議使用scrollTo
self.swipe([[0.5, 0.7], [0.5, 0.6], [0.5, 0.5], [0.5, 0.4], [0.5, 0.3]])
def tearDown(self):
try:
self.driver.quit()
except:
pass
def swipe(self, points):
last_x = 0
last_y = 0
swipe_action = TouchAction(self.driver)
for i in range(0, len(points)):
x=float(points[i][0]) * self.width
y=float(points[i][1]) * self.height
if i == 0:
swipe_action = swipe_action.press(None, x, y).wait(20)
elif i == (len(points) - 1):
swipe_action = swipe_action.move_to(None, x - last_x, y - last_y).release()
swipe_action.perform()
else:
swipe_action = swipe_action.move_to(None, x - last_x, y - last_y).wait(20)
last_x = x
last_y = y
def wait_for_element(self, xpath=None, id=None, index=None, timeout=3):
startTime = time.time()
nowTime = time.time()
while nowTime - startTime < timeout:
# 通過 xpath 查找控件
try:
if xpath is not None:
el = self.driver.find_element_by_xpath(xpath)
return el
except:
pass
# 通過 id 查找控件
try:
if id is not None:
if index is not None:
return self.driver.find_elements_by_id(id)[index]
else:
return self.driver.find_element_by_id(id)
except:
pass
sleep(1)
nowTime = time.time()
raise Exception("Element xpath[%s] id[%s] index[%s] not found" % (xpath, id, index))
if __name__ == '__main__':
try: unittest.main()
except SystemExit: pass
準備好腳本後,就可以到 MQC 平台進行提測了:
1.將這個腳本打包成zip包,到 MQC主頁 添加待測app, 之後進入用例庫頁麵
2.創建一個新用例,取名為 登錄
3.進入功能測試提測頁麵進行用例提測, 用戶自己上傳腳本創建用例需選中已上傳用例,使用在線錄製服務創建的用例需選擇已錄製用例
4.將上麵的 DEMO 腳本提測後,24小時內便可查看測試報告。
怎麼使用在線錄製?
大家寫功能測試腳本的時候一定有想過錄製回放這樣的功能,就是通過工具把操作錄製下來,而後再通過引擎回放錄製的動作。在線錄製結合了雲真機機型多的優勢,提供了這麼一項在線服務。在線錄製可以大大加速用例的生成,但是,一個好的用例是需要不斷地驗證打磨的,除了基本的點擊、滑動操作外,若您有具體的功能驗證需求,如圖片上傳、隨機密碼鍵盤等等,都是需要有經驗的工程師來修改完善腳本的, 在線錄製僅僅是用例腳本設計中的第一步。當然,若您有複雜的用例設計需求,也可以聯係我們,通過在阿裏雲購買人工支持用例設計,讓阿裏雲的測試專家為您的 app 量身定製用例。
在使用在線錄製的時候,可以看到下圖所示界麵
1.在點擊的時候若出現控件樹不準確的情況,需要手動點擊刷新(框1)來重新解析控件樹;
2.框2中的內容是控件的坐標、resource-id[index]、text信息;
3.有些 app 有左滑的起始頁,這裏封裝了一些滑動操作,可以有效避免錄製的左滑動作過快或過短導致回放失敗的問題;對於一些輸入操作,錄製時直接使用鍵盤輸入可能沒有準確識別出該步所有輸入文本,可以使用 輸入 按鈕來完成輸入的操作;
4.框4和框5是直接使用在線錄製回放腳本,可以快速驗證錄製腳本的準確性,框4能夠直接支持單步回放,框5可以構建appium腳本再使用appium引擎進行回放。
更多功能
MQC 提供了完善的測試流程管理功能,覆蓋測試的整個生命周期,除了在線錄製、真機回放、測試任務管理等,還有用例庫管理、App版本管理、App缺陷統計等等功能,歡迎大家來使用體驗,這裏重點介紹用例庫的參數管理。
大家在寫功能測試腳本的時候可能都用過excel來管理一些常量,並在測試的時候傳遞給測試用例,這些通常會是腳本裏的參數。在使用雲端真機進行測試的時候,可以通過參數管理功能來完成參數的分發、互踢等工作,直接在腳本中獲取參數,同時在線維護參數值。
如下圖創建兩組參數 username、password、point,在提測時選上使用的參數,平台會自動將參數分發到各個功能測試任務並執行
同樣,使用 desired_capabilities 類可以獲取到相應的參數:
import desired_capabilities
username = desired_capabilities.getParam("username")
password = desired_capabilities.getParam("password")
point = desired_capabilities.getParam("point")
到這 appium 功能測試的一些基本概念與服務已經介紹完全了,後續 MQC 會繼續和大家分享功能測試的一些專業知識,希望大家持續關注。
最後更新:2017-09-19 12:02:49