【问题标题】:Is there a way to programmatically supply variables to behat features?有没有办法以编程方式提供变量来表现特征?
【发布时间】:2015-12-01 17:36:20
【问题描述】:

我想用 behat 彻底测试一组页面。

例如,这个场景大纲:

Scenario Outline:
  Given I am at <path>
  When I click some button
  Then I should see <hidden-stuff>
  | path  | hidden-stuff |
  | path1 | element1     |
  | path1 | element2     |
  | path1 | element3     |
  | path2 | element1     |
  | path2 | element2     |
  | path2 | element3     |
  | path3 | element1     |
  | path3 | element2     |
  | path3 | element3     |
  ...

在我的具体情况下,我有超过 10 个示例和 50 条路径,因此您可以看到这变得非常笨拙。我试图避免 500 行的不可维护功能,每次添加新路径或更多元素时都需要对其进行编辑。

我可以将 mysql 查询的结果输入 "" 参数吗?

或者在命令行或通过环境提供“路径”?

有没有更好的方法来解决这个问题?

编辑:我确实找到了this post,它基本上将所有逻辑从 .feature 文件 (Gherkin) 中提取到 FeatureContext (PHP) 中。但这似乎不是一种对利益相关者友好的行为方式。这真的是最好/唯一的方法吗?

【问题讨论】:

    标签: php unit-testing behat acceptance-testing


    【解决方案1】:

    这对你来说几乎是一个复制+粘贴的工作。我为您编写了一个自定义步骤定义Given the page contents are correct。我还添加了一个 Scenario Outline 作为经典示例,因此它们都执行相同的操作,但您感兴趣的是自定义步骤定义之一。

    小黄瓜

    Feature: Just testing
    
      Scenario Outline: Multiple generic visits
        Given I am on "<page>"
        Then I should see "<content>"
        Examples:
        | page              | content   |
        | /                 | HOME PAGE |
        | /login            | Username  |
        | /profile/step_one | Name      |
    
      Scenario: Multiple dynamic visits
        Given the page contents are correct
    

    结果

    FEATURECONTEXT

    您只需要使用getPageAndContent() 来查询数据库以返回您想要的内容。现在我只是在$pageAndContent 中硬编码了几个示例。

    namespace Application\FrontendBundle\Features\Context;
    
    use Behat\MinkExtension\Context\MinkContext;
    use Behat\Symfony2Extension\Context\KernelAwareContext;
    use Doctrine\ORM\EntityManager;
    use Doctrine\ORM\EntityRepository;
    use Symfony\Component\HttpKernel\KernelInterface;
    use Exception;
    use LogicException;
    
    class FeatureContext extends MinkContext implements KernelAwareContext
    {
        /* @var KernelInterface */
        private $kernel;
    
        public function setKernel(KernelInterface $kernelInterface)
        {
            $this->kernel = $kernelInterface;
        }
    
        /**
         * @Given /^the page contents are correct$/
         */
        public function thePageContentsAreCorrect()
        {
            $pageAndContent = $this->getPageAndContent();
    
            foreach ($pageAndContent as $page => $content) {
                try {
                    $this->visitPath($page);
                } catch (Exception $e) {
                    throw new LogicException(sprintf('The page "%s" does not exist.', $page));
                }
    
                try {
                    $this->assertSession()->pageTextContains($this->fixStepArgument($content));
                } catch (Exception $e) {
                    throw new LogicException(sprintf('The page "%s" does not contain "%s".', $page, $content));
                }
            }
        }
    
        /**
         * @return array
         */
        private function getPageAndContent()
        {
            /*
            $em = $this->getEntityManager();
            $repo = $this->getRepository($em, 'ApplicationFrontendBundle:Pages');
    
            $pageAndContent = [];
            $pages = $repo->findAll();
            foreach ($pages as $page) {
                // Build you array here
                $pageAndContent[$page->getUrl] = $page->getContent();
            }
    
            return $pageAndContent;
            */
    
            return [
                '/' => 'HOME PAGE',
                '/login' > 'Username',
                '/profile/step_one' => 'Name'
            ];
        }
    
        /**
         * @return EntityManager
         */
        private function getEntityManager()
        {
            return $this->kernel->getContainer()->get('doctrine')->getManager();
        }
    
        /**
         * @param EntityManager $entityManager
         * @param string        $serviceName
         *
         * @return EntityRepository
         */
        private function getRepository(EntityManager $entityManager, $serviceName)
        {
            return $entityManager->getRepository($serviceName);
        }
    }
    

    【讨论】:

    • 似乎你在暗示,正如我所担心的那样,纯粹在 Gherkin 功能中没有办法做到这一点。例如以对利益相关者友好的方式。
    • Gherkin 步骤是有限的,所以在极端情况下,我们必须编写自己的步骤定义,您的情况就是其中之一。如果我给你看我的一个 Context 文件,你可能会哭!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-09
    • 2010-10-11
    • 2013-04-02
    • 2021-08-28
    • 1970-01-01
    • 1970-01-01
    • 2017-01-09
    相关资源
    最近更新 更多