目录
前言:
简介
功能
常用目录
配置
实例 - 第一次启动 app
实例 - 登录
代码入口实例
结果展示
前言:
Page Object模式是一种常用的设计模式,用于组织和管理自动化测试脚本中的页面对象。它将页面的元素和操作封装在一个独立的类中,使测试脚本更加模块化、可维护和可重用。
简介
- 基于 appium+python3 封装的自动化测试框架
功能
- python3
- unittest 参数化
- pageobject
- 数据维护用的 YMAL
- excel 的测试报告
- 支持多设备 andoird 并行
- 支持 webview
常用目录
- Base 封装常用方法
- Log 记录不同设备的操作用例的日志,操作失败的截图
- PageObject 放 page
- test 目录写测试用例
- runner 运行入口
配置
配置 run.yaml
app: Jianshu.apk
配置 devices.yaml
- devices: emulator-5554
port: 4724
config: appium --session-override -p 4724 -bp 4734 -U emulator-5554
platformName: android
- devices: DU2TAN15AJ049163
port: 4725
config: appium --session-override -p 4725 -bp 4735 -U DU2TAN15AJ049163
platformName: android
实例 - 第一次启动 app
配置用例 yaml
testinfo:
- id: test001
title: 第一次打开
testcase:
- operate_type: swipeLeft
time: 4
element_info: android.widget.ImageView
find_type: class_name
- element_info: com.jianshu.haruki:id/tv_enter
find_type: id
operate_type: click
check:
- element_info: com.jianshu.haruki:id/btn_login
find_type: id
PageObject
class FirstOpen:
'''
kwargs: WebDriver driver, String path(yaml配置参数)
isOperate: 操作失败,检查点就失败
testInfo:
testCase:
'''
def __init__(self, **kwargs):
self.driver = kwargs["driver"]
self.path = kwargs["path"]
self.operateElement = OperateElement(self.driver)
self.isOperate = True
self.testInfo = getYam(self.path)["testinfo"]
self.testCase = getYam(self.path)["testcase"]
'''
操作步骤
logTest 日记记录器
'''
def operate(self, logTest):
for item in self.testCase:
result = self.operateElement.operate(item, self.testInfo, logTest)
if not result:
print("操作失败")
self.isOperate = False
break
'''
检查点
caseName:函数名
logTest 记录日志:一个手机记录单独记录一个日志
'''
def checkPoint(self, caseName, logTest, devices):
result = False
if not self.isOperate:
print("操作失败,检查点失败")
# return self.isOperate
else:
check = getYam(self.path)["check"]
result = self.operateElement.findElement(check) # 检查点
countSum(result)
countInfo(result=result, testInfo=self.testInfo, caseName=caseName, driver=self.driver, logTest=logTest, devices=devices)
return result
test
PATH = lambda p: os.path.abspath(
os.path.join(os.path.dirname(__file__), p)
)
class FirstOpenTest(ParametrizedTestCase):
def testFirst(self):
firsOpen = FirstOpen(driver=self.driver, path=PATH("../yaml/firstOpen.yaml"))
firsOpen.operate(logTest=self.logTest)
firsOpen.checkPoint(caseName=self.__class__.__name__, logTest=self.logTest, devices=self.devices["deviceName"])
def setUp(self):
super(FirstOpenTest, self).setUp()
实例 - 登录
配置 yaml
testinfo:
- id: test0002
title: 登录
testcase:
- element_info: com.jianshu.haruki:id/btn_login
find_type: id
operate_type: click
- element_info: com.jianshu.haruki:id/et_tel
find_type: id
operate_type: set_value
text: username
- element_info: com.jianshu.haruki:id/et_password
find_type: id
operate_type: set_value
text: pwd
- element_info: com.jianshu.haruki:id/btn_register_1
find_type: id
operate_type: click
- element_info: //android.widget.ImageView[@index='0']
find_type: xpath
operate_type: click
check:
- element_info: com.jianshu.haruki:id/add_subscribe
find_type: id
- element_info: com.jianshu.haruki:id/tab_more
find_type: id
PageObject
class Login:
'''
kwargs: WebDriver driver, String path(yaml配置参数)
isOperate: 操作失败,检查点就失败
testInfo:
testCase:
'''
def __init__(self, **kwargs):
self.driver = kwargs["driver"]
self.path = kwargs["path"]
self.operateElement = OperateElement(self.driver)
self.isOperate = True
self.testInfo = getYam(self.path)["testinfo"]
self.testCase = getYam(self.path)["testcase"]
'''
操作步骤
logTest 日记记录器
'''
def operate(self, logTest):
for item in self.testCase:
result = self.operateElement.operate(item, self.testInfo, logTest)
if not result:
print("操作失败")
self.isOperate = False
break
'''
检查点
caseName:测试用例函数名 用作统计
logTest: 日志记录
devices 设备名
'''
def checkPoint(self, caseName, logTest, devices):
result = False
if not self.isOperate:
print("操作失败,检查点失败")
else:
check = getYam(self.path)["check"]
result = self.operateElement.findElement(check) # 检查点
countSum(result)
countInfo(result=result, testInfo=self.testInfo, caseName=caseName, driver=self.driver, logTest=logTest, devices=devices)
return result
test
PATH = lambda p: os.path.abspath(
os.path.join(os.path.dirname(__file__), p)
)
class LoginTest(ParametrizedTestCase):
def testLogin(self):
login = Login(driver=self.driver, path=PATH("../yaml/login.yaml"))
login.operate(logTest=self.logTest)
login.checkPoint(caseName=self.__class__.__name__, logTest=self.logTest, devices=self.devices["deviceName"])
# def testWrongPwd(self):
# pass
def setUp(self):
super(LoginTest, self).setUp()
代码入口实例
def runnerCaseApp(devices):
starttime = datetime.now()
suite = unittest.TestSuite()
suite.addTest(ParametrizedTestCase.parametrize(FirstOpenTest, param=devices)) # 引用不同的测试类
suite.addTest(ParametrizedTestCase.parametrize(LoginTest, param=devices)) # 引用不同的测试类
unittest.TextTestRunner(verbosity=2).run(suite)
endtime = datetime.now()
countDate(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), str((endtime - starttime).seconds) + "秒"
...
if __name__ == '__main__':
if AndroidDebugBridge().attached_devices():
getDevices = init()
appium_server = AppiumServer(getDevices)
appium_server.start_server()
while not appium_server.is_runnnig():
time.sleep(2)
runnerPool(getDevices)
appium_server.stop_server()
writeExcel()
else:
print(u"设备不存在")
结果展示
日志目录
文件夹:samsung_GT-I9500_android_4.4,包含截图
2017-06-07 19:39:35,972 - INFO - ---- test001_第一次打开_android.widget.ImageView START ----
2017-06-07 19:39:44,433 - INFO - [CheckPoint_1]: FirstOpenTest: NG
2017-06-07 19:40:02,013 - INFO - ---- test0002_登录_com.jianshu.haruki:id/btn_login START ----
2017-06-07 19:40:03,075 - INFO - ---- test0002_登录_com.jianshu.haruki:id/et_tel START ----
2017-06-07 19:40:07,460 - INFO - ---- test0002_登录_com.jianshu.haruki:id/et_password START ----
2017-06-07 19:40:08,480 - INFO - ---- test0002_登录_com.jianshu.haruki:id/btn_register_1 START ----
2017-06-07 19:40:13,640 - INFO - ---- test0002_登录_//android.widget.ImageView[@index='0'] START ----
测试报告
作为一位过来人也是希望大家少走一些弯路
在这里我给大家分享一些自动化测试前进之路的必须品,希望能对你带来帮助。
(软件测试相关资料,自动化测试相关资料,技术问题答疑等等)
相信能使你更好的进步!
点击下方小卡片