果型

pypom-form的Python项目详细描述


pypom_形式

https://travis-ci.org/tierratelematics/pypom_form.svg?分支=开发https://requires.io/github/tierratelematics/pypom_form/requirements.svg?分公司=开发https://readthedocs.org/projects/pypom_form/badge/?version=latesthttps://codecov.io/gh/tierratelematics/pypom_form/branch/development/graph/badge.svghttps://api.codacy.com/project/badge/grade/0698c7aa2e164ee996518737aad7d6f4python 3

pypom_form 是一个基于pypom的包,它为页面对象提供基于声明性模式的表单交互。

pypom_表单旨在改善用户界面、e2e测试自动化的开发人员体验 由于声明性模式模型,必须与包含表单的页面对象进行交互。

如果您以前使用过类似于sqlalchemy、灵巧性( plone )或旧原型(plone)的框架 您应该已经熟悉了这个模式:您只需使用模式定义一个模型,就可以 与保存或检索数据的模型交互。 当模型是页面时,pypom_表单也会发生同样的情况。

pypom_表单内部基于:

它是如何工作的?

你只要用皮波姆的形式:

  • 实例化其类继承自pypom_form提供的baseformpage的页对象实例
  • 声明模式模型

你会为我准备好的输入您的页面,用您的表单驱动浏览器,只需键入:

page.title = 'the title'
page.title

假设表单中有一个 标题 字段。

主要概念

您可以将 模式 概念看作一组命名属性( 字段 )。 可作为常规属性在 型号上使用。

模式上的每个 字段都用 类型定义(例如:string、int、float、datetime、date、bool等) 定义应用程序域级别上给定字段的数据类型。

字段具有对必需定义的或根据字段默认分配的小部件的引用。 类型。 pypom_表单提供的小部件的内部实现基于pypom的区域,因此 小部件区域 包装和管理包含小部件的dom。

基本上,小部件将数据从应用程序域转换到浏览器域,反之亦然 通过序列化和反序列化。

当您将 true 设置为布尔值时,您可能会认为小部件是如何驱动浏览器的 属性或获取窗体上的实际值:基本上取决于小部件实现。例如 您可能有一个复选框、是/否单选按钮或组合选择等,如果您想设置 true 驱动浏览器更改的方式。日期窗口小部件等也一样。

您可能还需要处理复杂的小部件,例如:

  • 引用小部件(例如:带有搜索、筛选等的分层内容导航)
  • 高级多选小部件
  • 字典小部件(键值映射)
  • ET

例如,假设您正在处理一个假装高级的单选选项字段,则可以 访问小部件区域提供的高级逻辑

page.getWidgetRegion('state').filter('virg').select('Virginia')

或访问验证错误消息、标签文本等。

为什么使用pypom格式

显然,您可以使用普通的selenium/splinter或传统的 普通页面对象模型模式,但使用pypom_表单,您有以下优点:

  • 编写一次可重用的方法,在测试cms框架时非常有用
  • 页面和小部件逻辑的关注点分离
  • 声明性模式方法
  • 可重用的模式和小部件,无代码重复
  • 可以使用pypom_表单将小部件与其他项目共享
  • 基于自动生成的getter和setter的简单api
  • 通过基于pypom的区域窗口小部件与高级窗口小部件逻辑交互
  • 小部件隔离。所有元素查询都针对根区域运行,而不是针对页根
  • 更简单的输入元素选择器,它们与区域小部件根相对
  • 模式表单改进了文档页面包含表单的方式(属性名称、类型、小部件, 允许的词汇等)。您所需要知道的是在模式级别定义整个图片 一目了然
  • 如果要测试基于colander/deform的应用程序(可能 您正在测试一个pylons,它是基于python的web应用程序
  • 也支持页面和模式继承
  • 使用相同的数据模型、相同或不同的选择器或小部件轻松测试多皮肤web应用程序 类型。因此,可以在定义所有页面对象类时重用它们,它只更改模式 窗口小部件选择器和窗口小部件类型
  • 小部件区域是pypom区域,因此如果您想访问小部件容器中的内部元素 生成的选择器将更简单,因为它们是相对于小部件区域根的。 也支持子/嵌套区域或动态区域
  • 使用应用程序域数据而不是浏览器域数据与模型交互。更多的是 简单易管理的python数据(例如ET 12.9代替"12.9",日期时间相同 值,如 datetime.now()
  • 支持链接调用,如page.set('title','thetitle')
  • 通过 页支持根据模式级别定义的顺序进行批量字段更新。update(**values)
  • 不要重新发明轮子。它基于现有的和广泛使用的组件,如普通的pypom或 colander库
  • 同样的用户体验,如果您已经熟悉模式声明性模型,比如 sqlalchemy 原型 (plone)、 灵巧性 (plone)或形成类似于 变形的库
  • 由于小部件的实现是基于区域的,所以您只需执行 page.name="the name" 在页面加载时而不是在设置值之前调用等待方法: 小部件可以在获取或设置数据之前等待小部件加载
  • 页面对象类更简单,代码更少,更标准,即使不同的测试工程师 实现页格式逻辑:有一个结构模式

另外:

  • 100%测试覆盖率
  • python 2和3都支持
  • 支持拆分驱动程序(尚未提供Selenium支持)
  • pytest设置就绪,这要归功于pytest splinter

代码示例

下面的代码示例假设有一个导航设备提供页面实例 使用拆分驱动程序构建,但您可以自己构建以下页面实例 pypom文档:

架构定义:

import colander

from pypom_form.form import BaseFormPage


class BaseEditSchema(colander.MappingSchema):
    """ This is the base edit mapping common for all pages """

    name = colander.SchemaNode(
        colander.String(),
        selector=('id', 'name-widget'),
    )


class BaseEditPage(BaseFormPage):
    """ This is the base edit class """

    schema_factory = BaseEditSchema

假设你有一个页面实例,你可以和上面的页面交互 只需设置一个属性:

@pytest_bdd.when(pytest_bdd.parsers.parse(
    'I set {name} as name field'))
def fill_name(navigation, name):
    page = navigation.page
    page.name = name

还可以使用扩展模式定义其他页,例如整数 类型:

class AnotherPageEditSchema(BaseEditSchema):

    duration = colander.SchemaNode(
        colander.Int(),
        missing=0,
        selector=('id',
                  'duration-widget'),
        validator=colander.Range(0, 9999))

但是也可以创建字段类型,如 colander.bool 或任何其他colander 支持的类型。

测试:

@pytest_bdd.when(pytest_bdd.parsers.cfparse(
    'I set {duration:Number} as Alarm duration',
    extra_types=dict(Number=int)))
def fill_alarm_duration(navigation, duration):
    page = navigation.page
    page.duration = duration

您可能会注意到,在上面的示例中,您正在设置一个整数持续时间 而不是一根绳子。因此您可以执行 页。例如,duration+=10

如果默认实现在字段上定义自定义小部件 与应用程序中可用的不匹配(例如非标准 复选框用于布尔窗口小部件),例如假装 mybooleanwidget

mybool = colander.SchemaNode(
    colander.Bool(),
    missing=False,
    selector=(
        'id',
        'mybool-widget'
    ),
    pypom_widget=MyBoolWidget()
)

还支持链式调用(例如:设置标题,执行假装提交方法 然后设置一个布尔值:

page.set('title', 'the title'). \
    .submit(). \
    .set('mybool', False)

或批量更新。所有更改在架构级别按照字段顺序进行:

page.update(**{'title': 'the title', 'mybool': True})

更新 原始更新 可用于创建测试先决条件。 假设您有一个通用的给定步骤,其中参数化了复杂的配置 您可以传递原始json数据,而 原始更新 将处理 从浏览器模型(例如:字符串)到页面模型(字符串、整数, 日期时间等):

page.title = 'the title'
page.title
0

假设 raw_conf 是以json格式指定的 功能文件,例如:

page.title = 'the title'
page.title
1

正如您在上面的代码示例中所看到的,不需要在 在页面加载时与表单交互,因为每个小部件都可以等到 受控输入元件准备就绪。等待逻辑已经在小部件级定义,并且 您可以覆盖它们。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java无法启动应用程序:JNLP错误   java根据用户输入在PreparedStatement中使用setTime()或setNull()   java EJB与同步   java以object为键通过hashmap进行搜索   java中的模10^9+7   针对包含其他对象的对象的java OOP最佳实践   如何将字符串作为HTML代码从Java文件读取到JSP页面?   java我的POM怎么了?“解析表达式..检测到递归表达式循环”   用于Hbase的Mapreduce的java NoSuchMethodError   JAVAlang.SecurityException:权限拒绝:启动意图{act=安卓.Intent.action.MAIN cat=[安卓.Intent.category.LAUNCHER]   数组初始化谜语Java   通过arraylist搜索时的java句柄关联