问题:优化behat测试套件

我有一个包含 20 个功能文件的测试套件,并且正在执行 100% 的 MySQL CRUD 操作。大约需要 5 分钟才能完成。如果我手动进行测试,最多需要 7 分钟。我需要知道的是,为了优化整个过程,我需要做什么?

注意:Behat 3 不支持 ParallelRunnder,所以它现在超出了范围!

如果您要建议使用 Behat 3,那么请帮助我修改我的 composer.json 和 behat.yml 文件,因为当我自己这样做并运行 bin/behat 时,我会收到如下错误:

`Behat\Symfony2Extension\Extension` extension file or class could not be located.
`Behat\MinkExtension\Extension` extension file or class could not be located. 
Unrecognized options "mink_driver" under "testwork.symfony2"
Unrecognized options "context, paths" under "testwork" 

正如您在下面看到的,我使用某些版本的数字,没有星号。

当前作曲家.json:

"require": {
    "php": ">=5.3.3",
    "symfony/symfony": "2.5.4",
    "doctrine/orm": "~2.2,>=2.2.3",
    "doctrine/doctrine-bundle": "~1.2",
    "twig/extensions": "~1.0",
    "symfony/assetic-bundle": "~2.3",
    "symfony/swiftmailer-bundle": "~2.3",
    "symfony/monolog-bundle": "~2.4",
    "sensio/distribution-bundle": "~3.0",
    "sensio/framework-extra-bundle": "~3.0",
    "incenteev/composer-parameter-handler": "~2.0",
    "behat/behat": "2.5.3",
    "behat/behat-bundle": "1.0.0",
    "behat/symfony2-extension": "1.1.2",
    "behat/mink": "1.5.0",
    "behat/mink-extension": "~1.3",
    "behat/mink-selenium2-driver": "1.1.1",
    "behat/mink-goutte-driver": "1.0.9"
},

当前 behat.yml:

default:
    context:
        class: FeatureContext
        parameters:
            output_path: %behat.paths.base%/build/behat/output/
            screen_shot_path: %behat.paths.base%/build/behat/screenshot/
    extensions:
        Behat\Symfony2Extension\Extension:
            mink_driver: true
            kernel:
                env: test
                debug: true
        Behat\MinkExtension\Extension:
            base_url: 'http://symfony.local/app_test.php/'
            files_path: %behat.paths.base%/build/dummy/
            javascript_session: selenium2
            browser_name: firefox
            goutte: ~
            selenium2: ~
    paths:
        features: %behat.paths.base%/src
        bootstrap: %behat.paths.features%/Context

编辑:

我有 20 个功能文件和一个场景。对于 CRUD 操作:

  • 我在每个场景中都运行了登录方法。查询针对数据库运行。

  • 有些场景做INSERT,有些做UPDATE,有些做DELETE。

  • 我用pdo_mysql作为database_driver

我的 FeatureContext 文件的一部分:

namespace Site\CommonBundle\Features\Context;

use Behat\MinkExtension\Context\MinkContext;
use Behat\Mink\Exception\UnsupportedDriverActionException;
use Behat\Mink\Driver\Selenium2Driver;
use Behat\Symfony2Extension\Context\KernelAwareInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Process\Process;

/**
 * Class FeatureContext
 *
 * Parent to other FeatureContext files. It is used to avoid duplicated codes and all the
 * shared commons are kept here.
 *
 * @package Site\CommonBundle\Features
 */
class FeatureContext extends MinkContext implements KernelAwareInterface
{
    protected $kernel;
    protected $screenShotPath;
    protected $outputPath;

    /**
     * Parameter $parameters comes from behat.yml file.
     * @param array $parameters
     */
    public function __construct(array $parameters)
    {
        $this->outputPath = $parameters['output_path'];
        $this->screenShotPath = $parameters['screen_shot_path'];
    }

    /**
     * Helps to use doctrine and entity manager.
     * @param KernelInterface $kernelInterface Interface for getting Kernel.
     */
    public function setKernel(KernelInterface $kernelInterface)
    {
        $this->kernel = $kernelInterface;
    }

    /**
     * Without this, PhantomJs will fail if responsive design is in use.
     * @BeforeStep
     */
    public function resizeWindow()
    {
        $this->getSession()->resizeWindow(1440, 900, 'current');
    }

    /**
     * Take screen-shot when step fails. Works only with Selenium2Driver.
     *
     * @AfterStep
     * @param $event Current event.
     * @throws \Behat\Mink\Exception\UnsupportedDriverActionException
     */
    public function takeScreenshotAfterFailedStep($event)
    {
        if (4 === $event->getResult()) {
            $driver = $this->getSession()->getDriver();

            if (! ($driver instanceof Selenium2Driver)) {
                throw new UnsupportedDriverActionException(
                    'Taking screen-shots is not supported by %s, use Selenium2Driver instead.',
                    $driver
                );

                return;
            }

            if (! is_dir($this->screenShotPath)) {
                mkdir($this->screenShotPath, 0777, true);
            }

            $filename = sprintf(
                '%s_%s_%s.%s',
                $this->getMinkParameter('browser_name'),
                date('Ymd') . '-' . date('His'),
                uniqid('', true),
                'png'
            );

            file_put_contents($this->screenShotPath . '/' . $filename, $driver->getScreenshot());
        }
    }

    /**
     * @When /^I login as "([^"]*)"$/
     * @param $type User role type.
     */
    public function iLoginAs($type)
    {
        $container = $this->kernel->getContainer();
        $userData = $container->getParameter('dummy_user');

        $this->visit('/login');
        $this->fillField('username', $userData[$type]['username']);
        $this->fillField('password', $userData[$type]['password']);
        $this->pressButton('_submit');
    }
    .........
}

解答

我不知道为什么我认为运行需要 20 分钟,这可能与功能的数量相混淆。 5分钟一点也不差。您可以做一些基本的事情来帮助加快速度。

1.@BeforeStep中的逻辑——你可能可以将它移动到@BeforeScenario甚至到@BeforeFeature甚至到@BeforeSuite中——没有必要经常这样做。

2.很明显,但以防万一:Goutte驱动比其他驱动快得惊人,缺点是它不支持JS,你不能截图。但我认为 Symfony 应用程序不涉及太多 JS 来执行 CRUD 操作。因此,请仔细检查不涉及 JS 的所有内容并将其与 Goutte 一起使用。

3.iLoginAs大概每一步都会用到。您可以通过手动创建用户会话并将 cookie 设置为标头来将其更新得更快,即,您的身份验证方法中的相同逻辑进入步骤定义,然后您只需执行$this->getSession()->getDriver()->setCookie(session_name(), session_id());- 在下一次请求您的用户时已通过身份验证。

4.browser_name: firefox- 上帝不......使用chrome,它必须更快。

  1. 使用 HHVM 运行 Behat 测试(该应用程序仍然使用旧的好 PHP)将大大提高性能。安装它可能会很痛苦,尤其是在 Mac 上。

  2. 最后,迁移到 Behat 3,这应该不会很痛苦。他们从 2.x 中汲取了大量知识,并用它来改进它,包括性能方面。它在配置上也更加灵活,允许多个上下文以使事情更好地组织和清洁。

Logo

更多推荐