Behat 默认在名为的文件中查找步骤定义FeatureContext
(一个文件中的所有步骤)。
有很多步骤,很难维护这么大的文件。
我希望每个功能文件都有一个定义文件。
如何在外部文件中有步骤定义?
例如
homepage.feature
HomepageContext extends FeatureContext
Behat 有多个选项供您将 FeatureContext 拆分为多个类。首先,您可以使用老式的 php5 继承。如果继承不是您想要的,Behat 还支持子上下文:“使用子上下文”。
接下来,如果您想以不同于 的方式命名您的类FeatureContext
,您可以在配置文件的“上下文配置”部分重新定义它。behat.yml
这样,您可以将通用定义和挂钩拆分为单独的类,并在其他功能套件中使用它们以及子上下文或继承。
但你的问题也问:
我希望每个功能文件都有一个定义文件。
这个要求是完全错误的。Behat and Scenario BDD 就是用业务术语描述您的应用程序行为并为描述的行为创建测试字典。牢记这一点,从逻辑上讲,一个功能集不能有多个不同的字典。通过编写步骤定义,您可以告诉 Behat 这Given I am on "/news"
意味着什么。当您希望该步骤在功能之间具有不同的含义时-您做错了。
Behat 由 2 个主要且足够独立的概念组成:
*.feature
文件,用 Gherkin 语言编写。这些文件应该是自我描述的。意味着,他们应该为读者提供所有信息以便理解它们。Gherkin 不是用于您的功能测试的新编程语言,它只是您的用户故事的降价!FeatureContext.php
类,描述 Behat 应该如何测试你的特性。它定义了与整个应用程序功能套件一起使用的应用程序范围的字典。这是您的降价类用户故事和实际功能测试之间的编程桥梁。你不应该把这件事搞砸。单一功能套件应该有单步骤字典(定义)。但是由于继承和子上下文,您可以在多个功能套件中使用单个字典。是的,您可以将单个套件字典拆分为多个 php 类;-)
使用类继承和单独的上下文。
# /features/contexts/
AbstractContext extends BehatContext {}
FeaturenameContext extends AbstractContext {}
然后在/feature/FeatureContext.php
导入上下文文件:
/**
* Initializes context.
* Every scenario gets it's own context object.
*
* @param array $parameters context parameters (set up via behat.yml)
*/
public function __construct(array $parameters) {
// import all context classes from context directory, except the abstract one
$filesToSkip = array('AbstractContext.php');
$path = dirname(__FILE__) . '/../contexts/';
$it = new RecursiveDirectoryIterator($path);
/** @var $file SplFileInfo */
foreach ($it as $file) {
if (!$file->isDir()) {
$name = $file->getFilename();
if (!in_array($name, $filesToSkip)) {
$class = pathinfo($name, PATHINFO_FILENAME);
require_once dirname(__FILE__) . '/../context/' . $name;
$this->useContext($class, new $class($parameters));
}
}
}
}
一种解决方案是子上下文的水平可重用性。为每个“功能组”使用一个子上下文。
class FeatureContext extends BehatContext
{
public function __construct(array $context_parameters)
{
$this->useContext('math_context', new MathContext());
$this->useContext('bash_context', new BashContext());
}
}