报告统计
yaml 管理所有的配置文件.只要改 case 配置,不用改其他代码
配置 case 的参数介绍
element_info: cn.ibona.t1_beta:id/GroupPersonItemPosition
find_type: by_id
find_element_by_id = "by_id"
find_elements_by_id = "by_ids"
find_element_by_name = "by_name"
find_elements_by_name = "by_names"
find_element_by_link_text ="by_link_text"
find_elements_by_link_text = "by_link_texts"
find_element_by_xpath = "by_xpath"
find_elements_by_xpath = "by_xpaths"
find_element_by_class_name = "class_name"
find_elements_by_class_name = "class_names"
operate_type: click
SEND_KEYS = "send_keys" 输入
TAP = "tap"
SWIPELEFT = "swipeLeft" 左滑动,一般还有配置time参数(左滑次数)
CLICK = "click"
text: 1111111 此参数一般与 send_keys 配套,表示输入的参数
index: 0 此参数一般与 find_type 配置里面的 ids,names,xpaths 等一组文件配套使用
test_id: 1003 用例 id
test_intr: 个人反馈 用例介绍
---
-
element_info: //android.widget.Button[@text='允许']
test_intr: 引导图
operate_type: click
find_type: by_xpath
test_id: 1001
-
element_info: cn.ibona.t1_beta:id/btn_skip
operate_type: click
find_type: by_id
-
operate_type: swipeLeft
time: 5
element_info: android.widget.ImageView
find_type: class_name
-
element_info: android.widget.Button
find_type: by_name
name: 立即开启
入口参数化了 unittest
PATH = lambda p: os.path.abspath(
os.path.join(os.path.dirname(__file__), p)
)
def appDevices():
mapp = MAppDevices.getDriver()
return BAppDevices.appDevices(mapp, PATH("../AppDevices.ini"))
ga = appDevices()
class TestInterfaceCase(unittest.TestCase):
def __init__(self, methodName='runTest'):
super(TestInterfaceCase, self).__init__(methodName)
@staticmethod
def setUpClass():
desired_caps = {}
global driver
if ga.platformName == common.ANDROID or ga.platformName == common.IOS:
if common.FLAG:
desired_caps['platformName'] = ga.platformName
desired_caps['platformVersion'] = ga.platformVersion
desired_caps['deviceName'] = ga.deviceName
desired_caps['appPackage'] = ga.appPackage
desired_caps['appActivity'] = ga.appActivity
desired_caps['app'] = PATH(
'../img/t.apk'
)
# desired_caps["unicodeKeyboard"] = "True"
# desired_caps["resetKeyboard"] = "True"
common.PACKAGE = ga.appPackage
driver = webdriver.Remote(ga.Remote, desired_caps)
common.DRIVER = driver
common.FLAG = False
def setUp(self):
print("setUp")
@staticmethod
def tearDownClass():
# driver.close_app()
# driver.quit()
print('tearDownClass')
@staticmethod
def parametrize(testcase_klass):
testloader = unittest.TestLoader()
testnames = testloader.getTestCaseNames(testcase_klass)
suite = unittest.TestSuite()
for name in testnames:
suite.addTest(testcase_klass(name))
return suite
# 引用需要导入的class写的case
from testCase.Home import testHome
from testCase.work import testContact
def runnerCaseApp():
start_test_time = dataToString.getStrTime(time.localtime(), "%Y-%m-%d %H:%M %p")
suite = unittest.TestSuite()
starttime = datetime.datetime.now()
suite.addTest(TestInterfaceCase.parametrize(testHome))
suite.addTest(TestInterfaceCase.parametrize(testContact))
unittest.TextTestRunner(verbosity=2).run(suite)
endtime = datetime.datetime.now()
get_common_report(start_test_time, endtime, starttime)
report()
if __name__ == '__main__':
if BAdbCommon.attached_devices():
if ga.platformName == common.ANDROID or ga.platformName == common.IOS:
appium_server = BtestServer.AppiumServer(ga.appiumJs, ga.Remote)
appium_server.start_server()
while not appium_server.is_runnnig():
time.sleep(2)
runnerCaseApp()
appium_server.stop_server()
else:
print(u"设备不存在")
class testHome(TestInterfaceCase):
def __init__(self, methodName=''):
super(testHome, self).__init__(methodName)
self.bc = BaseCaseList.BexceCase(test_module="个人中心", getTempCase=MBaseTestCase.getTempCase, BaseTestCase=MBaseTestCase.BaseTestCase, fps=[], cpu=[], men=[])
def home_fist_open(self):
self.bc.execCase(PATH("yaml/myinfo/home_fist_open.yaml"), test_name="test_home_fist_open", isLast="0")
def home_login(self):
self.bc.execCase(PATH("yaml/myinfo/home_login.yaml"), test_name="test_home_login", isLast="0")
def home_feed(self):
self.bc.execCase((PATH("yaml/myinfo/home_feed.yaml")), test_name="test_home_feed", isLast="1") # isLast表示的意思是最后一个case用于后面的统计
@staticmethod
def tearDownClass():
pass
# 注意这里的小技巧,这样按顺序放入case,可以按顺序执行
def test_home(self):
self.home_fist_open()
self.home_login()
self.home_feed()
class BexceCase():
def __init__(self, test_module="", getTempCase="", BaseTestCase="",fps=[], cpu=[], men=[]):
self.test_module = test_module
self.getTempCase = getTempCase
self.BaseTestCase = BaseTestCase
self.fps = fps
self.cpu = cpu
self.men = men
def getModeList(self, f):
bs = []
gh = getXMl.getYam(f)
for i in range(len(gh)):
if i == 0:
#用例id
self.getTempCase.test_id = gh[i].get("test_id", "false")
# 用例介绍
self.getTempCase.test_intr = gh[i].get("test_intr", "false")
# bt = self.BaseTestCase
self.BaseTestCase.element_info = gh[i].get("element_info", "false")
# 操作类型
self.BaseTestCase.operate_type = gh[i].get("operate_type", "false")
# 输入文字
self.BaseTestCase.name = gh[i].get("name", "false")
self.BaseTestCase.index = gh[i].get("index", "false")
self.BaseTestCase.text = gh[i].get("text", "false") # 对应by_link_text
# 验证类型
self.BaseTestCase.find_type = gh[i].get("find_type", "false")
self.BaseTestCase.time = gh[i].get("time", 0)
bs.append(json.loads(json.dumps(self.BaseTestCase().to_primitive())))
return bs
def execCase(self, f, **kwargs):
logTest = testLog.myLog().getLog()
bc = self.getModeList(f)
go = bo.getOperateElement(driver=common.DRIVER)
ch_check = bc[-1]
for k in bc:
if k["operate_type"] != "false":
if go.operate_element(k)== False:
logTest.checkPointNG(common.DRIVER, kwargs["test_name"], kwargs["test_name"])
logTest.resultNG(kwargs["test_name"], "找不页面元素")
get_men = ap.get_men(common.PACKAGE)
get_cpu = ap.top_cpu(common.PACKAGE)
get_fps = ap.get_fps(common.PACKAGE)
self.cpu.append(get_cpu)
self.men.append(get_men)
self.fps.append(get_fps)
common.MEN.append(get_men)
common.CPU.append(get_cpu)
common.FPS.append(get_fps)
if go.findElement(ch_check):
common.test_success += 1
self.getTempCase.test_result = "成功"
logTest.resultOK(kwargs["test_name"])
else:
# logTest.screenshotNG(common.DRIVER, kwargs["test_name"])
logTest.checkPointNG(common.DRIVER, kwargs["test_name"], kwargs["test_name"])
common.test_failed += 1
test_reason = "检查不到元素"
# if common.I_ANR > 0:
# test_reason = "有ANR错误"
# if common.I_CRASH > 0:
# test_reason = "有CRASH错误"
# if common.I_EXCEPTION > 0:
# test_reason = "有EXCEPTION错误"
self.getTempCase.test_result = "失败"
self.getTempCase.test_reason = test_reason
self.getTempCase.test_name =kwargs["test_name"]
self.getTempCase.test_module = self.test_module
common.test_sum += 1
self.getTempCase.test_men_max = rp.phone_max_use_raw(self.men)
avg_men = ba.get_avg_raw(self.men) # 获取每次占用内存多少
self.getTempCase.test_men_avg = avg_men
self.getTempCase.test_cpu_max = rp.phone_avg_max_use_cpu(self.cpu)
self.getTempCase.test_cpu_avg = rp.phone_avg_use_cpu(self.cpu)
self.getTempCase.test_fps_max = rp.fps_max(self.fps)
self.getTempCase.test_fps_avg = rp.fps_avg(self.fps)
common.RESULT["info"].append(json.loads(json.dumps(self.getTempCase().to_primitive())))
if kwargs["isLast"] == "1":
# 最后case要写最下面的统计步骤
common.RRPORT["info"].append(common.RESULT["info"])
# 此脚本主要用于查找元素是否存在,操作页面元素
class getOperateElement():
def __init__(self, driver=""):
self.cts = driver
def findElement(self, mOperate):
'''
查找元素.mOperate是字典
operate_type:对应的操作
element_info:元素详情
find_type: find类型
'''
try:
WebDriverWait(self.cts, common.WAIT_TIME).until(lambda x: elements_by(mOperate, self.cts))
return True
except selenium.common.exceptions.TimeoutException:
return False
except selenium.common.exceptions.NoSuchElementException:
print("找不到数据")
return False
def operate_element(self, mOperate):
if self.findElement(mOperate):
elements = {
common.CLICK: lambda: operate_click(mOperate, self.cts),
# common.TAP: lambda: operate_tap(mOperate["find_type"], self.cts, mOperate["element_info"], arg),
common.SEND_KEYS: lambda: send_keys(mOperate, self.cts),
common.SWIPELEFT: lambda : opreate_swipe_left(mOperate, self.cts)
}
return elements[mOperate["operate_type"]]()
return False
# 点击事件
def operate_click(mOperate,cts):
if mOperate["find_type"] == common.find_element_by_id or mOperate["find_type"] == common.find_element_by_name or mOperate["find_type"] == common.find_element_by_xpath:
elements_by(mOperate, cts).click()
if mOperate["find_type"] == common.find_elements_by_id or mOperate["find_type"] == common.find_elements_by_name:
elements_by(mOperate, cts)[mOperate["index"]].click()
# 记录运行过程中的一些系统日志,比如闪退会造成自动化测试停止
errorLog.get_error(log=r"d:\operate_log.txt")
def opreate_swipe_left(mOperate, cts):
time.sleep(1)
width = cts.get_window_size()["width"]
height = cts.get_window_size()["height"]
for i in range(mOperate["time"]):
cts.swipe(width/4*3, height / 2, width / 4 *1, height / 2, 500)
time.sleep(1)
# start_x,start_y,end_x,end_y
# 轻打x轴向右移动x单位,y轴向下移动y单位
# def operate_tap(elemen_by,cts,element_info, xy=[]):
# elements_by(elemen_by, cts, element_info).tap(x=xy[0], y=xy[1])
def send_keys(mOperate,cts):
elements_by(mOperate, cts).send_keys(mOperate["text"])
# 封装常用的标签
def elements_by(mOperate, cts):
elements = {
common.find_element_by_id : lambda :cts.find_element_by_id(mOperate["element_info"]),
common.find_elements_by_id : lambda :cts.find_elements_by_id(mOperate["element_info"]),
common.find_element_by_xpath: lambda :cts.find_element_by_xpath(mOperate["element_info"]),
common.find_element_by_name: lambda :cts.find_element_by_name(mOperate['name']),
common.find_elements_by_name: lambda :cts.find_elements_by_name(mOperate['name'])[mOperate['index']],
common.find_element_by_class_name: lambda :cts.find_element_by_class_name(mOperate['element_info']),
common.find_elements_by_class_name: lambda :cts.find_elements_by_class_name(mOperate['element_info'])[mOperate['index']]
}
return elements[mOperate["find_type"]]()
# 常用的性能监控
def top_cpu(pkg_name):
result = 0
cmd = "adb shell dumpsys cpuinfo | grep -w " + pkg_name+":"
temp = []
# cmd = "adb shell top -n %s -s cpu | grep %s$" %(str(times), pkg_name)
top_info = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.readlines()
for info in top_info:
temp.append(info.split()[2].decode()) # bytes转换为string
break
for i in temp:
if i != "0%":
print("cpu="+i)
result = int(i.split("%")[0])
return result
# 得到men的使用情况
def get_men(pkg_name):
result = "0"
cmd = "adb shell dumpsys meminfo %s" %(pkg_name)
temp = []
m = []
men_s = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.readlines()
for info in men_s:
temp.append(info.split())
m.append(temp)
for t in m:
result = t[19][1]
break
return int(result.decode())
# 得到fps
def get_fps(pkg_name):
_adb = "adb shell dumpsys gfxinfo %s | grep -A 128 'Execute' | grep -v '[a-Z]' "%pkg_name
result = os.popen(_adb).read().strip()
result = result.split('\r\n')
# r_result = [] # 总值
# t_result = [] # draw,Process,Execute分别的值
# f_sum = 0
for i in result:
l_result = i.split('\t')[-3:]
f_sum = 0
for j in l_result:
r = re.search(r"\d+\.\d+", str(j))
if r:
f_sum += float(r.group())
# t_result.append('%.2f'%f_sum)
return float('%.2f'%f_sum)