genesis/behat-sql-extension

为Behat提供便捷的SQL/PDO扩展,允许动态创建测试数据

安装次数: 74,993

依赖项: 3

建议者: 0

安全: 0

星标: 10

关注者: 4

分支: 12

类型:behat-extension

8.5.1 2020-07-20 22:46 UTC

This package is not auto-updated.

Last update: 2024-09-10 17:20:56 UTC


README

通用库:为Behat提供对任何PDO支持数据库的简单数据操作。核心功能

  • 提供简单的数据库交互步骤定义。
  • 自动填充表中的必填字段,让您摆脱所需数据的束缚。
  • 维护所有查询的SQL历史,以便以后进行清理。
  • 提供API来替换字符串中的关键字,如URL,允许轻松导航到动态URL。
  • 提供从密钥存储中访问最后操作记录的整个记录的简便方法。
  • 提供高级集成的API。
  • 提供快速设置的高级查询内部解析。

您可以在features/test.feature文件中找到用法示例。

版本8的新功能

  • 自定义异常。

次要版本中的新功能

  • 1: 添加了ODBC支持。
  • 2: 添加了计数API调用。
  • 3: 读取表的所有列。开发改进。
  • 4: 能够注册外部数据库提供程序。

补丁修复

  • 1: 调整了LastInsertId获取,以正确与postgresql驱动程序一起工作。

安装

使用Composer要求

composer require "genesis/behat-sql-extension"

实例化

在您的FeatureContext类中实例化sql扩展。

use Genesis\SQLExtension\Context;

$databaseParams = [
    'engine' => 'mssql', // The database engine to use, mysql, mssql, pgsql.
    'schema' => 'dbo', // The database schema. Optional.
    'dbname' => 'MyDB', // The database name.
    'prefix' => 'dev_', // You can provide a database prefix which could be different based on the environment.
    'host' => '192.168.0.1', // The database host.
    'port' => '9876', // The database port.
    'username' => 'db_username', // The username for the database.
    'password' => 'db_password' // The password for the database.
];

$this->sqlContext = new Context\API(
    new Context\DBManager(
      new Context\DatabaseProviders\Factory(),
      $databaseParams
    ),
    new Context\SQLBuilder(),
    new Context\LocalKeyStore(),
    new Context\SQLHistory()
);

请注意,Context\SQLHistory参数是可选的,您可以将其省略。

设置

在Composer安装扩展后,您需要设置连接详细信息。这可以通过以下两种方式完成

###1. Behat.yml

除了常规mink-extension参数外,您还可以传递一个connection_details参数,如下所示

default:
    extensions:
        ...
        Genesis\SQLExtension\Extension:
          # Database connection details
          connection_details:
            engine: pgsql
            host: 127.0.0.1
            port: 3306
            schema: ...
            dbname: ...
            username: ...
            password: ...
            dbprefix: ...
          # Keywords to be used with the SQL extension steps
          keywords:
            ...
          notQuotableKeywords:
            ...
          # 1 for max debug, 2 dumps only SQL queries executed.
          debug: false

在上面的示例中,keywords部分提供了注入关键字。例如,您可以有

default:
    extensions:
        ...:
          ...
          keywords:
            qwerty: thisisthehashofthepassword

这将使qwerty关键字可用,如下所示

Given I have a "user" where "email:[email protected],password_hash:{qwerty}"

注意使用{qwerty}关键字。{qwerty}将被替换为thisisthehashofthepassword

notQuotableKeywords提供了一种指定在SQLContext生成SQL查询时不想用引号放入的MySQL函数的方法。这些预期是正则表达式,但没有分隔符。已设置的默认值如下

$keywords = [
  'true',
  'false',
  'null',
  'NOW\(\)',
  'COUNT\(.*\)',
  'MAX\(.*\)',
  'DATE\(.*\)',
  '\d+'
];

仅通过使用API添加非可引词,请使用以下行

$_SESSION['behat']['GenesisSqlExtension']['notQuotableKeywords'][] = 'YOUR-REGEX-GOES-HERE';

注意:对于SQLContext来说,schema是一个非常重要的参数,如果您正在使用多个数据库,请不要设置固定模式。要引用其他数据库中的表,只需按照sql约定在数据库名称前缀即可,它将为您在表中动态使用该模式。如果您正在应用程序中仅使用一个数据库,请将模式设置为与数据库相同。

启用严格异常

要启用在执行查询过程中抛出任何问题的异常,您可以在dbConnection上设置它,如下所示

$this->get('dbManager')->getConnection()->setAttribute(
  PDO::ATTR_ERRMODE,
  PDO::ERRMODE_EXCEPTION
);

注册自己的数据库提供程序类

如果提供的提供程序与您的引擎版本不兼容或不存在,您可以在调用之前注册自己的提供程序,如下所示

<?php

class FeatureContext
{
    public function __construct()
    {
        $this->sqlContext = ...;
        $this->sqlContext->get('dbManager')->getProviderFactory()->registerProvider(
          string $engine,
          string $providerClass
        );
    }
}

###2. 环境变量

可以通过以下方式设置数据库连接详细信息的环境变量

$ export BEHAT_ENV_PARAMS="DBENGINE:mysql;DBHOST:127.0.0.1;DBSCH..."

所需字段如下

DBENGINE
DBHOST
DBSCHEMA
DBNAME
DBUSER
DBPASSWORD

这些字段需要预先设置,但可以是空的。

本扩展提供的调用

在表中插入数据

这将使用提供的@where/@with数据执行插入查询

# file: insert.feature

# replace @table with your table name, include schema if table is stored in a schema
# @with/@where are used synonymously in this call
Given I have a "@table" where "@where"

要一次性插入多行,可以将上述语句重写如下

# file: insert.feature

Given I have "@table" where:
  | column1            | column2            |
  | row1-column1-value | row1-column2-value |
  | row2-column1-value | row2-column2-value |

上述操作将插入两行。

在表中删除数据

这将使用提供的@where/@with标准对数据库执行删除查询

# file: delete.feature

# @with/@where are used synonymously in this call
Given I do not have a "@table" where "@where"

在表中更新数据

此调用将在数据库记录上运行匹配@where子句的更新查询

# file: update.feature

# @table for this to make sense your table should represent an entity
# @update the field you would like to update e.g email:[email protected]
# @where this functions exactly the same as the sql where clause
# Format for @update and @where is "email:its.inevitable.com,id:1,isActive:true"
Given I have an existing "@table" with "@update" where "@where"

使用not运算符。

您可以使用not运算符来指定列不应等于某个值,如下所示

Then I should have a "user" with "email:[email protected], active: !null" in the database

这将生成active is not null。对于非null值,将生成column != value

可以写成如下形式

Then I should have a "user" with:
    | column | value                      |
    | email  | its.inevitable@hotmail.com |
    | active | !null                      |

注意最上面的行仅用于说明,它不会被用作查询的一部分。

执行LIKE搜索。

您可以使用以下格式执行LIKE子句

Then I should have a "user" with "user_agent:%Firefox%" in the database

大于或小于比较。

为了应用大于或小于比较

Then I should have a "user" with "dob:>2001-01-01" in the database

OR

Then I should have a "user" with "age:<18" in the database

注意:这些运算符仅适用于数字和日期格式(yyyy-mm-dd)。

重用其他记录的值

在创建或更新数据后,您可以使用以下子句将记录的值分配给关键字

# file: reuse.feature

# Create a new user.
Given I have a "user" where "email:[email protected]"

# The above command will create the record and also be aware of the data created. You can re-use this data in the following
# commands. To re-use, just use it like so "user.<column>". Remember any required fields that you may have not passed in data for
# explicitly will still be filled by the extension for you.
Given I have an "account" where "title:my account, user_id:{user.id}"

Given I have ...命令将为您做两件事

  • 如果不存在,尝试创建新记录。
  • 保存新记录的所有列以便在关键字存储中重用。这些可以通过如下方式访问:{表.列} 示例
    • 考虑一个具有以下列的user表
      • id
      • name
      • email
      • role_id
    • Given I have a "user" where "email: [email protected]"将给出以下关键字
      • {user.id}
      • {user.name}
      • {user.email}
      • {user.role_id}

引用外键表值

要使用来自另一个表的值,请使用以下语法

Then I should have a "table" where "column1:value1, column2:[table1.columnToUse|whereColumn:Value]"

将上述内容放入上下文中。

column1: value1 # Usual sql syntax.
column2: [table1.columnToUse|whereColumn:Value] # External reference to the table `table1`

上述语法即[...]将按如下方式解析

SELECT `table1.columnToUse` FROM `table1` WHERE `whereColumn` = 'Value';

验证数据库中的数据 - 已弃用

请通过测试您的应用程序而不是使用此扩展来验证数据库的行为。以下内容不推荐,除非在特殊情况之下。

按照以下方式验证数据库记录

Then I should have a "user" with "email:[email protected],status:1" in the database

注意:步骤定义中的'in the database'部分是可选的,仅用于步骤定义的清晰性。

调试模式

调试模式可用于将SQL查询和结果打印到屏幕上,以便快速调试。

# file: behat.yml

# Enable debug mode to check for errors
...
Genesis\SQLExtension\Extension:
    debug: true
    ...

上述"I have"命令将输出如下到屏幕

Executing SQL: INSERT INTO user (email) VALUES ('[email protected]')

Last ID fetched: 57

SQLContext API

扩展提供了一个与DSL语言相同功能的简单API。要为代码提供更多上下文,请使用以下

  $this
    ->select(string $table, array $where) # select a record, essentially perform a iHaveAnExistingWhere.
    ->insert(string $table, array $where) # Insert a new record if it does not exist, same as iHaveAWith
    ->update(string $table, array $update, array $where) # Update an existing record, same as iHaveAnExistingWithWhere
    ->delete(string $table, array $where) # Delete a record, same as iDontHaveAWhere
    ;

DSL所做的任何事情都将使用上述方法(即设置关键字、输出到调试日志等...)

为此扩展做出贡献

发现了一个bug?太好了,我想了解有关它的所有信息。请在此处记录问题链接,为了项目的热爱,或者只需打开一个PR,我很乐意批准。