srathbone/behat-sql-extension

为Behat提供实时创建固定数据的SQL/PDO扩展

安装: 8

依赖项: 0

建议者: 0

安全: 0

星标: 0

关注者: 1

分支: 12

类型:behat-extension

8.5.1 2020-07-20 22:46 UTC

This package is not auto-updated.

Last update: 2024-09-15 03:24:09 UTC


README

通用库:为Behat提供任何PDO启用数据库的简单数据处理。核心功能

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

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

版本8的新功能

  • 自定义异常。

次要版本新功能

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

修补程序修复

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

安装

使用Composer require

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:its.inevitable@hotmail.com,password_hash:{qwerty}"

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

'notQuotableKeywords'提供了一种指定在生成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:someone@somewhere.com
# @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:its.inevitable@hotmail.com, 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

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:its.inevitable@hotmail.com"

# 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 ...命令将为您做两件事

  • 如果不存在,尝试创建新记录。
  • 将新记录的所有列保存起来,以便在关键字存储中重复使用。这些可以通过如下方式访问:{table.column} 示例
    • 考虑一个具有以下列的user表
      • id
      • name
      • email
      • role_id
    • Given I have a "user" where "email: its.inevitable@hotmail.com"将为您提供以下关键字
      • {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:its.inevitable@hotmail.com,status:1" in the database

注意:步骤定义中的“在数据库中”部分是可选的,仅用于澄清步骤定义。

调试模式

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

# file: behat.yml

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

上述“我有一个”命令将在屏幕上输出类似以下内容

Executing SQL: INSERT INTO user (email) VALUES ('its.inevitable@hotmail.com')

Last ID fetched: 57

SQLContext API

该扩展提供了一个易于使用的API,用于实现与DSL语言相同的功能。为了给代码提供更多上下文,请使用以下

  $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执行的所有操作都将使用上述方法(例如设置关键字、输出到调试日志等)

为这个扩展做贡献

发现了一个错误?太好了,我想了解所有相关信息。请在此处记录问题链接,或者只是打开一个PR,我会很高兴批准。