Behave 简明教程
Behave - Introduction
Behave 是在 Python 编程语言中用于 Behaviour driven development (BDD) 的工具。在一个敏捷开发框架中,BDD 创造了一种文化,其中测试工程师、开发人员、业务分析员和项目的其他相关人员可以为软件开发做出贡献。
简而言之,技术人员和非技术人员都在整个项目中扮演着角色。Behave 的测试使用纯文本编写,并且在 Python 中实现逻辑。
BDD 格式从软件特征的描述开始,类似于一个故事。
然后继续进行开发并执行以下任务−
-
为特征开发一个失败的测试用例。
-
实现一个测试通过的逻辑。
-
代码优化以满足项目指南。
BDD 有大量库,例如支持 JavaScript 的 Mocha、支持 Java/Ruby 的 Cucumber 和支持 Python 的 Behave 等。
在本教程中,我们将详细讨论 Behave。
让我们看看 BDD 的一个基本结构。它主要包括功能文件、步骤定义文件等。
Feature File
Behave 中的功能文件可以如下所示 −
Feature − Verify book name added in Library.
Scenario − Verify Book name.
Given − Book details.
Then − Verify book name.
Behave - Installation
行为安装可以通过以下方式来完成 −
With pip
对于行为安装,我们应该为我们的系统安装 Python 语言 pip – the package installer 。如果 Python 版本大于 2(高达 2.7.9),则会默认安装 pip。
要安装 pip,运行以下提到的命令 −
pip install pip
要使用 Behave 安装 pip,运行以下给出的命令 −
pip install behave
以下屏幕将出现在您的计算机上:
我们可以用以下命令更新现有版本的 Behave −
pip install –U behave
我们还可以使用 easy_install 进行 Behave 安装。
要安装 Setuptools,运行以下提到的命令 −
pip install setuptools
现在,对于 Behave 安装,运行以下陈述的命令:
easy_install behave
我们可以使用下面的命令更新一个现有的 behave 版本:
easy_install –U behave
Behave - Command Line
Behave 有一系列命令行参数,也可以从配置文件中概述。配置文件中设置的值会自动使用,但可以被命令行参数覆盖。
Command Line Arguments
让我们讨论一些命令行参数 −
-
–c, --no-color
损害 ANSI 彩色转义的使用。
-
--color -
使用 ANSI 颜色转义符。这是内置特性,并且可以覆盖配置文件中的设置。
-
–d, --dry-run
在不运行步骤的情况下调用格式化程序。
-
-D, --define
声明 config.userdata 字典的自定义信息。
-
–e, --exclude Pattern
从执行中排除与正则表达式模式相同的特性文件。
-
–i, --include Pattern
在执行期间包含与正则表达式模式相同的特性文件。
-
--no-junit
不输出 JUnit 报告。
-
--junit
添加 JUnit 报告作为输出。启用 JUnit 时,每个 stdout 和 stderr 将成为 junit 报告的一部分。(与 -capture/-no-capture 选项无关)。
-
–f, --format
定义格式化程序。如果省略,将使用内置格式化程序。–format-help 命令将显示所有可用格式。
-
-steps-catalog
显示现有步骤定义的目录。
-
–k, --no-skipped
不将被跳过的步骤打印到控制台中。
-
no-snippets
不将尚未实现的步骤片段打印到控制台中。
-
--snippets
在控制台中打印时包含片段,其中包括尚未实施的步骤。这是内置特性,可覆盖配置文件设置。
-
–m, --no-multiline
排除步骤下的多行表格和字符串。
-
--multiline
在步骤下包含多行表格和字符串。这是内置特性,可覆盖配置文件设置。
-
–n, --name
包含与运行中指定名称相同的特性元素。如果多次提供该选项,则应与所有名称匹配。
-
--no-capture
排除将 stdout 捕获。
-
--capture
包含 stdout。这是内置特性,可覆盖配置文件设置。
-
--no-capture-stderr
排除将 stderr 捕获。
-
--capture-stderr
包含 stderr。这是内置特性,可覆盖配置文件设置。
-
--no-logcapture
排除将日志捕获。
-
--logcapture
包含日志捕获。在故障期间,将出现和提供步骤的每一份日志。这是内置特性,可覆盖配置文件设置。
-
--logging-level
提及应捕获的日志级别。默认值为 INFO。
-
--logging-format
提及打印语句的用户定义格式。默认值为 %(levelname)s:%(name)s:%(message)s。
-
--logging-datefmt
提及打印语句的用户定义日期和时间格式。
-
--logging-filter
提及是否对语句进行过滤。默认会捕获所有语句。如果输出过长,我们可以利用该选项来过滤掉不必要的输出。
-
--logging-clear-handlers
移除用于日志记录的所有处理程序。
-
--no-summary
排除执行后的摘要。
-
-summary
包含执行后的摘要。
-
–o, --outfile
写入给定的文件,而不是使用 stdout。
-
–q, --quiet
别名用于 –no-snippets –no-source。
-
–s, --no-source
不包括打印文件和步骤定义行和步骤。
-
--show-source
包括打印文件和步骤定义行和步骤。这是一个内置特性,并且可以覆盖配置文件设置。
-
--stage
-
--stop
在遇到第一次失败后终止执行测试。
-
–t, --tags
包括具有标记的特性/场景,这些标记与执行中的 TAG_EXPRESSION 相同。
-
–T, --no-timings
不包括打印每个步骤的执行持续时间。
-
--show-timings
在控制台捕获每个步骤完成所需的时间(以秒为单位)。这是一个内置特性,并且可以覆盖配置文件设置。
-
–v, --verbose
显示加载的特性和文件。
-
–w, --wip
执行具有 wip 标记的场景。此外,我们必须使用简单的格式化程序,而不是记录 stdout 或日志输出,并在第一次失败后终止。
-
–x, --expand
展平输出中场景提纲的表格。
-
--lang
使用英语之外的语言的关键字。
-
--lang-list
显示所有可用语言 –lang。
-
--lang-help
显示针对单一语言获取的所有翻译。
-
--tags-help
显示标记语句的帮助信息。
-
--version
显示版本。
-
junit –directory
这是 junit 报告存储的目录位置。
-
--show-skipped
在控制台中打印时包括跳过的步骤。这是一个内置特性,并且可以覆盖配置文件设置。
Behave - Configuration Files
Behave 配置文件称为 .behaverc / behave.ini / setup.cfg / tox.ini (可选择一个并根据用户选择设定)。
文件可以位于以下位置−
-
The present working directory.
-
User home directory.
-
对于 Windows 用户,在目录 %APPDATA% 中。
命令 behave –v 将显示所有配置详情。配置文件应以关键字 [behave] 开头,并遵循 Windows INI 样式格式。
例如,
[behave]
format = plain
dry_run = false
Types of Parameters
Behave 中的配置参数类型包括以下内容−
-
Text − 将文本分配给配置设置。
-
Bool − 将布尔值分配给配置设置。文本定义行为(真值包括 1、true、yes 和 on)。假值包括 0、false、no 和 off)。
-
Sequence<text> − 接受新行上的多个值。
例如,标签表达式可以如下所示−
tags=@a, ~@b
@c
这等效于以下标签表达式−
--tags @a, ~@b --tags @c
Configuration Parameters
Behave 中的一些配置参数如下−
-
color − bool
使用 ANSI 颜色转义。这是一个内置特性,可否决配置文件中的设置。
-
dry_run − bool
调用格式化程序而不运行步骤。
-
userdata_defines − sequence<text>
声明用于 config.userdata 词典的自定义数据。
-
exclude_re − text
从执行中排除与正则表达式模式相同的特性文件。
-
include_re − text
在执行期间包括与正则表达式模式相同的特性文件。
-
junit − bool
添加 JUnit 报告作为输出。启用 JUnit 时,每个 stdout 和 stderr 将成为 junit 报告的一部分。(与 -capture/-no-capture 选项无关)。
-
junit_directory − text
这是存储 JUnit 报表的位置。
-
default_format − text
声明默认格式。默认值为 pretty。
-
format: sequence<text>
定义格式化程序。如果省略,将使用内置格式化程序。–format-help 命令将显示所有可用格式。
-
steps_catalog − bool
显示现有步骤定义的目录。
-
scenario_outline_annotation_schema: text
提及场景大纲的注释模式。
-
show_skipped − bool
在控制台打印时包含跳过的步骤。这是内置特性,并且可以覆盖配置文件设置。
-
show_snippets − bool
在控制台打印时包括尚未实现的步骤的代码段。这是内置特性,并且可以覆盖配置文件设置。
-
show_multiline − bool
在步骤下包含多行表格和字符串。这是内置特性,可覆盖配置文件设置。
-
name − sequence<text>
包括在运行中与指定名称相同的特性元素。如果多次提供此选项,它将匹配所有指定的名称。
-
stdout_capture − bool
包含 stdout。这是内置特性,可覆盖配置文件设置。
-
stderr_capture − bool
包含 stderr。这是内置特性,可覆盖配置文件设置。
-
log_capture − bool
包含日志捕获。在故障期间,将出现和提供步骤的每一份日志。这是内置特性,可覆盖配置文件设置。
-
logging_level − text
提及要捕获的日志级别。默认值为 INFO。
-
logging_format − text
提及用于打印语句的用户定义格式。默认值为 %(levelname)s:%(name)s:%(message)s。
-
logging_datefmt − text
提及用于打印语句的用户定义日期和时间格式。
-
logging_filter − text
提及要过滤的语句。默认情况下捕获所有语句。如果输出太长,我们可以使用该选项来过滤掉不必要的输出。
-
logging_clear_handlers : bool
移除用于日志记录的所有处理程序。
-
summary − bool
执行后包括一个摘要。
-
outfiles − sequence<text>
写入给定的文件,而不是使用 stdout。
-
paths − sequence<text>
提及特性的文件默认路径。
-
quiet − bool
别名用于 –no-snippets –no-source。
-
show-source − bool
包括打印文件和步骤定义的行,以及步骤。这是内置特性,并且可以覆盖配置文件设置。
-
stage − text
描述测试的当前阶段。阶段名称用作环境文件的名称附加信息,以及步骤目录。
-
stop − bool
在遇到第一次失败后终止执行测试。
-
tags − sequence<text>
在执行中包括具有与 TAG_EXPRESSION 相同标记的特性/场景。
-
default_tags − text
如果未给定默认标记,则声明默认标记。
-
show_timings − bool
在控制台捕获每个步骤完成所需的时间(以秒为单位)。这是一个内置特性,并且可以覆盖配置文件设置。
-
verbose − bool
显示加载的特性和文件。
-
wip − bool
执行具有 wip 标记的场景。此外,我们必须使用简单的格式化程序,而不是记录 stdout 或日志输出,并在第一次失败后终止。
-
expand − bool
展平输出中场景提纲的表格。
-
lang − text
使用英语之外的语言的关键字。
Behave - Feature Testing Setup
Behave 使用三种不同的文件类型,如下所示 −
-
由业务分析员或任何项目相关人员创建的 Feature files ,其中包含与行为相关的用例。
-
Step Implementation file 用于功能文件中定义的场景。
-
Environment Setup files ,在其中,步骤、特性、场景等之前和之后要执行前提条件/后置条件。
Feature File
功能文件应该位于名为特性文件夹中。此外,特性目录中应该有一个名为步骤的子目录。
Launching Feature file
我们可以使用各种命令行参数启动特性文件。这些如下所述 −
-
如果没有可用的信息,将加载 features 目录中的所有特性文件以在 behave 中执行。
-
如果提供了功能目录的路径,那么功能目录中必须至少有一个功能文件(.feature 扩展名)和一个名为 steps 的子目录。
-
此外,如果 environment.py 存在,它应当位于具有 steps 目录的目录中,而不在 steps 目录中。
-
如果提供了指向功能文件的路径,那么它指示 Behave 搜索该文件。要获取该功能文件对应的步骤目录,需要搜索父目录。
-
如果没有在当前父目录中找到,则查找其父目录。当到达文件系统根目录时,此过程将继续。另外,如果 environment.py 存在,则它应位于包含 steps 目录(而不是 steps 目录内)的目录中。
Behave - Gherkin Keywords
行为中的 Gherkin 关键字列在下面 −
-
Features
-
Scenario
-
Steps
-
Background
-
Scenario Outline
-
Text
-
Table
-
Tags
-
Given
-
When
-
Then
-
But
-
And
特征文件是用 Gherkin 语言编写的。它是纯文本,由团队的非技术成员(业务分析师)创建的。特征文件既可用于自动化测试,又可用于文档编制。
行尾结束语句包含在行为中。我们可以使用制表符/空格来缩进。大多数行均以 Scenario、Given、Then 等关键字开始。可以在文件中的任何位置添加注释。它们以 / 或 # 符号及其相关内容开始,前面可能带有空格。
让我们讨论一些重要的 Gherkin 关键字。
Feature
功能包含用例。它们可能包含或不包含描述、背景和一组标记。
功能文件结构如下 -
Feature − Verify book name added in Library
Scenario − Verify Book name
Given Book details
Then Verify book name
功能的名称应该包含被测试功能的描述。不过,不会强制要求提供冗长的描述,只在功能名称有歧义时才添加描述。
Background
添加背景以包含一组步骤。它接近于用例。我们可以使用背景为多个用例添加上下文。它在功能的每个用例之前运行,但处于 before hook 执行之后。
Background 通常用于执行前提条件,例如登录场景或数据库连接等。
可以添加背景描述以提高人类可读性。背景只能在功能文件中出现一次,并且必须在用例或用例大纲之前声明。
不应将背景用于创建复杂状态(仅在不可避免时)。这段应简短且真实。此外,我们应该避免在一个功能文件中包含大量用例。
Feature File with Background
具有背景关键字的功能文件如下 -
Feature: Payment Process
Background:
Given launch application
Then Input credentials
Scenario: Credit card transaction
Given user is on credit card payment screen
Then user should be able to complete credit card payment
Scenario: Debit card transaction
Given user is on debit card payment screen
Then user should be able to complete debit card payment
Scenario
用例定义被测试应用程序的行为。它通过标题描述其目标。可以添加描述以提高人类可读性。
用例可能有多个步骤,以关键字 Given、Then、When 等开头。建议使用用例来检查单个特征或预期结果。
Feature File with Scenario
具有用例关键字的功能文件如下:
Feature − Payment Process
Scenario − Credit card transaction
Given user is on credit card payment screen
Then user should be able to complete credit card payment
Scenario Outline
如果我们有一组类似的条件和要传递到用例中的结果,则使用用例大纲。用例大纲附带一个示例表,并且可以有多个示例表。
测试根据示例表中标题行内找到的每一行执行一次。要测试的值由括号 <> 中包含的名称表示。这些名称应与示例表标题匹配。
它有助于减少代码行数,因为它消除了重复步骤并排列了我们的测试。
Feature File with Scenario Outline
具有用例大纲关键字的功能文件如下 -
Feature − User information
Scenario Outline: Check login functionality
Given user enters <email> and <password>
Then user should be logged in
Example
以下是具有用例大纲的功能文件示例 -
Examples: Credentials
| email | password |
| qa@gmail.com | pwd1 |
| qe@gmail.com | pwd2 |
使用不同的参数集执行相同的测试。
Given
以关键字 Given 开始的步骤用于在用户与系统交互之前(类似于前置条件)将系统置于熟悉的环境中。建议在 Given 步骤中不描述用户操作。
我们可以添加一个 Given 步骤来设置数据库中的配置,登录应用程序,等等。
Feature File with Given
使用 Given 关键字的功能文件如下 −
Feature − Payment Process
Scenario − Credit card transaction
Given user is on credit card payment screen
Then user should be able to complete credit card payment
When
从关键字 When 开始的步骤用于添加用户要执行的重要任务。通过此步骤,用户可以与系统进行通信,从而更改系统的状态或影响其他地方。
Feature File with When
使用 When 关键字的功能文件如下 −
Feature − Payment Process
Scenario − Credit card transaction
Given user is on credit card payment screen
When user clicks on the Payment with Credit Card button
Then user should be able to complete credit card payment
Then
从关键字 Then 开始的步骤用于获取预期结果。此步骤中观察到的结果(理想情况下为输出形式 - 消息、报告等)应连接到业务场景和其中存在的特征文件。
建议不要将 Then 步骤用于数据库场景,因为它本质上用于描述最终用户可注意的后果。
Feature File with Then
使用 When 关键字的功能文件如下 −
Feature − Payment Process
Scenario − Credit card transaction
Given user is on credit card payment screen
When user clicks on the Payment with Credit Card button
Then user should be able to complete credit card payment
And, But
如果我们有多个连续的 Given、When、Then 步骤,我们可以使用 And 和 But 步骤。它为用户提供了更好的可读性。
Feature File with multiple consecutive Then/Given steps
在 Behave 中有多个连续 Then/Given 步骤的功能文件如下 −
Feature − Verify book names added in Library
Scenario − Verify Book name
Given Book1 details
Given Book2 details
Then Verify book names
Then Verify newly added book names should not be in Delete History
Feature File without multiple Then/Given steps
没有多个 Then/Given 步骤的功能文件如下 −
Feature − Verify book names added in Library
Scenario − Verify Book name
Given Book1 details
And Book2 details
Then Verify book names
But Verify newly added book names should not be in Delete History
Step Data – Table
一个步骤可以有一个与其关联的文本和数据表。我们可以为一个步骤添加一个数据表。建议将表格数据缩进,并且必须为每行指定相等数量的列。
列数据应使用 | 符号分隔。
Feature File with Table
具有表格关键字的功能文件如下 −
Feature − User Registration
Scenario − User enters registration details
When User enters name and password
| name |password |
| t1 | pwd |
| t2 | pwd1 |
Then user should be able to complete registration
可以在上下文变量(在步骤函数中传递)中的 .table 属性中使用表格来访问 Python 实现代码。表格是 Table 的实例。
Implementation logic for Table
在 Table 中对 .table 属性的实现逻辑如下:
@when('User enters name and password')
def step_impl(context):
for r in context.table:
model.delete_usr(name=r['name'], password=r['password'])
Step Data – Text
在 """ 中封闭的步骤后的文本块将与该步骤关联。在此处,会分析缩进。从文本中删除所有开头的空格。此外,所有后续行都必须至少有一个空格作为起始行。
可以通过上下文变量(在 step 函数中传递)中的 .text 属性访问实现 Python 代码的文本。
Feature File with Text
使用 text 关键字的功能文件如下:
Feature − Verify book name added in Library
Scenario − Verify Book name
Given Book details
"""
Text added for a step
"""
Then Verify book name
Tags
功能文件的章节可以进行标记,以便 Behave 能够仅验证该功能文件的部分章节。只有场景、功能、场景大纲可以进行标记。
此外,用于功能的标记应由其所有的场景和大纲继承。标记放在我们要标记的场景或功能之前。我们还可以在一行内通过空格使用多个标记。一个标记以 @ 开头,后跟标记名称。
Feature File with tags
使用 tags 关键字的功能文件如下:
@payment
@high
Feature − Payment Process
Scenario − Credit card transaction
Given user is on credit card payment screen
Then user should be able to complete credit card payment
标记有助于通过排除/包含取决于该标记的特定场景或功能来管理测试执行。
Behave - Feature Files
如前所述,Behave 使用三种不同的文件类型。这些文件如下——
-
Feature files 由业务分析师或任何项目利益相关者创建,并包含与行为相关的用例。
-
Step Implementation file 用于功能文件中定义的场景。
-
Environment Setup files 其中预/后置条件将在步骤、功能、场景等之前和之后执行。
功能文件应位于名为 features 的文件夹中。此外,features 目录中还应有子目录 steps。
以下屏幕将出现在您的计算机上:
Launching Feature file
我们可以使用各种命令行参数启动功能文件,如下所述——
-
如果没有可用的信息,features 目录中的所有功能文件都将被加载以在 Behave 中执行。
-
如果提供了功能目录的路径,那么功能目录中必须至少有一个功能文件(.feature 扩展名)和一个名为 steps 的子目录。
-
此外,如果 environment.py 存在,它应当位于具有 steps 目录的目录中,而不在 steps 目录中。
-
如果提供了指向功能文件的路径,那么它指示 Behave 搜索该文件。要获取该功能文件对应的步骤目录,需要搜索父目录。
-
如果在当前父目录中未找到,则搜索其父目录。这将一直持续到到达文件系统根目录为止。此外,如果 environment.py 存在,它应当位于具有 steps 目录的目录中,而不在 steps 目录中。
Structure of a Feature File
功能包括场景。场景可能包含也可能不包含说明、背景和一组标记。
功能文件结构如下 −
Feature File
功能文件格式如下 −
Feature − Verify book name added in Library
Scenario − Verify Book name
Given Book details
Then Verify book name
Corresponding Step Implementation File.
相应的步骤实现文件看起来像下面提到的文件 −
from behave import *
@given('Book details')
def impl_bk(context):
print('Book details entered')
@then('Verify book name')
def impl_bk(context):
print('Verify book name')
Output
运行功能文件后获得的输出如下 −
输出显示功能和场景名称,以及测试结果和测试执行时间。
Behave - Step Implementations
Behave 中功能文件中的场景步骤应具有以 Python 编写的执行逻辑。这称为执行/步骤定义文件(.py 扩展名),应存在于 steps 目录中。
此文件中提供了所有必需的导入。步骤目录应成为特性目录的一部分。
以下屏幕将出现在您的计算机上:
步骤定义文件包含定义特性文件中的步骤的 Python 函数。在 Python 函数的开头,必须具有以 @given、@when 等开头的修饰符。这些修饰符与功能文件中的给定、然后、何时和其他步骤进行比较和匹配。
Feature File
功能文件如下 −
Feature − Verify book name added in Library
Scenario − Verify Book name
Given Book details
Then Verify book name
Corresponding Step Implementation File
相应的步骤实现文件看起来像下面提到的文件 −
from behave import *
@given('Book details')
def impl_bk(context):
print('Book details entered')
@then('Verify book name')
def impl_bk(context):
print('Verify book name')
Output
运行功能文件后获得的输出如下 −
输出显示功能和场景名称,以及测试结果和测试执行的持续时间。
Behave - First Steps
让我们创建一个基本的 Behave 测试。
Feature File
标题为支付类型的功能文件的示例如下 −
Feature − Payment Types
Scenario − Verify user has two payment options
Given User is on Payment screen
When User clicks on Payment types
Then User should get Types Cheque and Cash
Corresponding Step Implementation File
上述功能对应的步骤实现文件如下 −
from behave import *
@given('User is on Payment screen')
def impl_bkpy(context):
print('User is on Payment screen')
@when('User clicks on Payment types')
def impl_bkpy(context):
print('User clicks on Payment types')
@then('User should get Types Cheque and Cash')
def impl_bkpy(context):
print('User should get Types Cheque and Cash')
Project Structure
功能“支付类型”的项目结构如下 −
Output
运行功能文件后获得的输出如下,此处使用的命令为 behave
输出显示功能和场景名称,以及测试结果和测试执行的持续时间。
Python 控制台输出如下 −
Behave - Supported Languages
我们有权在功能文件中使用除英语以外的其他语言。这是因为大多数 BDD 工具都支持国际化。重要的是,关键字 - Then、When、Given 可以用其他本机语言(如西班牙语、法语等)描述。
在这种情况下,开发人员还可以在其他语言中实现步骤定义。可以使用以下命令获取所有语言的列表:behave --lang-list。
使用命令 behave --lang-list 后,以下屏幕将出现在您的计算机上:
Behave 中包含的其他一些语言如下所示:
功能文件可以与特定语言相关联。此时,BDD 框架会选择该特定语言的关键词。该语言可以在配置文件中设置为默认值。
行为配置文件可以是 .behaverc 或 behave.ini 文件。如果我们想要语言为丹麦语,则该配置文件中的参数 lang 值应设置为 da。
Behave - Step Parameters
我们可以在 Behave 里将参数传递给步骤。让我们检视一个功能文件,其中包含具有多个参数且设置了不同值的步骤。这有助于简化自动化实现,因为减少了总的步骤定义。
Feature File
请考虑如下功能文件示例:
Feature − Schedule
Scenario − Verify Day and Night Schedule
Given I reach office at "day" shift
And I reach office at "night" shift
该功能文件包含几乎与 Given 和 And 步骤相同的步骤。唯一的区别在于白天和晚上的轮班时间。我们可以将参数传递给步骤定义文件中的步骤,而不必重复实现几乎相同的步骤。
请注意:我们将 day 和 night 参数放在双引号文本中(也可以使用单引号文本)放入功能文件中。在步骤实现中,我们将以 {} 括住传递参数。
此外,该参数作为带有实现方法的自变量之一传递。
Corresponding Step Implementation File
相应的步骤实现文件如下:
from behave import *
@given('I reach office at "{time}" shift')
def step_implpy(context, time):
print("Shift is: {}".format(time))
Output
运行功能文件后获得的输出如下,使用的命令是 behave --no-capture -f plain :
输出显示 Shift is: day 和 Shift is: night 已打印。在此处,参数 day 和 night 从步骤传递。
Behave - Scenario Outlines
如果我们有一组类似的条件并且结果要传递给场景,则可以使用场景提纲。场景提纲与示例表一起使用。场景提纲可以有多个示例表。
对于在示例表(接表头行之后)中找到的每一行,测试都将执行一次。要测试的值由括号<>中的名称表示。这些名称应与示例表头相匹配。
它有助于减少代码行数(消除重复步骤)并对我们的测试进行排序。
Feature File
场景大纲的功能文件如下−
Feature − User information
Scenario Outline: Check login functionality
Given user enters "<name>" and "<password>"
Then user should be logged in
Examples: Credentials
| name | password |
| user1 | pwd1 |
| user2 | pwd2 |
请注意:我们已将名称和密码参数括在“<>”中。这些参数是“示例”部分下方提供的列标题。在步骤实现中,我们将传递括在“{}”中的参数。
此外,这些参数需要作为参数传递给实现方法。
Corresponding Step Implementation File
相应的步骤实现文件如下:
from behave import *
@given('user enters "{name}" and "{password}"')
def step_implpy(context, name, password):
print("Username for login: {}".format(name))
print("Password for login: {}".format(password))
@then('user should be logged in')
def step_implpy(context):
pass
Output
在运行功能文件并使用 behave --no-capture -f plain 命令后,即可获得输出。
输出显示 Username for login: user1, Password for login: pwd1 and Username for login: user2, Password for login: pwd2 已打印。此处,两个数据集已从“示例”传递。
Behave - Multiline Text
用 “””括起来的步骤后的文本块将与此步骤链接。此处,解析缩进。将从文本中删除开头的所有空格,并且所有后续行都必须至少有一个最小空格作为起始行。
可以通过上下文变量(在 step 函数中传递)中的 .text 属性访问实现 Python 代码的文本。
Feature File
标题为用户信息的 feature 文件如下−
Feature − User information
Scenario − Check login functionality
Given user enters name and password
"""
Tutorialspoint Behave
Topic – Multiline Text
"""
Then user should be logged in
Corresponding Step Implementation File
该 feature 的相应步骤实现文件如下−
from behave import *
@given('user enters name and password')
def step_impl(context):
#access multiline text with .text attribute
print("Multiline Text: " + context.text)
@then('user should be logged in')
def step_impl(context):
pass
Output
运行该 feature 文件后获取的输出如下所示并且所使用的命令是 behave --no-capture -f plain 。
输出显示打印的多行文本。
Behave - Setup Table
一个步骤可以有一个与其关联的文本和数据表。我们可以为一个步骤添加一个数据表。建议将表格数据缩进,并且必须为每行指定相等数量的列。
列数据应使用 | 符号分隔。
Feature File with Table (Login.feature)
功能文件如下所示 −
Feature − User Information
Scenario − Check login functionality
Given Collection of credentials
| username |password |
| user1 | pwd1 |
| user2 | pwd2 |
Then user should be logged in
一个表可以用 context 变量(在步骤函数中传递)中的 .table 属性访问实现的 Python 代码。(表的一个实例。我们可以使用设置表来帮助设置测试。
Python code
访问表(login_module.py)的 Python 代码如下 −
class Deprt(object):
def __init__(self, username, ms=None):
if not ms:
ms = []
self.username = username
self.ms = ms
def m_addition(self, usernane):
assert usernane not in self.ms
self.ms.append(usernane)
class LModel(object):
def __init__(self):
self.loginusrs = []f
self.passwords = {}
def usr_addition(self, username, password):
assert username not in self.loginusrs
if password not in self.passwords:
self.passwords[password] = Deprt(password)
self.passwords[password].m_addition(username)
Corresponding Step Implementation File(step_implg.py)
文件如下所示 −
from behave import *
from features.steps.login_module import LModel
@given('Collection of credentials')
def step_impl(context):
model = getattr(context, "model", None)
if not model:
context.model = LModel()
#iterate rows of table
for r in context.table:
context.model.usr_addition(r["username"], password=r["password"])
@then('user should be logged in')
def step_impl(context):
pass
Project setup
在 Python 项目中设置的文件如下所示
Output
运行功能文件后获得的输出如下,使用的命令是 behave --no-capture -f plain 。
输出显示打印了 step up 表。
Behave - Steps in a Step
我们可以在一个情景中用一个宏步骤替换多个步骤。这有助于我们在步骤定义文件中不重复相同的代码。BDD 框架有能力从步骤定义调用多个步骤。
Feature File with Similar Steps
具有类似步骤的特性文件如下所示 -
Feature − Payment Module
Scenario − Verify message after payment
Given User is on payment screen
When User enters payment details
And User completes payment
Then User should get success message
Scenario − Verify new users can process payment
Given User keys in payment info and submits
Then success message should get displayed
在特性文件中,我们有两个具有类似步骤的情景。在 Behave 中,我们可以在单个步骤中执行多个步骤。这可以通过步骤实现文件中的 context.execute_steps 方法完成。
Corresponding Step Implementation File
上面提到的特性文件对应的步骤实现文件如下 -
from behave import *
@given('User is on payment screen')
def is_on_payment_screen(context):
print('User is on payment screen')
@when('User enters payment details')
def enters_payment_details(context):
print('When User enters payment details')
@when('User completes payment')
def completes_payment(context):
print('When User completes payment')
@then('User should get success message')
def get_success_message(context):
print('Then User should get success message')
@given('User keys in payment info and submits')
def payment_info_and_submits(context):
#passing steps within steps with context.execute_steps
context.execute_steps(u"""
Given User is on payment screen
When User enters payment details
And User completes payment
""")
@then('success message should get displayed')
def success_message(context):
print('Then success message should get displayed')
Output
运行功能文件后获得的输出如下,使用的命令是 behave --no-capture -f plain 。
后续输出如下所示 −
输出显示情景验证的新用户可以通过执行情景验证新用户可以处理付款中的步骤来处理付款。
Behave - Background
Background 用于为一群步骤添加组。它接近一个场景。我们可以使用 Background 向多个场景添加一个上下文。它在每个特征的场景之前运行,但在执行之前的钩子之后运行。
Background 通常用于执行前提条件,例如登录场景或数据库连接等。
可以添加 Background 描述,以便人类更好理解。它在特征文件中的只出现一次,并且必须在场景或场景大纲之前声明。
不应该使用 Background 来创建复杂的状态(只有在无法避免的情况下才使用)。该段落应该简洁且真实。另外,我们应该避免在一个特征文件中包含大量场景。
Feature File with Background
以下是标题为“payment process”的特征的包含 background 的特征文件−
Feature − Payment Process
Background:
Given launch application
Then Input credentials
Scenario − Credit card transaction
Given user is on credit card payment screen
Then user should be able to complete credit card payment
Scenario − Debit card transaction
Given user is on debit card payment screen
Then user should be able to complete debit card payment
Corresponding Step Implementation File
该文件如下所示−
from behave import *
@given('launch application')
def launch_application(context):
print('launch application')
@then('Input credentials')
def input_credentials(context):
print('Input credentials')
@given('user is on credit card payment screen')
def credit_card_pay(context):
print('User is on credit card payment screen')
@then('user should be able to complete credit card payment')
def credit_card_pay_comp(context):
print('user should be able to complete credit card pay')
@given('user is on debit card payment screen')
def debit_card_pay(context):
print('User is on debit card payment screen')
@then('user should be able to complete debit card payment')
def debit_card_pay_comp(context):
print('user should be able to complete debit card payment')
Output
以下是运行特征文件后获得的输出,这里使用的命令为 behave --no-capture -f plain 。
后续输出如下所示 −
输出显示 Background 步骤(Given 启动应用程序和 Then 输入凭据)在每个场景之前运行了两次。
Behave - Data Types
Behave 中存在两种数据类型,即预定义和用户定义。让我们首先了解什么是预定义数据类型。
Pre-defined Data types
Behave 利用解析模块来解析步骤定义中的解析参数。让我们探索一些对步骤定义有支持且无需像用户定义数据类型那样注册的解析类型。
-
w(类型为 str)- 下划线和字母。
-
W(类型为 str)- 下划线和非字母。
-
s(类型为 str)- 空白。
-
S(类型为 str)- 非空白。
-
d(类型为 int)- 数字。
-
D(类型为 str)- 非数字。
-
n(类型为 int)- 带千位分隔符的数字。
-
%(类型为 float)- 百分比。(转换为值/100.0)
-
f(类型为 float)- 定点数字。
-
e(浮点型)−浮点数连同指数。
-
g(浮点型)−数字格式。
-
b(整型)−二进制数。
-
(整型)−八进制数。
-
x(整型)−十六进制数。
-
ti(datetime 型)−ISO 8601 日期/时间格式的时间。
-
te(datetime 型)−RFC 2822 电子邮件数据/时间格式的时间。
-
tg(datetime 型)−Global 数据/时间格式的时间。
-
ta(datetime 型)−US 数据/时间格式的时间。
-
tc(datetime 型)−ctime() 数据/时间格式。
-
th(datetime 型)−HTTP 日志数据/时间格式的时间。
-
tt (of time type)
在步骤实现中,我们将传递以下参数:包含在“{}”中的数据类型。
Feature File with % data type
带有 % 数据类型的功能文件如下所示 −
Feature − Payment Process
Scenario Outline: Credit card transaction
Given user is on credit card payment screen
When user makes a payment of "<p>" percent of total
Examples: Amounts
| p |
|80% |
|90% |
Corresponding Step Implementation File
文件如下所示 −
from behave import *
@given('user is on credit card payment screen')
def credit_card_pay(context):
print('User is on credit card payment screen')
#passing parameter in % datatype enclosed in {}
@when('user makes a payment of "{p:%}" percent of total')
def step_impl(context, p):
print('Number is: ')
print(p)
Output
在运行功能文件并使用 behave --no-capture -f plain 命令后,即可获得输出。
后续输出如下所示 −
输出显示 0.8 和 0.9,它们是由 % 数据类型获得的,以表示从功能文件中传递的 80% 和 90% 的值。
User-defined Data types
Behave 还有用户定义的数据类型。register_type 方法用于注册一个用户自定义类型,该类型可在匹配步骤时进行任何类型转换的解析。
Feature File
标题为支付流程的功能文件如下−
Feature − Payment Process
Scenario Outline: Credit card transaction
Given user is on credit card payment screen
When user makes a payment of "<amount>" of total
Examples: Amounts
|amount |
|75 |
|85 |
在步骤实现中,我们将传递参数:用“{}”括起用户定义的数据类型。register_type 方法用于注册用户自定义类型,该类型可以在匹配步骤时被解析为任何类型转换。
Corresponding Step Implementation File
文件如下所示 −
from behave import *
from behave import register_type
#convert parsed text to float
def parse_percent(t):
return float(t)
#register user-defined type
register_type(Float=parse_percent)
@given('user is on credit card payment screen')
def credit_card_pay(context):
print('User is on credit card payment screen')
@when('user makes a payment of "{amount:Float}" of total')
def step_impl(context, amount):
print('Number is: ')
print(amount)
Output
在运行功能文件并使用 behave --no-capture -f plain 命令后,即可获得输出。
后续输出如下所示 −
输出显示 75.0 和 85.0 ,它们已转换为浮点值(借助用户定义的转换)。这些参数作为整数类型从功能文件中传递。
Behave - Tags
功能文件的章节可以进行标记,以便 Behave 能够仅验证该功能文件的部分章节。只有场景、功能、场景大纲可以进行标记。
此外,用于功能的标签应被其所有场景和场景大纲继承。标签位于我们要标记的场景或功能之前。我们还可以在一行中用空格分隔多个标签。
标签以 @ 开头,后跟标签名称。
Feature File with tags (Payment.feature)
带标签的功能文件如下所示 −
@high
Feature − Payment Process
@creditpayment
Scenario − Credit card transaction
Given user is on credit card payment screen
Then user should be able to complete credit card payment
@debitpayment
Scenario − Debit card transaction
Given user is on debit card payment screen
Then user should be able to complete debit card payment
标记有助于通过排除/包含取决于该标记的特定场景或功能来管理测试执行。
在上例中,要运行带有标签 creditpayment 的特定场景,我们必须运行以下命令 −
behave payment.feature --tags=creditpayment
要运行带有标签 high 的功能并执行所有场景,我们必须运行以下命令 −
behave payment.feature --tags=high
如果运行以下所示的命令,则表示该命令将执行标记为 creditpayment 或 debitpayment 的场景。
behave payment.feature --tags= creditpayment, debitpayment
如果运行以下给出的命令,则表示该命令将执行标记为 creditpayment 和 debitpayment 的两个场景。
behave payment.feature --tags= creditpayment --tags=debitpayment
如果运行以下所示的命令,则表示该命令不会执行标记为 creditpayment 的场景。
behave payment.feature --tags= ~ creditpayment
因此, the Feature File with tags(Payment.feature) 现在将如下所示 −
@high
Feature − Payment Process
@creditpayment @payment
Scenario − Credit card transaction
Given user is on credit card payment screen
@debitpayment @payment
Scenario − Debit card transaction
Given user is on debit card payment screen
Scenario − Cheque transaction
Given user is on cheque payment screen
Corresponding Step Implementation File
文件如下所示 −
from behave import *
@given('user is on credit card payment screen')
def credit_card_pay(context):
print('User is on credit card payment screen')
@given('user is on debit card payment screen')
def debit_card_pay(context):
print('user is on debit card payment screen')
@given('user is on cheque payment screen')
def cheque_pay(context):
print('user is on cheque payment screen')
Output
运行功能文件后获得的输出如下。在这里,我们使用了命令 behave --no-capture Payment.feature --tags=payment 。
输出显示两个场景通过,因为在功能文件中,有两个场景带有 payment 场景标签。
当我们使用命令 behave --no-capture Payment.feature --tags=~creditpayment 时,输出如下 −
输出显示两个场景通过,因为在功能文件中,有两个场景没有标记为 creditpayment 的场景标签。
当我们使用命令 behave --no-capture Payment.feature --tags=high 时,输出如下 −
输出显示三个场景通过,因为在功能文件中,有三个场景没有标记为 high 的功能。
使用命令 behave --no-capture Payment.feature --tags=payment,creditpayment 以获取以下提到的输出 −
该输出显示通过了两个场景,因为功能文件中没有标记为“payment”或“creditpayment”的场景。
Behave - Enumeration
枚举用于将基于多个独特字符串的单词映射到值。
我们可能需要具有以下特征的用户定义数据类型 −
-
必须匹配少量单词。
-
在测试执行前进行预定义值。
对于以上场景,可以使用基于字符串的枚举。
Feature File
考虑一个针对名为 payment process 的功能的功能文件,如下所示 −
Feature − Payment Process
Scenario − Response
When User asks "Is payment done?"
Then response is "No"
在步骤实现文件中,TypeBuilder.make_enum 函数对提供的单词或字符串枚举求值为正则表达式模式。method register_type 用于注册一个用户定义类型,该类型可以在匹配步骤时被解析为任何类型转换。
此外,我们应传入参数:用“{}”括起来的用户定义枚举数据类型。
Corresponding Step Implementation File
以下是针对上述功能的步骤实现文件 −
from behave import *
from behave import register_type
from parse_type import TypeBuilder
# -- ENUM: Yields True (for "yes"), False (for "no")
parse_response = TypeBuilder.make_enum({"yes": True, "no": False})
register_type(Response=parse_response)
@when('User asks "{q}"')
def step_question(context, q):
print("Question is: ")
print(q)
@then('response is "{a:Response}"')
def step_answer(context, a):
print("Answer is: ")
print(a)
Output
运行功能文件后获得的输出如下。这里,我们使用了命令 behave --no-capture -f plain 。
输出显示 Is payment done? 和 False 。False 输出来自枚举数据类型。
Behave - Step Matchers
Behave 中有三种类型的 Step Matcher。它们如下所示 −
-
ParseMatcher (parse) − 基于 parse 模块。
-
extended ParseMatcher(cfparse) − 允许基数语法。
-
RegexMatcher (re) − 基于用于匹配模式的正则表达式。
Parse matcher
内置的 step matcher 具有以下所述特性:
-
使用和理解简单。
-
预定义和用户定义的数据类型支持此匹配器。
-
借助数据类型重新利用正则表达式。
-
隐藏正则表达式的复杂性。
extended Parse matcher
它扩展了 Parse Matcher。它除了具有 Parse 匹配器的特性外,还具有其他特性。
其他特性包括 −
-
理解基数字段语法。
-
为具有基数字段部分的字段生成缺失的类型转换器。
-
Built on parse-type.
Parse Matchers
功能文件中可能会有几乎具有类似短语的步骤。Behave 具有解析能力。方法 use_step_parser 用于此操作,我们必须将解析器类型作为参数传递给该方法。
对于解析匹配器,我们必须传递参数解析。它利用解析进行正则表达式解析和匹配。
Feature File (almost Given similar steps)
相似步骤的功能文件如下所示 −
Feature − Payment Process
Scenario − Check Debit transactions
Given user is on "debit" screen
When user makes a payment
Scenario − Check Credit transactions
Given user is on "credit" screen
Corresponding Step Implementation File
步骤实现文件如下所示 −
from behave import *
#define parser type
use_step_matcher("parse")
@given('user is on "{p}" screen')
def step_impl(context, p):
print(p)
@when('user makes a payment')
def step_pay_complete(context):
pass
Output
运行功能文件后获得的输出如下。这里,我们使用了命令 behave --no-capture -f plain 。
输出显示 debit 和 credit 。这两个值几乎与功能文件中的 Given 步骤类似而传递。在步骤实现中,我们解析了这两个步骤。
Behave - Regular Expressions
让我们对正则表达式的语法进行总体了解 −
-
点 (.) − 等效于任何字符。
-
脱字符号 (^) − 等效于字符串的开头。(^…)
-
美元符号 ($) − 等效于字符串的结尾。 (…$)
-
| − 表达式 x| y,匹配 x 或 y。
-
\ − Escape character.
-
\. − 匹配点。 (.)
-
\\ − 匹配反斜杠。 (\)
-
[…] − 声明一组字符。 ([A-Za-z])
-
\d − 匹配数字。 ([0-9])
-
\D − Matches non-digit.
-
\s − 匹配空白字符。
-
\S − 匹配非空白字符。
-
\w − Matches alphanumeric.
-
\W − Matches non-alphanumeric.
-
(…) − 将正则表达式的模式分组。
-
\number − 按照索引匹配前一组文本。(\1)
-
(? P<name>…) − 匹配模式,并将它存储在 name 参数中。
-
(?P=name) − 匹配所有与前一组 name 匹配的文本。
-
(?:…) − 匹配模式,但无法捕获文本。
-
(?#…) − 注释(不被视为模式)。叙述模式的详细信息。
如果一个字符、字符集或组需要重复多次,有必要提供正则表达式的模式基数。
-
?:基数为 0… 1 的模式:非必需的(问号)
-
-:基数为 0 或更多,0.. 的模式(星号)
-
+ -:基数为 1 或更多,1.. 的模式(加号)
-
{n}:为 n 次重复匹配一个模式。
-
{a ,b}:为 a 至 b 次重复匹配一个模式。
-
[A-Za-z]+:匹配多个字母字符。
功能文件中可能会有包含几乎相似短语的步骤。Behave 具有解析能力。为此使用了 use_step_parser 方法,我们必须将解析器类型作为参数传递给该方法。
对于正则表达式匹配器,我们必须传递参数 re。参数 (? P<name>…) 用来从步骤定义获取参数。
Feature File (almost similar steps)
类似步骤的功能文件如下所示 −
Feature − Payment Process
Scenario − Check Debit transactions
Given user is on "debit" screen
Scenario − Check Credit transactions
Given user is on "credit" screen
Corresponding Step Implementation File
步骤实现文件如下所示 −
from behave import *
#define parser type
use_step_matcher("re")
#regular expression parsing
@given('user is on "(?P<payment>.*)" screen')
def step_impl(context, payment):
print("Screen type: ")
print(payment)
Output
运行功能文件后获得的输出如下。在此,我们使用了命令 behave --no-capture -f plain 。
输出显示了借方和贷方。这两个值在功能文件中以几乎相似的步骤传递。在步骤执行中,我们使用正则表达式解析了两个步骤。
Behave - Optional Part
在 feature 文件中可能存在具有几乎相似短语的步骤。Behave 具有解析能力以便一个步骤定义可以涵盖这些步骤。为此使用 use_step_parser 方法,并且我们必须将解析器类型作为参数传递给该方法。
对于扩展解析匹配,我们必须传递参数 cfparse。它具有基数字段 (CF) 支持。在默认情况下,它为连接的基数生成缺失的类型转换器(如果给定了基数等于一的类型转换器)。
它可以支持以下解析表达式−
-
{values:Type+} – Cardinality=1..N, many
-
{values:Type*} – Cardinality=0..N, many0
-
{values:Type?} – Cardinality=0..1, optional
Feature File (almost similar steps)
具有非常相似步骤的功能文件如下 −
Feature − Payment Process
Scenario − Check Debit transactions
Given user is on "debit" screen
Scenario − Check Credit transactions
Given user is on "credit" screen
register_type 方法用于注册用户定义的类型,以便在匹配步骤时可以对其进行任何类型转换的解析。
Corresponding Step Implementation File
步骤实现文件如下 −
from behave import *
import parse
#define parse type
use_step_matcher("cfparse")
# for whitespace characters
@parse.with_pattern(r"x\s+")
def parse_string(s):
#type converter for "x" succeeded by single/multiple spaces
return s.strip()
#register user-defined datatype
register_type(x_=parse_string)
#optional part :x_? cardinality field in parse expression
@given('user is on {:x_?}{payment} screen')
def step_payment(context, x_, payment):
print("Payment type: ")
print(payment)
Output
运行功能文件后获得的输出如下,使用的命令是 behave --no-capture -f plain 。
输出显示 debit 和 credit 。这两个值通过特性文件中的几乎类似步骤来传递。在步骤实现中,我们在解析表达式的基数字段中解析了这两个步骤。
Behave - Multi-Methods
也许在功能文件中具有短语类似的步骤。例如,
Given user makes payment of 100 INR
And user makes payment of 10 Dollar
在这里,我们可以有不同的步骤定义来区分 INR 和美元。为此,我们可以使用多方法方法,必须对不同的数据类型使用不同的正则表达式。
Feature File (almost similar steps)
将功能文件视为如下内容:
Feature − Multi-Methods
Scenario − Purchase
Given User is on shop
When user purchases 3 shirts
And user purchases 4 pants
在步骤实现文件中, TypeBuilder.make_choice 函数为提供的选择评估正则表达式模式。register_type 方法用于注册用户自定义类型,该类型可以在步骤匹配时解析为任何类型转换。
此外,我们将传入参数:用 “{}” 括起来的自定义数据类型。
Corresponding Step Implementation File
步骤实现文件如下所示 −
from behave import *
from behave import register_type
from parse_type import TypeBuilder
parse_dress = TypeBuilder.make_choice(["shirts", "t-shirts"])
#register user-defined datatype
register_type(Dress=parse_dress)
parse_pant = TypeBuilder.make_choice(["pants", "gowns"])
#register user-defined datatype
register_type(Pant=parse_pant)
@given("User is on shop")
def step_user_shop(context):
pass
# multiple methods being used .
@when(u"user purchases {count:n} {d:Dress}")
def step_dress(context, count, d):
print("User purchased: ")
print(d)
print("Count is:")
print(count)
@when(u"user purchases {count:n} {p:Pant}")
def step_pant(context, count, p):
print("User purchased: ")
print(p)
print("Count is:")
print(count)
Output
运行功能文件后获得的输出如下,使用的命令是 behave --no-capture -f plain 。
输出显示购买项目及其数量。在功能文件中几乎使用类似的步骤(但不同的数据类型)传递了这两个值。在步骤实现中,我们使用多种方法来获取值。
Behave - Step Functions
步骤函数在 steps 目录中存在的 Python 文件中创建。该目录内的每个 Python 文件(具有 .py 扩展名)都会被导入以获得步骤的实现。
一旦特性文件被触发执行,实现文件就会被加载。步骤函数与步骤装饰器相关联。
步骤实现必须从导入开始,使用下面提到的命令 -
from behave import *
这将导入 Behave 中描述的多个装饰器,帮助我们找到步骤函数。给定、当、然后等装饰器接受一个字符串参数。
例如,考虑下面给出的代码 -
@given('user is on admin screen')
def step_impl(context):
pass
上述代码将与下面特性文件中的 Given 步骤匹配,如下所示 -
Feature − Admin Module
Scenario − Admin verification
Given user is on admin screen
特性文件中以且/但是开头的步骤被重命名为它们早期的步骤关键字。
例如,考虑下面给出的特性文件 -
Feature − Admin Module
Scenario − Admin verification
Given user is on admin screen
And user is on history screen
Then user should be able to see admin name
But user should not able to check history
且步骤将被重命名为给定步骤,而但是步骤将被重命名为早期的步骤关键字。所有这些都在内部处理。
如果连续有多个且/但是步骤,它们将继承非且或但是关键字的关键字。
具有步骤装饰器的步骤函数至少有一个参数。第一个参数称为上下文变量。其他参数来自步骤参数(如果需要)。
例如,根据步骤参数参考步骤函数。
@given('user is on admin screen')
def step_impl(context):
pass
Project Structure
功能的项目结构如下:
Behave - Step Parameters
我们可以在步骤名称中使用参数。这些参数可以通过正则表达式或默认解析器或扩展解析器在 use_step_matcher 方法的帮助下进行处理。
behave.use_step_matcher(name)
修改解析步骤文本时的参数匹配器。Behave 中存在多个内置解析器,如下所示 -
-
parse − 它提供了一个简单的解析器,该解析器使用纯语法恢复步骤参数的正则表达式。例如,{parameter: type}。它允许使用类型转换器进行类型转换。
-
cfparse − 它支持基数字段 (CF)。默认情况下,它会为连接基数生成缺失的类型转换器(如果给出了基数等于一的类型转换器)。它可以支持以下解析表达式 -{values:Type+} – Cardinality=1..N、many{values:Type*} – Cardinality=0..N、many0{values:Type?} – Cardinality=0..1,可选 它允许使用类型转换器进行类型转换。
-
re − 它利用完整的正则表达式来解析从句。我们必须借助命名组 (? P<name>…) 声明从文本中获取的变量,然后将其提供给步骤 ()。
我们借助 register_type 方法可以对自定义匹配器以及新数据类型进行注册。
class behave.matchers.Matcher(func, pattern ,step_type=None)
它从步骤名称中提取参数。
-
pattern − 与步骤函数关联的模式匹配。
-
func − 步骤函数与模式关联。
-
check_match(step) − 与提供的步骤名称匹配。
-
describe(schema=None) − 以函数或匹配器对象的文本形式给出描述。
-
regex_pattern: 产生所利用的文本正则表达式。
Behave - Runner Script
我们可以通过运行命令行参数来运行 Behave 测试,或者我们可以创建一个 runner 脚本。此脚本提供运行测试和生成相应报告的功能。
我们可以重新尝试并执行失败的测试。此外,在执行整个套件之前,runner 脚本能够进行应用程序编程接口 (API) 调用并确保 API 没有问题。
Steps for Runner Script
按照以下步骤在 Behave 中成功创建和执行 runner 脚本。
Step 1 − Create a runner script (runner.py) within the features folder.
以下屏幕将出现在您的计算机上:
Step 2 − Runner Script Implementation to run tests
runner 脚本可以通过使用以下代码来实现以运行测试:
import subprocess
if __name__ == '__main__':
#command line args along with error capture on failure with check true
s = subprocess.run('behave --no-capture',shell=True, check=True)
Step 3 − Execute the runner script
使用命令执行 runner.py 文件 python3 runner.py (如果 Python 版本是 3)。以下屏幕将出现在您的计算机上:
Step 4 − Parametrise runner script by passing command line arguments.
可以使用以下内容,作为 runner 脚本的实现来运行测试:
import argparse
import subprocess
if __name__ == '__main__':
p = argparse.ArgumentParser()
#--testdir command line argument added
p.add_argument('--testdir', required=False, help="File path")
a = p.parse_args()
testdir = a.testdir
#complete command
c= f'behave --no-capture {testdir}'
s = subprocess.run(c, shell=True, check=True)
Step 5 − Execute the runner script
使用命令 python3 runner.py --testdir=features 执行 runner.py 文件。
Behave - Exclude Tests
我们可以通过其文件名从执行中排除正在执行的文件。
假设我们具有 features 文件夹中有多个功能文件。可以在计算机上看到以下屏幕:
执行 behave 命令后,输出如下:
如果我们仅运行 Payment.feature 功能文件并排除 Payment1.feature ,我们必须传递命令行参数 --e 或 --exclude 后跟正则表达式的模式。
执行命令 behave --exclude *1.feature 后,输出如下:
输出显示 one feature passed 以及 Payment.feature 文件名。此外,Payment1.feature 不包含在运行中。
Behave - Retry Mechanism
我们可以在 Behave 中重新运行功能文件中的失败场景。这是在格式化程序的帮助下进行的。
所有可用于 Behave 的格式化程序可以使用以下命令查看:
behave –f help
使用命令后,您可以看到以下屏幕:
rerun 格式化程序用于捕获失败的场景,并将其输出到一个单独的文件中。让我们举一个例子,其中我们有 1 个失败的功能。
然后使用以下命令捕获另一个功能文件中的失败功能:
behave –f rerun –o failed_features.feature
您可以看到以下内容:
failed_features.feature 文件会在项目中生成。其中包含我们失败的功能文件名 Payment1.feature。
要仅重新触发失败的场景,我们必须运行如下所示的命令:
behave @failed_features.feature
您将看到以下屏幕:
Behave - Reports
报告生成是朝着测试自动化框架迈出的最重要的步骤之一。在执行结束时,我们无法依赖控制台输出,而是应该提供一份详细的报告。
它应包括通过、失败、跳过的测试数量、特性和场景细分信息。Behave 不会生成内置报告,但可以以多种格式输出,我们可以利用第三方工具生成报告。
使用命令显示 Behave 中所有可用格式化程序:
behave --format help
当您使用该命令时,您的电脑上将出现以下屏幕:
一些常见的 Behave 报告为:
-
Allure Report.
-
Output JSON Report.
-
JUnit Report
JUnit Report
让我们执行一个包含两个特性文件的测试,其测试结果如下:
上述测试的项目文件夹结构如下:
Step 1 − Execute the command
要创建一个 JUnit 报告,请运行下面给出的命令:
behave --junit
Step 2 − Report folder generation
将在项目中生成一个名为 reports 的文件夹,名称为 TESTS-<feature file name>.xml 。
此处,Payment 和 Payment1 是特性文件名称。
Step 3 − Report generation to a specific folder
要将报告生成到一个特定文件夹(比如 my_reports),我们需要运行下面提到的命令:
behave --junit --junit-directory my_reports
一个名为 my_reports 的文件夹将在项目中生成,其中包含该报告。
JSON Report
我们可以创建行为 JSON 报告。JSON 实际上是一种格式化器。
让我们执行一个包含两个特性文件的测试,其测试结果如下:
上述测试的项目文件夹结构如下−
Step 1 − Execute the command
要在控制台中创建 JSON 输出,运行命令−
behave -f json
将出现以下屏幕−
Step 2 − Output in readable format
要以更易读的格式创建 JSON 输出,运行以下命令−
behave -f json.pretty
以下是捕获在下图中一部分输出−
Step 3 − Report generation to a specific folder
要将报告生成到特定文件夹(例如 my_reports.json),我们必须运行以下命令−
behave –f json.pretty –o my_reports.json
下图表示将出现在您计算机上的屏幕。
一个名为 my_reports.json 的文件夹会在项目中生成,其中包含所有已执行特征的详细信息。
Allure Report
要在 Behave 中生成 Allure 报告,我们首先必须在系统中安装 Allure。如需从 Linux 命令行安装,依次运行以下命令−
sudo apt-add-repository ppa:qameta/allure
sudo apt-get update
sudo apt-get install allure
对于 Mac 用户,安装使用 Homebrew 完成,且使用以下命令−
brew install allure
对于 Windows,Allure 从 Scoop 安装程序安装。运行以下命令下载并安装 Scoop,最终在 PowerShell 中执行−
scoop install allure
要从 Scoop 更新 Allure 分发安装,从 Scoop 安装目录运行以下命令−
\bin\checkver.ps1 allure -u
最后,运行以下给出的命令−
scoop update allure
安装 Allure 后,我们必须为 Python 获取 Allure-Behave 集成插件。为此,运行以下命令−
pip install allure-behave
要验证是否已成功安装 Allure,请运行以下说明的命令−
allure
让我们执行一个包含两个特性文件的测试,其测试结果如下:
上述测试的项目文件夹结构如下−
Step 1 − Report generation to a specific folder
要将报告生成到特定文件夹(例如 my_allure),我们必须运行以下命令−
behave -f allure_behave.formatter:AllureFormatter –o my_allure
你会得到如下所示的屏幕——
一个名为 my_allure 的文件夹会在项目中生成,其中包含带有 .json 扩展名的文件。
Step 2 − Start the web server
要启动 Web 服务器,运行以下给出的命令:
allure serve my_allure
这里,my_ allure 是包含 allure JSON 文件的目录。
同时,打开一个浏览器,其中包含如下所示的 Allure 报告:
我们还可以点击各个 feature 并找到它们的分解,如下所示:
Behave - Hooks
Behave 设置和取消设置函数在名为 environment.py 的文件中实现,该文件位于包含 steps 文件夹的同一目录中。设置函数包括 - 浏览器打开、数据库连接、配置等。
取消设置函数包括浏览器关闭、数据库连接终止、还原更改等。
environment.py 文件包含以下函数:
-
before_feature(context,feature) - 在每个 feature 之前执行。
-
before_scenario(context,scenario) - 在每个 scenario 之前执行。
-
before_step(context,step) - 在每个 step 之前执行。
-
before_tag(context,tag) - 在每个 tag 之前执行。
-
before_all(context) - 在所有内容之前执行。
-
after_feature(context,feature) - 在每个 feature 之后执行。
-
after_scenario(context,scenario) - 在每个 scenario 之后执行。
-
after_step(context,step) - 在每个 step 之后执行。
-
after_tag(context,tag) - 在每个 tag 之后执行。
-
after_all(context) - 在所有内容之后执行。
上述函数被用作 Behave 中的挂钩。项目结构应如下所示:
Feature File with hooks (Payment.feature)
Payment.feature 带有钩子的功能文件如下所示 −
Feature − Payment Process
Scenario − Verify transactions
Given user makes a payment of 100 INR And user makes a payment of 10 Dollar
Feature File with hooks (Payment1.feature)
下面给出带有钩子的 Payment1.feature 的功能文件 −
Feature − Administration Process
Scenario − Verify admin transactions
Given user is on admin screen
Corresponding step Implementation File
步骤实现文件如下所示 −
from behave import *
from parse_type import TypeBuilder
parse_amt = TypeBuilder.make_choice(["100", "10"])
register_type(Amt=parse_amt)
parse_curr = TypeBuilder.make_choice(["INR", "Dollar"])
register_type(Curn=parse_curr)
@given("user makes a payment of {n:Amt} {t:Curn}")
def step_payment(context, n, t):
pass
@given('user is on admin screen')
def step_admin(context):
pass
Step 4 − Hooks in environment.py file
environment.py 文件中的钩子如下:
# before all
def before_all(context):
print('Before all executed')
# before every scenario
def before_scenario(scenario, context):
print('Before scenario executed')
# after every feature
def after_feature(scenario, context):
print('After feature executed')
# after all
def after_all(context):
print('After all executed')
Output
运行功能文件后获得的输出如下 −
Behave - Debugging
Behave 脚本可以通过预运行测试步骤进行调试。预运行有助于查看所有测试步骤,而无需实际运行它。它有助于确定步骤定义文件中的未定义步骤。
它验证是否有任何缺少的导入语句、语法错误等。所有这些问题都会通过预运行在很短的时间内被检测出来。如果我们在进行大量更新或任何配置更改,预运行有助于在短时间内检测到任何错误。
如果我们不得不运行整个套件进行调试,那将非常耗时。在 Behave 中,我们可以使用下面提到的命令通过预运行进行调试——
behave --no-capture --dry-run
你会得到如下所示的屏幕——
输出显示了 3 untested ,其中显示了测试步骤的数量。
让我们预运行具有未实现步骤的功能文件,如下所示——
输出明确定义了通过预运行在步骤定义文件中获得的未定义步骤。