Playwright + Pytest 实现 Web UI 自动化测试

已转战 Playwright node.js 版,不继续使用 Py3 版了
相关示例仓库:https://github.com/tomoyachen/e2e-playwright-scaffold

文章目录

  • 前言
  • 项目地址
  • 分层
  • 其他
  • 新功能
    • 视频录制
    • allure 报告
  • 已知问题

前言

平时工作一直用的 Cypress,但是 Cypress 真的太慢了,就想看看有什么替代品。Selenium 我一直不太喜欢,正好看到微软出的 Playwright 好像蛮有意思的。虽然 Playwright 的 JS 版本 的 Star 是 Python 版本的十倍之多,不过我个人还是更喜欢 Python 和 Pytest,就还是用 Python 版的 Playwright 搭配 Pytest 来食用了。(其实是 js 不太熟悉 XD)

主流的 UI 自动化 框架对比可以参考这篇文章 [传送门]

本项目风格和我之前写的 api-test比较相似,越小越简单越好。

项目地址

Github:https://github.com/tomoyachen/playwright-test

本项目参考了虫师 & Yusuke Iwaki 的项目

分层

定位符、页面操作、业务逻辑三层:合并成了 page 类
测试用例层:test 类(基于 pytest)
数据层:yaml 文件 (config 数据 与 fixtures 数据)
结果层:HTML 报告(基于 pytest-html,感兴趣可以改成 allure),Log 日志(暂无)

Playwright + Pytest 实现 Web UI 自动化测试_第1张图片
* 图来自 陈晓伍 的 《Python Web自动化测试设计与实现》

test 类
page @pytest.fixture 来自 pytest-playwright
env 是自定义的 @pytest.fixture,用来读取当前环境的配置信息
Playwright + Pytest 实现 Web UI 自动化测试_第2张图片
使用内置的 browser @pytest.fixture 来 生成一个 page @pytest.fixture
提升作用域,以达到共用同一浏览器的效果
Playwright + Pytest 实现 Web UI 自动化测试_第3张图片

page 类
想了好几种方式,如何来使用page对象。本来想试试继承,但好像不行。
最终还是作为类属性来使用了。
Playwright + Pytest 实现 Web UI 自动化测试_第4张图片

config 数据,管理 base_url 等通用信息
fixtures 数据,就是测试用例的测试数据了,只是我习惯 Cypress 的命名方式了。

fixtures 我定义了2种获取方式。
一种是test 类中获取当前要用的测试对象的 yaml 文件

# test 类
@pytest.fixture()
def fixtures(self):
    yield Tools.get_fixtures("baidu_search")


# ---- 用法 -----
# test 类
fixtures['kerwords']

一种是放在conftest.py中,作为@pytest.fixture 来用

# conftest.py
@pytest.fixture(scope="class")
def fixtures():
    def _fixtures(filename: str):
        from common.tools import Tools
        return Tools.get_fixtures(filename)

    yield _fixtures


# ---- 用法 -----
# test 类
fixtures('baidu_search')['kerwords']

Playwright + Pytest 实现 Web UI 自动化测试_第5张图片

其他

虚拟环境使用的 poetry
Playwright + Pytest 实现 Web UI 自动化测试_第6张图片

conftest.py 文件中,pytest 钩子和 pytest-html 钩子都有详尽的注解
Playwright + Pytest 实现 Web UI 自动化测试_第7张图片

报告 用的 pytest-html,我还蛮喜欢的。
Playwright + Pytest 实现 Web UI 自动化测试_第8张图片

新功能

视频录制

Playwright 内置的视频录制,传入一个 路径就可以了。
还学到了一个新钩子

@pytest.fixture(scope="session")
def browser_context_args(browser_context_args, tmpdir_factory: pytest.TempdirFactory):
    return {
        **browser_context_args,
        "record_video_dir": os.path.join(OUTPUT_DIR, "videos")
        }

allure 报告

在 feature/allure 分支

有了截图和视频,再看 pytest-html 就有点磕碜了。所以就接了 allure。
目前是pytest-html 和 allure部分都保留了。

已知问题

  1. config 数据 和 fixtures 数据如何整合,目前还在思考

  2. Tools.get_config()、Tools.get_fixtures() 等依赖 env 信息的操作,只能放在__init__ 或 实例方法中。因为引入文件时会自动执行文件。此时还没有 env 信息,所以会报错。

# 错误
class BaiduSearchPage:

        host = Tools.get_config("base_url")
        
    def __init__(self, page: Page):
        self.page = page

# 正确
class BaiduSearchPage:

    def __init__(self, page: Page):
        self.page = page
        self.host = Tools.get_config("base_url")

你可能感兴趣的:(自动化测试,Playwright,Pytest,Playwright,自动化测试,Pytest)