playwright+pytest+BDD+pom书写自动化用例


BDD行为驱动开发是从用户视角描述我需要哪些特性,我们的验证场景是什么,保证文档与代码的统一、设计与测试的统一、开发出更符合需求的测试用例

BDD分为fixture(特性) scenario(场景) given(前置条件) when(用户操作) then(预期结果)

fixture(特性):是向最终用户或其他涉众提供的一项功能,以支持他们实现业务目标所需的功能。

scenario(场景):用户在访问应用时,用户和应用之间有多种条件需要满足,每一种不同的情况都对应不同的场景,简短的声明性句子来总结这个例子的特别之处

 given(前置条件):在测试操作前有哪些先决条件?应该定义出所有的但不场景该场景要求范围的先决条件,given主要为后面的测试主体服务

when (用户操作):用户做了哪个操作,输入了哪些数据

then (预期结果):回应行操作的预期结果,用户做了操作后会触发系统产生什么样的变化、输出的数据是什么

那么我们怎么将playwright pytest BDD结合起来书写自动化用例

1、下载插件pytest-bdd

pip insall  pytest-bdd

2、创建.feature文件,每个feature文件中仅有一个Feature描述

@hotlink @shop
  Feature: As a new user,
    I want to be order a t-shirt,
    In order to buy a t-shirt, I must register my account
#background每个场景相同的前置部分
    Background:
      Given Sean 打开网站首页

    Scenario: 我登录购物网站后按照购物流程进行下单
      Given Sean 登录xx购物网站
      And Sean 打开了T-shirt 分类
      When Sean 选了一件T-shirt加入购物车
      And Sean 完成了下单
      When Sean 查看个人资料订单页面
      Then Sean 订单页面有T-shirt订单

3、将feature文件中的given(前置条件) when(用户操作) then(预期结果)转化为POM中封装的页面元素操作,(pom封装如下https://www.cnblogs.com/mumu-lin/p/15585133.html)

也可以转换未封装的元素操作

import allure
from pytest_bdd import (
    given,
    scenario,
    then,
    when
)
# 需要从pytest_bdd中导入given、when、then等
from page_objects.registation.registration_object import RegistrationPage from page_objects.shop.shop_object import ShopPage from utils.bdd_helper import BddHelper feature_path = BddHelper.get_feature_path("shop/shop_order_t_shirt.feature")
@scenario(feature_path, '我登录购物网站后按照购物流程进行下单')
def test_shop_order_t_shirt():
"""我按照购物流程进行下单, 新用户注册等操作."""
pass
#使用scenario decorator修饰的函数的行为类似于正常的测试函数,它们将在所有场景步骤之后执行。但是更建议将逻辑仅包含在given、when then中

@when('Sean 完成了下单')
def finish_order_after_registration(page):
    """Sean 完成了下单."""
    ShopPage(page).finish_order_after_registration()


@given('Sean 打开了T-shirt 分类')
def open_t_shirt_category(page):
    """Sean 打开了T-shirt 分类."""
    ShopPage(page).open_t_shirt_category()


@given('Sean 打开网站首页')
def open_site(page):
    """Sean 打开网站首页."""
    ShopPage(page).open_site()


@when('Sean 查看个人资料订单页面')
def open_profile_order_page(page):
    """Sean 查看个人资料订单页面."""
    ShopPage(page).open_profile_order_page()

4、执行测试用例

使用@scenario装饰器的函数其实就是一个测试用例,所以我们只需要运行含有@scenario即可运行我们的测试用例。注意:pytest中检索测试用例的规则是 文件名、测试用例、类名默认要以Test开头。

如果不想按照每个feature文件都进行注册的话,可以按照目录进行注册。然后使用pytest 执行当前文件即可运行对应的features

#方式一:获取当前features目录下的所有feature
scenarios(feature_path)
#方式二:获取某个目录或某个features,这些路径可以是要素文件或要素文件夹。
scenarios(feature_path, 'other_features/some.feature', 'some_other_features')
#方式三:仅绑定有个场景
@scenario(feature_path, '进入首页后, 查看附件数量')
def test_shop_attachment_count():
    pass
if __name__ == '__main__':
pytest.main(['-v', 'D:\\jiaoben\\ui-test-regression-main\\tests\step_definition\\shop\\test_bdd_shop.py'])

从个人感觉上来说,BDD用例的given(前置条件) when(用户操作) then(预期结果)如何封装和存放,维护起来更方便,这个是需要慢慢摸索和调整的,避免在不同的文件夹下封装了多个相同的step

参考资料:

https://pypi.org/project/pytest-bdd/