用户故事结构[例如BDD]

时间:2016-03-09 09:54:17

标签: php symfony bdd behat user-stories

我目前正在考虑如何构建最佳用户故事,就我而言,当我使用BDD方法时 - 在开发人员的开头编写用户故事。

我们假设我们有以下"新功能":注册和帐户设置。在系统中,匿名,经过身份验证(登录其帐户的普通用户)和管理员用户(高级用户)作为角色。

匿名用户是唯一允许注册但不允许使用设置功能的用户,经过身份验证的用户可以更新其设置,管理员可以更新其设置和其他内容,但两者都无法注册(再次注册) )。

构建功能的最佳方法是什么 - 可能由不同角色使用但不是全部以不同方式使用 - 或者只能由bdd用户故事中的一个角色使用的功能?

2 个答案:

答案 0 :(得分:1)

我相信你所寻找的是一个场景大纲。

你似乎想要实现这样的目标:

@javascript
Feature: When I am not logged in, I should not be able to access certain pages within the site

Rules:
- Logged in users should be able to see pages that users not logged in should not.
- Logged in users should not be able to follow a link to the registrations screen

Scenario Outline: Following links to the registrations screen.
Given I go to "<urlwithlink>"
And I click on "<link>"
And wait "(Insert time to wait for page to load here)"
Then the url should match "(Insert registrationsPage)"

Examples:
|urlwithlink|link|
(Put some examples here)

Scenario Outline: When I am logged in, I should not be able to follow those links
Given I am logged in as a user
And I go to "<urlwithlink>"
Then I should not see "<link>"

Examples:
|urlwithlink|link|
(Insert same examples as above)

Scenario: When I am not logged in, I should not be able to access the settings screen
Given I go to "(Insert where link to settings is, here)"
And the "(link to settings)" should be disabled (or use I should not see an "(link to settings)" element)

Scenario: When I am logged in, I should be able to access the settings screen
Given I am logged in as a user
And I go to "(Insert where link to settings is here)"
Then the "(link to settings)" should not be disabled (or use I should see an "(link to settings)" element)

如果您想要上下文的额外步骤:

 /**
 * @Then /^(?:|I )click (?:on |)(?:|the )"([^"]*)"(?:|.*)$/
 */
public
function iClickOn($arg1)
{
    $findName = $this->getSession()->getPage()->find("css", $arg1);
    if (!$findName) {
        throw new Exception($arg1 . " could not be found");
    } else {
        $findName->click();
    }
}

/**
 * Simply wait the period of time.
 *
 * @Given /^(?:I |)(?:wait|pause for|take a break for) "([^"]*)"(?:|.*)/
 * @param int $milliseconds
 *
 */
public
function wait($milliseconds)
{
    $this->getSession()->wait($milliseconds);
}

/**
 * @Then /^(?:|the |an? )"([^"]*)" (?:|element )(?:is|should)(?P<negate>(?:n\'t| not)?) (?:|be )disabled$/
 *
 * @param string $elementCSS
 * @param string $negate
 *
 * @throws Exception
 */
public function theElementShouldBeDisabled($elementCSS, $negate)
{
    {
        $page = $this->getSession()->getPage();
        $element = $page->find("css", $elementCSS);
        if (!$element) {
            throw new Exception($elementCSS . ' does not exist');
        }
        $attributeValue = $element->getAttribute("disabled");

        if (is_numeric(strpos($negate, ' not')) || is_numeric(strpos($negate, 'n\'t'))) {
            if ($attributeValue) {
                if (is_numeric(strpos($attributeValue, "disabled"))) {
                    throw new Exception('The element ' . $elementCSS . ' is disabled');
                }
            }
        } else {
            if (!$attributeValue) {
                throw new Exception($elementCSS . ' does not have a disabled attribute');
            } else if (!is_numeric(strpos($attributeValue, "disabled"))) {
                throw new Exception('The element ' . $elementCSS . ' is not disabled');
            }
        }
    }
}

那应该这样做,我希望这有帮助。

如果要以不同的方式构建设置,可能需要将设置和链接拆分为两个不同的文件

答案 1 :(得分:1)

1)&#34;作为[角色]&#34;不是关于访问角色,而是谁需要该功能。大多数情况下,它是一些需要功能的利益相关者,这样公司才能从中受益并做得更好。

2)应在同一个功能文件中通过更多场景描述不同的访问。但是,所有访问角色对于解释该功能并不重要。尽管Gherkin背后的工具可以测试,但Gherkin的功能和场景更多的是捕捉它们背后的想法,而不是涵盖所有可能的场景。选择1个正面场景来覆盖每个功能,剩下的就是降低测试级别,主要是单元测试。

尽量记住测试金字塔,其中验收测试只占所有测试的一小部分。