Airtest+ddt+unittest+html报告
RUN为入口,调用操作文件内的方法,去做各参数的传递与处理
操作文件
# -*- encoding=utf8 -*-
__author__ = "Qin"
import random
from airtest.core.api import *
from poco.drivers.android.uiautomation import AndroidUiautomationPoco
import csv
from pyfile import logfile
class CZ():
def __init__(self,):
self.poco = AndroidUiautomationPoco(use_airtest_input=True, screenshot_each_action=False)
def faxian(self,path):
try:#处理没有正常返回到发现页
FX=self.poco("ht.sview:id/topbar_title")
if FX:
logfile.logger.info('当前在--{}--页面'.format('发现'))
else:
#发现页面截图,查看是否为APP 崩溃
self.saveimg(path, '发现判断失败---' + str(random.Random(1,10000)))
logfile.logger.warning('关闭APP')
stop_app("ht.sview")
logfile.logger.error('不在发现页面')
sleep(1)
self.StartAPP()
except Exception as e:#APP异常崩溃
stop_app("ht.sview")
self.StartAPP()
logfile.logger.error('不在发现页面######{}'.format(e))
raise NameError ('不在发现页面!!!')
def getCsvData(self,filename):
# 读取CSV文件
value_rows = []
with open(filename, encoding='UTF-8') as f:
f_csv = csv.reader(f)
next(f_csv)
for r in f_csv:
value_rows.append(r)
return value_rows
def back(self,number):
for i in range(1,number+1):
keyevent("KEYCODE_BACK")
def saveimg(self,path,name):
# snapshot(filename="{}\\loging\\{}.png".format(path,name), msg="断言失败截图", quality=90,
# max_size=1200)
snapshot(filename="{}\logimg\img\{}.png".format(path,name))
def StartAPP(self):
start_app("ht.sview")
sleep(1)
# 判断广告
try:
pos = exists(Template(r"common/tiaoguo.png"))
if pos:
logfile.logger.info('定位到广告跳转按钮')
touch(pos)
else:
logfile.logger.warning('没有定位到广告')
except Exception as e:
logfile.logger.warning('广告处理异常')
logfile.logger.error(e)
bendi_btn = self.poco("android.widget.FrameLayout").child("android.widget.LinearLayout").offspring(
"ht.sview:id/tab_local_iv")
bendi_btn.wait_for_appearance(timeout=10) # 等待本地按钮加载出来
sleep(0.5)
self.poco("ht.sview:id/tab_net_iv").click() # 点击发现
self.loading('common/请稍后加载.png', 50) # 等待列表加载完毕,10秒等待
def clickimg(self,filename):#定位图片并且点击
touch(Template(filename, record_pos=(-0.105, -0.96), resolution=(1080, 2340)))#点击图片
def sousuo(self,modelname):
self.poco("ht.sview:id/topbar_search").click() # 点击搜索按钮
sleep(0.5)
self.clickimg("common/搜索.png")
sleep(0.3)
text('{}'.format(modelname), search=True) # 输入输入框内容并执行搜索
self.loading('common/请稍后加载.png', 10) # 等待搜索加载完毕,10秒等待
self.poco("android.widget.FrameLayout").child("android.widget.LinearLayout").offspring("android:id/content").offspring(
"ht.sview:id/clouddialog_file_rv").child("android.widget.RelativeLayout")[0].offspring(
"ht.sview:id/imageView1").click() # 点击第一个
sleep(0.5)
def loading(self,file,time):
sleep(0.5)#等待反应进入发现列表
i=0
while i < time:
pos=exists(Template(file))
if pos:#如果为真
print('正在加载。。。。。')
sleep(1)
i = i + 1
print('等待{}秒'.format(i))
else:
print('加载完成,执行下一步')
break
def details(self,name):#详情页面操作,并进入三维视图
logfile.logger.info('进入{}详情页'.format(name))
self.clickimg("common/浏览模型.jpg")
alter=self.poco("android.widget.FrameLayout").offspring("android:id/content").child("android.widget.LinearLayout").child(
"android.widget.LinearLayout")
if alter:
print('定位到没有下载过该模型')
sleep(0.3)
self.poco("ht.sview:id/alert_dialog_ok_btn").click()#确认下载模型
self.loading('common/下载进度.jpg',60)#等待模型下载完成
sleep(1)
self.loading('common/模型-打开加载.jpg', 60) # 等待模型下载完成
print('文件已下载')
else:
print('已下载该模型')
self.loading('common/模型-打开加载.jpg', 60) # 等待模型下载完成
def Sview(self,path,name):
pct='common/三维视图初始状态.jpg'
try:
if exists(Template(pct)):
logfile.logger.info('已打开{}三维视图页面'.format(name))
print('成功打开{}三维视图页面'.format(name))
self.saveimg(path, name)
else:
self.saveimg(path,'失败---'+name)
with open('{}/logimg/报错模型.txt'.format(path),'a+') as f:
f.write('{}---------------打开失败\n'.format(name))
logfile.logger.info('{}打开失败'.format(name))
raise NameError("{}三维视图打开失败!!!!!".format(name))
except Exception as e:
logfile.logger.error(e)
print(e)
print('三维视图图片检测异常')
raise NameError("{}三维视图打开失败!!!!!{}".format(name,e))
if __name__ == '__main__':
pass
# aaa("C:\\Users\\Administrator\\Desktop\\untitled.air\\",'hahah23423421啊啊啊haah.png')
# StartAPP()
# sousuo()
# details()#详情页面操作,并进入三维视图
# Sview()
Run.py
import os
import unittest
from ddt import ddt, data, unpack
from BeautifulReport import BeautifulReport as bf#模板1
import caozuo
from pyfile import logfile
import time
@ddt
# ddt驱动
class MyTestCase(unittest.TestCase):
a='''
请确保已正常连接ANDROID设备
'''
logfile.logger.info(a)
logfile.logger.info('#####################开始执行操作#####################')
try:
dev = caozuo.CZ()
dev.StartAPP()
dir_path = os.getcwd()
print(dir_path)
logfile.logger.info("当前目录为{}".format(dir_path))
except Exception as e:
logfile.logger.error(e)
raise NameError('启动报错')
try:
datalist = dev.getCsvData(dir_path + '\lists.csv')#pycham需要加入\
except Exception as e:
logfile.logger.error(e)
time.sleep(5)
raise NameError ("测试文件错误!!!")
def setUp(self):
logfile.logger.info('---执行用例---')
self.dev.faxian(self.dir_path)#判断当前是否在发现页
@data(*datalist)
# 测试数据
@unpack
# 解包
def test_SView_Model(self,name):
# print(name)
# if len(name)<10:
# self.dev.sousuo(name)
# self.dev.saveimg(self.dir_path,name)
# print('screenshot:', "{}//logimg//{}.png".format(self.dir_path, name),'.png')
# raise NameError('长度不足10')
# else:
# print('执行成功')
self.dev.sousuo(name)#执行搜索
self.dev.details(name)#详情页面
self.dev.Sview(self.dir_path,name)
# print('screenshot:', "{}//logimg//{}.png".format(self.dir_path, name), '.png')
def tearDown(self):
self.dev.back(3)#返回三次
logfile.logger.info('---关闭用例---')
if __name__ == '__main__':
# 创建一个测试套件
a=MyTestCase()
suite = unittest.TestSuite()
# 将测试用例加载到测试套件中
loader = unittest.TestLoader() # 创建一个用例加载对象
suite.addTest(loader.loadTestsFromTestCase(MyTestCase))
run = bf(suite) # 实例化BeautifulReport模块
run.report(filename='/logimg/测试报告.html', description='测试报告', report_dir=a.dir_path, log_path=a.dir_path)
logfile.logger.info('#####################执行完成############################')
loging.py
import logging
logger = logging.getLogger("SView-APP") # 定义对应的程序模块名name,默认是root
logger.setLevel(logging.DEBUG) # 指定最低的日志级别 critical > error > warning > info > debug
consol_haddler = logging.StreamHandler() # 日志输出到屏幕控制台
consol_haddler.setLevel(logging.INFO) # 设置日志等级
# 这里进行判断,如果logger.handlers列表为空,则添加,否则,直接去写日志,解决重复打印的问题
if not logger.handlers:
file_haddler = logging.FileHandler("./logimg/SViewlog.log",encoding = "utf-8") # 向文件log.txt输出日志信息,encoding="utf-8",防止输出log文件中文乱码
file_haddler.setLevel(logging.INFO) # 设置输出到文件最低日志级别
formatter = logging.Formatter("%(asctime)s %(name)s- %(levelname)s - %(message)s")
# %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
# %(name)s 自定义的模块名
consol_haddler.setFormatter(formatter) # 选择一个输出格式,可以定义多个输出格式
file_haddler.setFormatter(formatter)
logger.addHandler(file_haddler) # 增加指定的handler
logger.addHandler(consol_haddler)