南飓风 发表于 2024-7-7 20:09:38

【Playwright+Python】系列教程(四)Pytest 插件在Playwright中的使用

一、命令行使用详解

使用Pytest插件在Playwright 中来编写端到端的测试。
1、命令行执行测试

pytest --browser webkit --headed
2、使用 pytest.ini 文件配置

内容如下:

# Run firefox with UI
addopts = --headed --browser firefox结果:
运行测试类,可以直接可以按照配置执行
命令行执行,无需指定参数输入pytest即可
3、CLI 参数详解

前提:未使用pytest.ini配置
3.1、在带头模式下运行测试(默认:无头)

pytest--headed
3.2、在差异的浏览器中运行测试

在差异的浏览器 chromium、firefox 或 webkit 中运行测试。可以多次指定(默认:chromium)
pytest --browser chromium --headed
3.3、使用的浏览器通道

pytest --browser-channel chrome --headed
3.4、将 Playwright 使用速度减慢指定的毫秒数

将 Playwright 使用速度减慢指定的毫秒数。很有用,以便您可以检察正在发生的事情(默认值:0)。
pytest --browser chromium --headed --slowmo 5000(5秒)
3.5、记录测试结果

是否为每个测试记录跟踪。on、off或retain-on-failure(默认:off)
pytest --browser chromium --headed --tracing on
3.6、视频录制

是否为每个测试录制视频。on、off或retain-on-failure(默认:off)。
pytest --browser chromium --headed --video on
结果默认保存在test-results目录下,和测试结果文件一样
https://cdn.nlark.com/yuque/0/2024/png/12957787/1720249269701-fabbdb97-df5f-4f16-b56c-6b9a99374efc.png#averageHue=%2327313b&clientId=ud88cfec1-f3d0-4&from=paste&height=113&id=ueddfba94&originHeight=141&originWidth=580&originalType=binary&ratio=1.25&rotation=0&showTitle=false&size=8672&status=done&style=none&taskId=ued662a78-268b-4cd8-a28b-196a02cff45&title=&width=464
3.7、截图

是否在每次测试后自动捕获屏幕截图。on、off或only-on-failure(默认:off)
pytest --browser chromium --headed --screenshot on
结果:
https://cdn.nlark.com/yuque/0/2024/png/12957787/1720250806748-fb1f3a02-abb1-4582-9dbc-ef5cd7eb3e3c.png#averageHue=%232f3c4c&clientId=ud88cfec1-f3d0-4&from=paste&height=437&id=u0c078bee&originHeight=546&originWidth=1645&originalType=binary&ratio=1.25&rotation=0&showTitle=false&size=758951&status=done&style=none&taskId=u7df25147-e636-4830-b52e-a47495b1f8a&title=&width=1316
在失败时截取整页截图(长截图)默认环境下,仅捕获视口。必要启用 --screenshot(默认off).
pytest --browser chromium --headed --screenshot on --full-page-screenshot
结果:
https://cdn.nlark.com/yuque/0/2024/png/12957787/1720252773446-a46de01c-be20-4bbe-83fe-8a48f32a15b7.png#averageHue=%23222b34&clientId=ud88cfec1-f3d0-4&from=paste&height=483&id=u5aaf996b&originHeight=604&originWidth=1704&originalType=binary&ratio=1.25&rotation=0&showTitle=false&size=121087&status=done&style=none&taskId=ubbb07d98-63d3-4ecb-bddc-1f1b6f007d9&title=&width=1363.2
二、Fixtures夹具

因为我们使用fixture更加机动,具体有独立的命名,然后呢,还可以按模块化的方式实现,每个fixture都可以互相调用,并且呢范围可以跨函数、类、模块、另有整个session范围
那fixture怎么使用呢?
1、fixture初步使用

我们直接在函数前定义就可以
@pytest.fixture()
但是这块是有一些注意事项:要定义的函数最好不要以test开头,和用例分开,并且fixture定义的函数是有返回值的,下边的测试用例可以调用fixture的返回值
我们看下实战
@pytest.fixture()
def set():
    print("----在用例前执行----")

def test_01(set):
    print('用例1')这里我们定义了一个测试夹具,然后再test_01中使用了测试夹具的参数,那么执行结果应该是会先调用这个夹具函数,然后再执行用例函数
看下执行结果:
https://cdn.nlark.com/yuque/0/2024/png/12957787/1720255089840-b40da2da-8e57-449e-abfa-ad7669004073.png#averageHue=%232e2e2d&clientId=ud88cfec1-f3d0-4&from=paste&id=uaaf88d37&originHeight=84&originWidth=531&originalType=url&ratio=1.25&rotation=0&showTitle=false&status=done&style=none&taskId=uc1e4ff2d-c97a-439b-a9f0-568d8a15312&title=
2、fixture进一步使用

我们另有一种使用fixture的方式
@pytest.mark.usefixtures(fixture_name)
这样使用,我们如果用在类上呢,这个类下的所有用例都会调用这个fixture
直接看实战:
@pytest.fixture()
def set():
    print("----在用例前执行----")


@pytest.mark.usefixtures('set')
class Test_Demo():

    def test_01(self):
      print('用例1')

    def test_02(self):
      print('用例2')看下结果:
https://cdn.nlark.com/yuque/0/2024/png/12957787/1720255089944-87e694be-2464-41c6-9388-14da25082a20.png#averageHue=%232d2d2d&clientId=ud88cfec1-f3d0-4&from=paste&id=u7767a9a1&originHeight=180&originWidth=695&originalType=url&ratio=1.25&rotation=0&showTitle=false&status=done&style=none&taskId=u640a9059-0b17-4e63-a509-65670ee0ea7&title=
每个用例前都执行了测试夹具
那么另有一种只作用在用例上呢
看实战:
@pytest.fixture()
def set():
    print("----在用例前执行----")


class Test_Demo():
    @pytest.mark.usefixtures('set')
    def test_01(self):
      print('用例1')

    def test_02(self):
      print('用例2')执行结果:
https://cdn.nlark.com/yuque/0/2024/png/12957787/1720255089883-94630669-9590-4e00-9a42-323aea3bd834.png#averageHue=%232d2d2c&clientId=ud88cfec1-f3d0-4&from=paste&id=u922255c7&originHeight=156&originWidth=694&originalType=url&ratio=1.25&rotation=0&showTitle=false&status=done&style=none&taskId=u1f5de85f-d763-489f-b2fb-45e4a8200e8&title=
只有用例1前执行了测试夹具
3、fixture作用域

在我们之前用了setupClass和tearDownclass,指的是在每个类前会执行前置,在执行后置
那我们在fixture中,也可以这样使用
并且有好几个:

[*]unction:默认作用域,每个测试用例都运行一次
[*]class:每个测试类只执行一次
[*]module:每个模块只执行一次
[*]package:每个python包只执行一次
[*]session:整个会话只执行一次,即运行项目时整个过程只执行一次
如果设置多个的话,会有一个优先级:session > package > module > class > function
那我们以其中的作用域为class做一个实战场景:
@pytest.fixture(scope='class')
def set():
    print("----在用例前执行----")

class Test_Demo1:
    def test_01(self,set):
      print('用例1执行')
    def test_02(self,set):
      print('用例2执行')

class Test_Demo2():
    def test_01(self,set):
      print('第二个类中的用例1')我们在夹具函数上定义每个类只执行一次
现在猜下执行结果是什么,是不是夹具——>Test_Demo1,夹具——>Test_Demo2
直接看结果:
https://cdn.nlark.com/yuque/0/2024/png/12957787/1720255089923-3038c1e9-4c4f-4c05-869d-96c9fcd5010e.png#averageHue=%232e2d2d&clientId=ud88cfec1-f3d0-4&from=paste&id=u7b18512d&originHeight=248&originWidth=743&originalType=url&ratio=1.25&rotation=0&showTitle=false&status=done&style=none&taskId=u8f3631a1-2ad8-44ff-9208-b38c8c186c3&title=
4、自定义夹具的使用

对于browser和context夹具,请使用以下夹具来定义自定义启动选项。

[*]browser_type_launch_args:覆盖 browser_type.launch() 的启动参数。它应该返回一个 Dict。
[*]browser_context_args:覆盖 browser.new_context() 的选项。它应该返回一个 Dict。
示例代码:
import pytest

@pytest.mark.browser_context_args(timezone_id="Europe/Berlin", locale="en-GB")
def test_browser_context_args(page):
    assert page.evaluate("window.navigator.userAgent") == "Europe/Berlin"
    assert page.evaluate("window.navigator.languages") == ["de-DE"]三、配置测试

1、并行测试

# install dependency
pip install pytest-xdist
# use the --numprocesses flag
pytest --numprocesses auto根据测试的硬件和性质,可以将 numprocesses 设置为从 2 到计算机上的 CPU 数量之间的任意值。如果设置得太高,您可能会注意到不测行为。
2、跳过测试

@pytest.mark.skip("firefox")
def test_visit_example(page):
    page.goto("https://www.alipansou.com/")3、配置 base-url执行

使用 base-url 参数启动 Pytest。pytest-base-url 插件用于允许您从配置、CLI arg 或作为固定装置设置根本 url 的插件。
pytest --base-url (http://localhost:8080)
def test_visit_example(page):
    page.goto("/admin")
    # -> Will result in http://localhost:8080/admin4、忽略 HTTPS 错误

conftest.py
import pytest

@pytest.fixture(scope="session")
def browser_context_args(browser_context_args):
    return {
      **browser_context_args,
      "ignore_https_errors": True
    }5、使用自定义视口巨细

conftest.py
import pytest

@pytest.fixture(scope="session")
def browser_context_args(browser_context_args):
    return {
      **browser_context_args,
      "viewport": {
            "width": 1920,
            "height": 1080,
      }
    }6、设备仿真

conftest.py
import pytest

@pytest.fixture(scope="session")
def browser_context_args(browser_context_args, playwright):
    iphone_11 = playwright.devices['iPhone 11 Pro']
    return {
      **browser_context_args,
      **iphone_11,
    }使用pytest --device="iPhone 11 Pro"--headed执行脚本
结果:
https://cdn.nlark.com/yuque/0/2024/png/12957787/1720260503787-cb4e8909-b513-49a7-9a2d-091dc4bf516f.png#averageHue=%23e9d8b3&clientId=ud88cfec1-f3d0-4&from=paste&height=760&id=u91cfc941&originHeight=950&originWidth=520&originalType=binary&ratio=1.25&rotation=0&showTitle=false&size=392480&status=done&style=none&taskId=u37808ea1-201a-4160-80d3-8db58dd26fe&title=&width=416
7、与 unittest.TestCase的使用

与 unittest.TestCase。这有一个限制,即只能指定一个浏览器,并且在指定多个浏览器时不会生成多个浏览器的矩阵。
示例代码:
# -*- coding: utf-8 -*-
# @Time    : 2024/07/06 18:10
# @Author: longrong.lang
# @FileName: test_unittest.py
# @Software: PyCharm
# @Cnblogs :https://www.cnblogs.com/longronglang
# @Motto:你只管努力,剩下的交给天意.
import pytest
import unittest

from playwright.sync_api import Page


class MyTest(unittest.TestCase):
    @pytest.fixture(autouse=True)
    def setup(self, page: Page):
      self.page = page

    def test_foobar(self):
      self.page.goto("https://microsoft.com")
      assert self.page.evaluate("1 + 1") == 28、运行调试

在测试代码中使用 breakpoint() 语句暂停执行并获取 pdb REPL。
def test_bing_is_working(page):
    page.goto("https://bing.com")
    breakpoint()
    # ...如何进行调试:

[*]启动调试:当步伐在breakpoint()处暂停时,它会自动进入pdb调试环境。
[*]检察状态:在pdb中,你可以使用命令如l(list)来检察当前代码周围的行,p 变量名来打印变量的值。
[*]继续执行:要继续执行步伐直到下一个断点或步伐结束,你可以输入c(continue)命令。
[*]如果你只是想在特定点暂停代码执行,但不盼望进入pdb环境,可以思量使用其他方法,比如打印语句(print())或条件断点。
结果:
https://cdn.nlark.com/yuque/0/2024/png/12957787/1720261344451-5a211599-5cea-469c-b4f6-02dbab1a7d33.png#averageHue=%23212933&clientId=ud88cfec1-f3d0-4&from=paste&height=446&id=u8a7d45d7&originHeight=557&originWidth=1855&originalType=binary&ratio=1.25&rotation=0&showTitle=false&size=88090&status=done&style=none&taskId=ubb6918f2-f941-4364-a05d-ced4770f5f4&title=&width=1484
四、关于自动等候的说明

Playwright能自动等页面准备好,但偶然你可能想让它等一会儿。别用time.sleep(5)来等,因为它会让步伐完全停下来。改用page.wait_for_timeout(5000)吧,这样步伐在等候时还能做其他事,更流畅。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【Playwright+Python】系列教程(四)Pytest 插件在Playwright中的使用