【自动化测试】Pytest+Appium+Allure 做 UI 自动化的那些事

这篇具有很好参考价值的文章主要介绍了【自动化测试】Pytest+Appium+Allure 做 UI 自动化的那些事。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

文本主要介绍下 Pytest+Allure+Appium 记录一些过程和经历。

法主要用了啥:

Python3
Appium
Allure-pytest
Pytest

Appium 不常见却好用的方法

Appium 直接执行 adb shell 方法

#Appium 启动时增加 --relaxed-security 参数 Appium 即可执行类似adb shell的方法
appium -p 4723 --relaxed-security

#使用方法
def adb_shell(self, command, args, includeStderr=False):
“”"
appium --relaxed-security 方式启动
adb_shell(‘ps’,[‘|’,‘grep’,‘android’])

:param command:命令
:param args:参数
:param includeStderr: 为 True 则抛异常
:return:
“”"
result = self.driver.execute_script(‘mobile: shell’, {
‘command’: command,
‘args’: args,
‘includeStderr’: includeStderr,
‘timeout’: 5000
})
return result[‘stdout’]

Appium 直接截取元素图片的方法
element = self.driver.find_element_by_id(‘cn.xxxxxx:id/login_sign’)
pngbyte = element.screenshot_as_png
image_data = BytesIO(pngbyte)
img = Image.open(image_data)
img.save(‘element.png’)
#该方式能直接获取到登录按钮区域的截图

Appium 直接获取手机端日志
#使用该方法后,手机端 logcat 缓存会清除归零,从新记录
#建议每条用例执行完执行一边清理,遇到错误再保存减少陈余 log 输出
#Android
logcat = self.driver.get_log(‘logcat’)

#iOS 需要安装 brew install libimobiledevice
logcat = self.driver.get_log(‘syslog’)

#web 获取控制台日志
logcat = self.driver.get_log(‘browser’)

c = ‘\n’.join([i[‘message’] for i in logcat])
allure.attach(c, ‘APPlog’, allure.attachment_type.TEXT)
#写入到 allure 测试报告中

Appium 直接与设备传输文件
#发送文件
#Android
driver.push_file(‘/sdcard/element.png’, source_path=‘D:\works\element.png’)

#获取手机文件
png = driver.pull_file(‘/sdcard/element.png’)
with open(‘element.png’, ‘wb’) as png1:
png1.write(base64.b64decode(png))

#获取手机文件夹,导出的是zip文件
folder = driver.pull_folder(‘/sdcard/test’)
with open(‘test.zip’, ‘wb’) as folder1:
folder1.write(base64.b64decode(folder))

#iOS
#需要安装 ifuse
#> brew install ifuse 或者 > brew cask install osxfuse 或者 自行搜索安装方式

driver.push_file(‘/Documents/xx/element.png’, source_path=‘D:\works\element.png’)

#向 App 沙盒中发送文件
#iOS 8.3 之后需要应用开启 UIFileSharingEnabled 权限不然会报错
bundleId = ‘cn.xxx.xxx’ # APP名字
driver.push_file(‘@{bundleId}/Documents/xx/element.png’.format(bundleId=bundleId), source_path=‘D:\works\element.png’)

Pytest 与 Unittest 初始化上的区别
很多人都使用过 unitest 先说一下 pytest 和 unitest 在 Hook method上的一些区别

1.Pytest 与 unitest 类似,有些许区别,以下是 Pytest
class TestExample:
def setup(self):
print(“setup class:TestStuff”)

def teardown(self):
print (“teardown class:TestStuff”)

def setup_class(cls):
print (“setup_class class:%s” % cls.name)

def teardown_class(cls):
print (“teardown_class class:%s” % cls.name)

def setup_method(self, method):
print (“setup_method method:%s” % method.name)

def teardown_method(self, method):
print (“teardown_method method:%s” % method.name)

2.使用 pytest.fixture()
@pytest.fixture()
def driver_setup(request):
request.instance.Action = DriverClient().init_driver(‘android’)
def driver_teardown():
request.instance.Action.quit()
request.addfinalizer(driver_teardown)

初始化实例
1.setup_class 方式调用
class Singleton(object):
“”“单例
ElementActions 为自己封装操作类”“”
Action = None

def new(cls, *args, **kw):
if not hasattr(cls, ‘_instance’):
desired_caps={}
host = “http://localhost:4723/wd/hub”
driver = webdriver.Remote(host, desired_caps)
Action = ElementActions(driver, desired_caps)
orig = super(Singleton, cls)
cls._instance = orig.new(cls, *args, **kw)
cls._instance.Action = Action
return cls._instance

class DriverClient(Singleton):
pass

测试用例中调用

class TestExample:
def setup_class(cls):
cls.Action = DriverClient().Action

def teardown_class(cls):
cls.Action.clear()

def test_demo(self)
self.Action.driver.launch_app()
self.Action.set_text(‘123’)

2.pytest.fixture() 方式调用
class DriverClient():

def init_driver(self,device_name):
desired_caps={}
host = “http://localhost:4723/wd/hub”
driver = webdriver.Remote(host, desired_caps)
Action = ElementActions(driver, desired_caps)
return Action

#该函数需要放置在 conftest.py, pytest 运行时会自动拾取
@pytest.fixture()
def driver_setup(request):
request.instance.Action = DriverClient().init_driver()
def driver_teardown():
request.instance.Action.clear()
request.addfinalizer(driver_teardown)

测试用例中调用

#该装饰器会直接引入driver_setup函数
@pytest.mark.usefixtures(‘driver_setup’)
class TestExample:

def test_demo(self):
self.Action.driver.launch_app()
self.Action.set_text(‘123’)

Pytest 参数化方法
1.第一种方法 parametrize 装饰器参数化方法
@pytest.mark.parametrize((‘kewords’), [(u"小明"), (u"小红"), (u"小白")])
def test_kewords(self,kewords):
print(kewords)

#多个参数
@pytest.mark.parametrize(“test_input,expected”, [
(“3+5”, 8),
(“2+4”, 6),
(“6*9”, 42),
])
def test_eval(test_input, expected):
assert eval(test_input) == expected

2.第二种方法,使用 pytest hook 批量加参数化
#conftest.py
def pytest_generate_tests(metafunc):
“”"
使用 hook 给用例加加上参数
metafunc.cls.params 对应类中的 params 参数

“”"
try:
if metafunc.cls.params and metafunc.function.name in metafunc.cls.params: ## 对应 TestClass params
funcarglist = metafunc.cls.params[metafunc.function.name]
argnames = list(funcarglist[0])
metafunc.parametrize(argnames, [[funcargs[name] for name in argnames] for funcargs in funcarglist])
except AttributeError:
pass

#test_demo.py
class TestClass:
“”"
:params 对应 hook 中 metafunc.cls.params
“”"
#params = Parameterize(‘TestClass.yaml’).getdata()

params = {
‘test_a’: [{‘a’: 1, ‘b’: 2}, {‘a’: 1, ‘b’: 2}],
‘test_b’: [{‘a’: 1, ‘b’: 2}, {‘a’: 1, ‘b’: 2}],
}
def test_a(self, a, b):
assert a == b
def test_b(self, a, b):
assert a == b

Pytest 用例依赖关系
使用 pytest-dependency 库可以创造依赖关系
当上层用例没通过,后续依赖关系用例将直接跳过,可以跨 Class 类筛选
如果需要跨.py 文件运行 需要将 site-packages/pytest_dependency.py 文件的

class DependencyManager(object):
“”“Dependency manager, stores the results of tests.
“””

ScopeCls = {‘module’:pytest.Module, ‘session’:pytest.Session}

@classmethod
def getManager(cls, item, scope=‘session’): # 这里修改成 session

如果

pip install pytest-dependency

class TestExample(object):

@pytest.mark.dependency()
def test_a(self):
assert False

@pytest.mark.dependency()
def test_b(self):
assert False

@pytest.mark.dependency(depends=[“TestExample::test_a”])
def test_c(self):
#TestExample::test_a 没通过则不执行该条用例
#可以跨 Class 筛选
print(“Hello I am in test_c”)

@pytest.mark.dependency(depends=[“TestExample::test_a”,“TestExample::test_b”])
def test_d(self):
print(“Hello I am in test_d”)

pytest -v test_demo.py
2 failed

test_1.py:6 TestExample.test_a
test_1.py:10 TestExample.test_b
2 skipped
Pytest 自定义标记,执行用例筛选作用
1.使用 @pytest.mark 模块给类或者函数加上标记,用于执行用例时进行筛选
@pytest.mark.webtest
def test_webtest():
pass

@pytest.mark.apitest
class TestExample(object):
def test_a(self):
pass

@pytest.mark.httptest
def test_b(self):
pass

仅执行标记 webtest 的用例

pytest -v -m webtest

Results (0.03s):
1 passed
2 deselected

执行标记多条用例

pytest -v -m “webtest or apitest”

Results (0.05s):
3 passed

仅不执行标记 webtest 的用例

pytest -v -m “not webtest”

Results (0.04s):
2 passed
1 deselected

不执行标记多条用例

pytest -v -m “not webtest and not apitest”

Results (0.02s):
3 deselected

2.根据 test 节点选择用例
pytest -v Test_example.py::TestClass::test_a
pytest -v Test_example.py::TestClass
pytest -v Test_example.py Test_example2.py

3.使用 pytest hook 批量标记用例
#conftet.py

def pytest_collection_modifyitems(items):
“”"
获取每个函数名字,当用例中含有该字符则打上标记
“”"
for item in items:
if “http” in item.nodeid:
item.add_marker(pytest.mark.http)
elif “api” in item.nodeid:
item.add_marker(pytest.mark.api)

class TestExample(object):
def test_api_1(self):
pass

def test_api_2(self):
pass

def test_http_1(self):
pass

def test_http_2(self):
pass
def test_demo(self):
pass

仅执行标记 api 的用例

pytest -v -m api
Results (0.03s):
2 passed
3 deselected
可以看到使用批量标记之后,测试用例中只执行了带有 api 的方法

用例错误处理截图,app 日志等
1.第一种使用 python 函数装饰器方法

def monitorapp(function):
“”"
用例装饰器,截图,日志,是否跳过等
获取系统log,Android logcat、ios 使用syslog
“”"

@wraps(function)
def wrapper(self, *args, **kwargs):
try:
allure.dynamic.description(‘用例开始时间:{}’.format(datetime.datetime.now()))
function(self, *args, **kwargs)
self.Action.driver.get_log(‘logcat’)
except Exception as E:
f = self.Action.driver.get_screenshot_as_png()
allure.attach(f, ‘失败截图’, allure.attachment_type.PNG)
logcat = self.Action.driver.get_log(‘logcat’)
c = ‘\n’.join([i[‘message’] for i in logcat])
allure.attach(c, ‘APPlog’, allure.attachment_type.TEXT)
raise E
finally:
if self.Action.get_app_pid() != self.Action.Apppid:
raise Exception(‘设备进程 ID 变化,可能发生崩溃’)
return wrapper

2.第二种使用 pytest hook 方法 (与方法一选一)

@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
Action = DriverClient().Action
outcome = yield
rep = outcome.get_result()
if rep.when == “call” and rep.failed:
f = Action.driver.get_screenshot_as_png()
allure.attach(f, ‘失败截图’, allure.attachment_type.PNG)
logcat = Action.driver.get_log(‘logcat’)
c = ‘\n’.join([i[‘message’] for i in logcat])
allure.attach(c, ‘APPlog’, allure.attachment_type.TEXT)
if Action.get_app_pid() != Action.apppid:
raise Exception(‘设备进程 ID 变化,可能发生崩溃’)

Pytest 另一些 hook 的使用方法
1.自定义 Pytest 参数

pytest -s -all

#content of conftest.py
def pytest_addoption(parser):
“”"
自定义参数
“”"
parser.addoption(“–all”, action=“store_true”,default=“type1”,help=“run all combinations”)

def pytest_generate_tests(metafunc):
if ‘param’ in metafunc.fixturenames:
if metafunc.config.option.all: # 这里能获取到自定义参数
paramlist = [1,2,3]
else:
paramlist = [1,2,4]
metafunc.parametrize(“param”,paramlist) # 给用例加参数化

#怎么在测试用例中获取自定义参数呢
#content of conftest.py
def pytest_addoption(parser):
“”"
自定义参数
“”"
parser.addoption(“–cmdopt”, action=“store_true”,default=“type1”,help=“run all combinations”)

@pytest.fixture
def cmdopt(request):
return request.config.getoption(“–cmdopt”)

#test_sample.py 测试用例中使用
def test_sample(cmdopt):
if cmdopt == “type1”:
print(“first”)
elif cmdopt == “type2”:
print(“second”)
assert 1

pytest -q --cmdopt=type2
second
.
1 passed in 0.09 seconds

2.Pytest 过滤测试目录
#过滤 pytest 需要执行的文件夹或者文件名字
def pytest_ignore_collect(path,config):
if ‘logcat’ in path.dirname:
return True #返回 True 则该文件不执行

Pytest 一些常用方法
Pytest 用例优先级(比如优先登录什么的)

pip install pytest-ordering

@pytest.mark.run(order=1)
class TestExample:
def test_a(self):

Pytest 用例失败重试
#原始方法
pytet -s test_demo.py
pytet -s --lf test_demo.py #第二次执行时,只会执行失败的用例
pytet -s --ll test_demo.py #第二次执行时,会执行所有用例,但会优先执行失败用例
#使用第三方插件
pip install pytest-rerunfailures #使用插件
pytest --reruns 2 # 失败case重试两次

Pytest 其他常用参数
pytest --maxfail=10 #失败超过10次则停止运行
pytest -x test_demo.py #出现失败则停止

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

【自动化测试】Pytest+Appium+Allure 做 UI 自动化的那些事,软件测试,pytest,appium,ui,功能测试,软件测试,自动化测试,程序人生

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你! 

【自动化测试】Pytest+Appium+Allure 做 UI 自动化的那些事,软件测试,pytest,appium,ui,功能测试,软件测试,自动化测试,程序人生文章来源地址https://www.toymoban.com/news/detail-824268.html

到了这里,关于【自动化测试】Pytest+Appium+Allure 做 UI 自动化的那些事的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Web UI 自动化测试框架(Pytest+Selenium+Allure+Loguru)

    本框架主要是基于 Python + pytest + selenium + Allure + loguru + 邮件通知/企业微信通知/钉钉通知 实现的WEB UI自动化框架。 基于PageObject设计模式结合,该平台可实现测试用例的自动化执行及自动化测试报告的生成同时包括自动化测试执行时,用例失败的截图操作。 使用webdriver_manag

    2024年02月04日
    浏览(119)
  • 【UI自动化测试技术】自动化测试研究:Python+Selenium+Pytest+Allure,详解UI自动化测试,学习模拟鼠标+模拟键盘进行相关操作(精)(四)

    1、了解元素交互的常用方法 2、学习如何对多选元素进行操作 3、 学习模拟鼠标进行相关操作 ( 本节目标 ) 4、 学习模拟键盘进行相关操作 ( 本节目标 ) 用于向 Web 浏览器提供虚拟化设备输入操作的低级接口.除了刚刚讲过的Web元素交互之外, Actions 接口 还提供了对指定输

    2024年03月24日
    浏览(84)
  • python+playwright+pytest+allure+pom+yaml实现UI自动化测试

    https://gitee.com/giteetangll/playwright-demo Auth:登录认证保存后的认证信息 BasePage:封装playwright的基础方法 BuildInLibrary:环境变量存放文件夹,可进行用例参数关联 Common:存放公共方法抽离文件夹 Config:配置文件存放文件夹 Logs:存放断言失败的记录 Pages:存放页面对象文件 Test

    2024年02月11日
    浏览(76)
  • 使用 uiautomator2+pytest+allure 进行 Android 的 UI 自动化测试

    目录 前言: 介绍 pytest uiautomator2 allure 环境搭建 pytest uiautomator2 allure pytest 插件 实例 初始化 driver fixture 机制 数据共享 测试类 参数化 指定顺序 运行指定级别 重试 hook 函数 断言 运行 运行某个文件夹下的用例 运行某个方法 运行某个类 运行 P0 级 运行非 P0 级 main 方式 报告

    2024年02月16日
    浏览(66)
  • Web UI 自动化测试框架(Pytest+Selenium+Allure/Pytest-html+Loguru)

    本框架主要是基于 Python + pytest + selenium + Allure + loguru + 邮件通知/企业微信通知/钉钉通知 实现的WEB UI自动化框架。 基于PageObject设计模式结合,该平台可实现测试用例的自动化执行及自动化测试报告的生成同时包括自动化测试执行时,用例失败的截图操作。 使用webdriver_manag

    2024年02月12日
    浏览(99)
  • 自动化测试笔记(selenium+pytest+Allure)

    自动化测试:所有采用程序或代码来替代或辅助人工测试的行为称为自动化测试。 自动化测试好处:提升工作效率 主要应用环节:回归测试、兼容性测试、冒烟测试 适合自动化测试的项目特点: 1、项目需求稳定 2、项目周期较长 3、脚本可以重复使用 selenium:是由thoughtwo

    2024年02月15日
    浏览(64)
  • Pytest自动化测试框架之Allure报告

    Allure Framework是一种灵活的、轻量级、多语言测试报告工具。 不仅可以以简洁的网络报告形式非常简洁地显示已测试的内容, 而且还允许参与开发过程的每个人从日常执行中提取最大程度的有用信息和测试。 从开发/测试的角度来看: Allure报告可以快速查看到缺陷点,可以将

    2024年02月06日
    浏览(85)
  • 【Pytest实战】Pytest+Allure+Jenkins自动化测试框架搭建

    😄作者简介: 小曾同学.com,一个致力于测试开发的博主⛽️,主要职责:测试开发、CI/CD 如果文章知识点有错误的地方,还请大家指正,让我们一起学习,一起进步。😊 座右铭:不想当开发的测试,不是一个好测试✌️。 如果感觉博主的文章还不错的话,还请点赞、收藏哦

    2024年02月15日
    浏览(60)
  • 接口自动化测试实战之pytest框架+allure讲解

    本文章主要会讲解Python中pytest框架的讲解,介绍什么是pytest、为何要测试、为何使用以及参考和扩展等等,话不多说,咱们直接进入主题哟。 pytest是一款单元测试框架,在编程过程中,单元主要指的是代码中最小的组成部分,例如函数或类,在面向对象中,最小的单元就是类

    2024年02月05日
    浏览(77)
  • 接口自动化测试:Python+Pytest+Requests+Allure

    本项目实现了对Daily Cost的接口测试: Python+Requests 发送和处理HTTP协议的请求接口 Pytest 作为测试执行器 YAML 管理测试数据 Allure 来生成测试报告。 本项目是参考了pytestDemo做了自己的实现。 项目结构 api : 接口封装层,如封装HTTP接口为Python接口 commom : 从文件中读取数据等各种

    2024年02月09日
    浏览(70)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包