magetest/magento-behat-extension

此包已被弃用且不再维护。未建议替代包。

Magento Behat 扩展

0.0.3 2012-10-09 21:48 UTC

README

Build Status Scrutinizer Code Quality

Magento 的 Behat 扩展,提供符合特定 Magento 需求的 Behat 上下文,允许您快速定义 Magento 场景和步骤,以在 Magento 项目中启用 BDD。

目标

  • 创建一个使测试变得简单易用的工具,以便测试 Magento 的外部行为。
  • 创建一个工具,当抛出异常时提供清晰的反馈。反馈应指导开发者如何解决问题,并且消息应正确地与 Magento 领域相符。

如何实现?

  • 此工具可以使用 composer 轻松安装。
  • 可以不创建新上下文即可完成标准场景的创建。
  • 不会抛出不提供如何进行或解决问题反馈的异常。
  • 文档包括如何使用工具每个功能的示例。

安装

先决条件

BehatMage 需要 PHP 5.3.x 或更高版本。

使用 composer 安装

对于本文档,我们假设目录布局如下。

project-dir
├── behat.yml
├── bin
│   └── behat
├── composer.json
├── composer.lock
├── features
│   ├── bootstrap
│   └── ...
├── htdocs
│   ├── app
│   ├── downloader
│   ├── index.php
│   ├── js
│   ├── skin
│   ├── var
│   └── ...
└── vendor
    ├── autoload.php
    ├── behat
    ├── magetest
    └── ...

我们假设您将保留您的 behat 功能声明,并将从您的项目目录(位于您的 Magento 基础目录之上)调用 behat 脚本。当然,任何其他布局也是可能的。只需注意以下调整即可

  • behat.yml 文件需要在与您调用 behat 脚本的目录中。
  • composer.json PSR-0 自动加载路径声明需要调整。
  • behat.yml 中默认.paths.features 设置需要调整。

首先,将 BehatMage 添加到您的 composer.json 中的依赖列表,并确保为自动加载注册一些路径

{
    "config": {
        "bin-dir": "bin"
    },
    "require": {
        "php": ">=5.3.0"
    },
    "require-dev": {
        "magetest/magento-behat-extension": "dev-develop"
    },
    "autoload": {
        "psr-0": {
            "": [
                "htdocs/app",
                "htdocs/app/code/local",
                "htdocs/app/code/community",
                "htdocs/app/code/core",
                "htdocs/lib"
            ]
        }
    },
    "minimum-stability": "dev"
}

然后只需使用 composer 安装它

$ composer install --dev --prefer-dist

您可以在其官方网站上了解更多关于 Composer 的信息。

基本用法

更改到您的项目目录,并在该目录中设置 behat

$ cd project
$ bin/behat --init

behat --init 将创建一个 features/ 目录,其中包含一些基本内容以帮助您入门。屏幕上的输出应类似于

$ bin/behat --init
+d features - place your *.feature files here
+d features/bootstrap - place bootstrap scripts and static files here
+f features/bootstrap/FeatureContext.php - place your feature related code here

定义您的功能

Behat 中的一切都始于您想要描述和实现的功能。在此示例中,功能将授予管理员用户管理评论可见性的能力,因此我们可以从创建 features/admin_user_manages_review_visibility.feature 文件开始

Feature: Admin User can manage review visibility
    So that our Customers are not influenced by a product with bad review history,
    as an Admin User
    I want to disable reviews of those specific products

每个特性都以相同的格式开始:一行命名特性,接着是三行分别描述收益、角色以及特性本身。虽然这一部分是必需的,但它的内容实际上对Behat或您最终的测试并不重要。然而,这一部分非常重要,以确保每个特性都能被一致地描述,并且易于他人阅读。

定义一个场景

接下来,将以下场景添加到features/admin_user_manages_review_visibility.feature文件的末尾

Scenario: Turn off reviews per product
    Given the following products exist:
        | sku      | name           | accepts_reviews |
        | Ottoman1 | Ottoman        | 1               |
    And "Ottoman1" has existing reviews
    When I turn reviews off for "Ottoman1" product
    Then no review should be displayed for "Ottoman1"

每个特性由一个或多个“场景”定义,这些场景解释了该特性在不同条件下应该如何行动。这部分将被转换成测试。每个场景总是遵循相同的基本格式

Scenario: Some description of the scenario
    Given [some context]
    When [some event]
    Then [outcome]

场景的每一部分 - 上下文、事件和结果 - 都可以通过添加And或But关键字进行扩展

Scenario: Some description of the scenario
    Given [some context]
        And [more context]
    When [some event]
        And [second event occurs]
    Then [outcome]
        And [another outcome]
        But [another outcome]

Then、And But或其他以每个句子开头的词语之间实际上没有区别。这些关键字都是可用的,以便使您的场景更自然、更易读。

执行Behat

您已经定义了特性和该特性的一个场景。您现在可以见证Behat的威力!尝试在您的项目目录内执行Behat

$ bin/behat

如果一切正常,您应该会看到类似以下的内容

Feature: Admin User can manage review visibility
  So that our Customers are not influenced by a product with bad review history,
  as an Admin User
  I want to disable reviews of those specific products

  Scenario: Turn off reviews per product              # features/reviews/admin_user_manages_review_visibility.feature:7
    Given the following products exist:
      | sku      | name    | accepts_reviews |
      | Ottoman1 | Ottoman | 1               |
    And "Ottoman1" has existing reviews
    When I turn reviews off for "Ottoman1" product
    Then no review should be displayed for "Ottoman1"

1 scenario (1 undefined)
4 steps (4 undefined)
0m1.836s

You can implement step definitions for undefined steps with these snippets:

    /**
     * @Given /^the following products exist:$/
     */
    public function theFollowingProductsExist(TableNode $table)
    {
        throw new PendingException();
    }

    /**
     * @Given /^"([^"]*)" has existing reviews$/
     */
    public function hasExistingReviews($arg1)
    {
        throw new PendingException();
    }

    /**
     * @When /^I turn reviews off for "([^"]*)" product$/
     */
    public function iTurnReviewsOffForProduct($arg1)
    {
        throw new PendingException();
    }

    /**
     * @Then /^no review should be displayed for "([^"]*)"$/
     */
    public function noReviewShouldBeDisplayedFor($arg1)
    {
        throw new PendingException();
    }

编写您的步骤定义

Behat会自动找到feature/admin_user_manages_review_visibility.feature文件,并尝试将其场景作为测试执行。然而,我们没有告诉Behat如何处理诸如“Given以下产品存在”之类的语句,这会导致错误。Behat通过将场景的每个语句与您定义的列表中的正则表达式“步骤”进行匹配来工作。换句话说,告诉Behat在看到“Given以下产品存在”时应该做什么是您的任务。幸运的是,Behat会打印出您可能需要创建该步骤定义的正则表达式

You can implement step definitions for undefined steps with these snippets:

    /**
     * @Given /^the following products exist:$/
     */
    public function theFollowingProductsExist(TableNode $table)
    {
        throw new PendingException();
    }

    /**
     * @Given /^"([^"]*)" has existing reviews$/
     */
    public function hasExistingReviews($arg1)
    {
        throw new PendingException();
    }

    /**
     * @When /^I turn reviews off for "([^"]*)" product$/
     */
    public function iTurnReviewsOffForProduct($arg1)
    {
        throw new PendingException();
    }

    /**
     * @Then /^no review should be displayed for "([^"]*)"$/
     */
    public function noReviewShouldBeDisplayedFor($arg1)
    {
        throw new PendingException();
    }

但是,Behat目前还没有意识到Magento域,它要求我们添加我们可能想要跳过的步骤定义,因为这些步骤具有重复性。然后我们必须通过使用其配置文件behat.yml让Behat意识到Magento,添加以下行

default:
  extensions:
    MageTest\MagentoExtension\Extension:
      base_url: "http://project.development.local"

  # The default is to have the features directory inside the project directory
  # If you want the features directory inside the Magento installation, set paths.features:
  #paths:
  #  features: htdocs/features

其中我们告诉Behat加载哪个扩展以及我们想要测试哪个商店。

到目前为止做得很好,我们现在必须告诉Behat我们想要为每个演员(在我们的例子中是管理员用户)使用特定的子上下文,以增加清晰度。为了做到这一点,我们必须更新features/bootstrap/FeatureContext.php文件,如下所示

<?php
# features/bootstrap/FeatureContext.php

use Behat\Behat\Context\ClosuredContextInterface,
    Behat\Behat\Context\TranslatedContextInterface,
    Behat\Behat\Context\BehatContext,
    Behat\Behat\Exception\PendingException;
use Behat\Gherkin\Node\PyStringNode,
    Behat\Gherkin\Node\TableNode;

//
// Require 3rd-party libraries here:
//
//   require_once 'PHPUnit/Autoload.php';
//   require_once 'PHPUnit/Framework/Assert/Functions.php';
//

/**
 * Features context.
 */
class FeatureContext extends BehatContext
{
    /**
     * Initializes context.
     * Every scenario gets it's own context object.
     *
     * @param array $parameters context parameters (set them up through behat.yml)
     */
    public function __construct(array $parameters)
    {
        // Initialize your context here
        $this->useContext('admin_user', new AdminUserContext($parameters));
    }
}

并创建这样的子上下文,作为扩展BehatMage提供的MagentoContext的PHP类

<?php
# features/bootstrap/AdminUserContext.php

use Behat\Behat\Exception\PendingException;
use Behat\Gherkin\Node\TableNode;
use MageTest\MagentoExtension\Context\MagentoContext;

class AdminUserContext extends MagentoContext
{

}

如果我们再次运行Behat,现在框架已经意识到Magento域,我们的输出应该不同,看起来像这样

Feature: Admin User can manage review visibility
  So that our Customers are not influenced by a product with bad review history,
  as an Admin User
  I want to disable reviews of those specific products

  Scenario: Turn off reviews per product              # features/reviews/admin_user_manages_review_visibility.feature:7
    Given the following products exist:               # AdminUserContext::theProductsExist()
      | sku      | name    | accepts_reviews |
      | Ottoman1 | Ottoman | 1               |
      accepts_reviews is not yet defined as an attribute of Product
    And "Ottoman1" has existing reviews
    When I turn reviews off for "Ottoman1" product
    Then no review should be displayed for "Ottoman1"

1 scenario (1 failed)
4 steps (3 undefined, 1 failed)
0m1.481s

You can implement step definitions for undefined steps with these snippets:

    /**
     * @Given /^"([^"]*)" has existing reviews$/
     */
    public function hasExistingReviews($arg1)
    {
        throw new PendingException();
    }

    /**
     * @When /^I turn reviews off for "([^"]*)" product$/
     */
    public function iTurnReviewsOffForProduct($arg1)
    {
        throw new PendingException();
    }

    /**
     * @Then /^no review should be displayed for "([^"]*)"$/
     */
    public function noReviewShouldBeDisplayedFor($arg1)
    {
        throw new PendingException();
    }

如您所见,添加以下片段的建议消失了

    /**
     * @Given /^the following products exist:$/
     */
    public function theFollowingProductsExist(TableNode $table)
    {
        throw new PendingException();
    }

这是因为BehatMage已经提供了所有那些通常需要和测试Magento行为所需的常见步骤的实现。所以现在让我们使用Behat的建议,并将以下内容添加到features/bootstrap/AdminUserContext.php文件中

<?php
# features/bootstrap/AdminUserContext.php

use Behat\Behat\Exception\PendingException;
use Behat\Gherkin\Node\TableNode;
use MageTest\MagentoExtension\Context\MagentoContext;

class AdminUserContext extends MagentoContext
{
    /**
     * @Given /^"([^"]*)" has existing reviews$/
     */
    public function hasExistingReviews($arg1)
    {
        throw new PendingException();
    }

    /**
     * @When /^I turn reviews off for "([^"]*)" product$/
     */
    public function iTurnReviewsOffForProduct($arg1)
    {
        throw new PendingException();
    }

    /**
     * @Then /^no review should be displayed for "([^"]*)"$/
     */
    public function noReviewShouldBeDisplayedFor($arg1)
    {
        throw new PendingException();
    }
}

或者使用以下命令行选项让Behat为我们执行

$ bin/behat --append-to=AdminUserContext

太好了!现在您已经定义了所有步骤并告诉了Behat要使用哪个上下文,再次运行Behat

$ bin/behat

如果一切正常,您应该会看到类似以下的内容

Feature: Admin User can manage review visibility
  So that our Customers are not influenced by a product with bad review history,
  as an Admin User
  I want to disable reviews of those specific products

  Scenario: Turn off reviews per product              # features/reviews/admin_user_manages_review_visibility
    Given the following products exist:               # AdminUserContext::theProductsExist()
      | sku      | name    | accepts_reviews |
      | Ottoman1 | Ottoman | 1               |
      accepts_reviews is not yet defined as an attribute of Product
    And "Ottoman1" has existing reviews               # AdminUserContext::hasExistingReviews()
    When I turn reviews off for "Ottoman1" product    # AdminUserContext::iTurnReviewsOffForProduct()
    Then no review should be displayed for "Ottoman1" # AdminUserContext::noReviewShouldBeDisplayedFor()## Some more about Behat basics

如您所见,由于BehatMage扩展,Behat向开发者提供了关于下一步实施所需行为的意义和有用的信息。所以让我们添加必要的代码来让我们的步骤通过第一个要求。根据建议的代码创建以下文件

<?xml version="1.0"?>
<!-- app/code/local/BehatMage/Catalog/etc/config.xml -->
<config>
    <modules>
        <BehatMage_Catalog>
            <version>0.1.0</version>
            <depends>
                <Mage_Catalog />
            </depends>
        </BehatMage_Catalog>
    </modules>
    <global>
        <resources>
            <behatmage_catalog_setup>
                <setup>
                    <module>BehatMage_Catalog</module>
                    <class>Mage_Catalog_Model_Resource_Setup</class>
                </setup>
            </behatmage_catalog_setup>
        </resources>
    </global>
</config>
<?xml version="1.0"?>
<!-- app/etc/modules/BehatMage_Catalog.xml -->
<config>
    <modules>
        <BehatMage_Catalog>
            <active>true</active>
            <codePool>local</codePool>
            <depends>
                <Mage_Catalog />
            </depends>
        </BehatMage_Catalog>
    </modules>
</config>
<?php
# app/code/local/BehatMage/Catalog/data/behatmage_catalog_setup/data-install-0.1.0.php

/** @var Mage_Catalog_Model_Resource_Setup $this */
$installer = $this;

$installer->startSetup();

$installer->addAttribute('catalog_product', 'accepts_reviews', array(
    'group' => 'General',
    'input' => 'boolean',
    'type' => 'int',
    'label' => 'Accept Reviews',
    'default' => true,
    'user_defined' => true,
    'visible_on_front' => true,
    'visible_in_advanced_search' => false,
    'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
));

$installer->endSetup();

一旦文件创建完成,请清除Magento缓存以运行设置脚本并添加所需的属性。现在该运行Behat了。

$ bin/behat

如果一切顺利,您的输出应该像这样:

Feature: Admin User can manage review visibility
  So that our Customers are not influenced by a product with bad review history,
  as an Admin User
  I want to disable reviews of those specific products

  Scenario: Turn off reviews per product              # features/reviews/admin_user_manages_review_visibility.feature:7
    Given the following products exist:               # AdminUserContext::theProductsExist()
      | sku      | name    | accepts_reviews |
      | Ottoman1 | Ottoman | 1               |
    And "Ottoman1" has existing reviews               # AdminUserContext::hasExistingReviews()
      TODO: write pending definition
    When I turn reviews off for "Ottoman1" product    # AdminUserContext::iTurnReviewsOffForProduct()
    Then no review should be displayed for "Ottoman1" # AdminUserContext::noReviewShouldBeDisplayedFor()

1 scenario (1 pending)
4 steps (1 passed, 2 skipped, 1 pending)
0m6.478s

正如您所看到的,由于我们的产品定义中已包含所需的属性,Behat已进入场景的下一步。正如您所想象的,现在只需逐步实现所有所需的测试和代码,以符合之前定义的场景。

关于功能更多信息

关于步骤更多信息

上下文类:MagentoContext

BehatMage命令行工具

接下来是什么?

问题提交

在您提交新问题之前,请确保您已阅读问题提交指南

贡献

查看贡献文档

许可和作者

作者:[https://github.com/MageTest/BehatMage/contributors](https://github.com/MageTest/BehatMage/contributors)

版权(C)2012-2013

以下条件下,免费向任何获得此软件及其相关文档副本(“软件”)的个人授予使用、复制、修改、合并、发布、分发、再许可和/或销售软件副本的许可,并允许向提供软件的个人使用本软件,但受以下条件约束:

上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。

软件按“原样”提供,不提供任何明示或暗示的保证,包括但不限于适销性、适用于特定目的和无侵权性的保证。在任何情况下,作者或版权持有人不对任何索赔、损害或其他责任(无论基于合同、侵权或其他原因)承担责任,即使作者或版权持有人已被告知该软件或其使用可能导致的损害。