我可以将步骤定义放在一个不是 "steps" 的文件夹中吗?

Can I put step definitions in a folder which is not "steps" with behave?

我正尝试在 Python 上使用 Behave。 我想知道是否有办法将我的 .py 文件放在其他地方,而不是被迫将它们全部放在 "steps" 文件夹中。我当前的结构如下所示

tests/
    features/
    steps/ #all code inside here, for now

我想完成的是

tests/
    features/ #with all the .feature files
    login/ #with all the .py files for logging in inside a service
    models/ #with all the .py files that represents a given object
    and so on

我在 Behave 之前使用的唯一 BDD 框架是带有 Java 的 Cucumber,它允许在我想要的任何地方插入步骤定义(其余由 Cucumber 本身处理)。 我问这个是因为我想在我的项目中有很多 类 以便更好地组织我的代码。

首先,来自 behave 文档(版本 1.2.7.dev0):

behave works with three types of files:

  1. feature files written by your Business Analyst / Sponsor / whoever with your behaviour scenarios in it, and
  2. a “steps” directory with Python step implementations for the scenarios.
  3. optionally some environmental controls (code to run before and after steps, scenarios, features or the whole shooting match).

因此需要 steps/ 目录。

为了实现类似于您所想的解决方法,我尝试在 /steps 目录中创建一个子目录:/steps/deeper/ 并在其中插入我的 Python 文件:/steps/deeper/testing.py. 运行 执行后,我收到“NotImplementedError”,这意味着未找到 /deeper/testing.py 中的步骤定义。

似乎 behave 不会在 steps/ 目录的子目录中递归搜索任何其他 Python 文件。

至于你想做什么,我认为这是一个不错的组织想法,但由于它不可行,你可以这样做:而不是 directories Python 文件在您的 tests/ 目录中,为什么不为您的 Python 文件制定一个良好的命名约定并将相关函数分隔到它们自己的 Python 文件中呢?即:

tests/
    features/
    steps/
        login_prompt.py # contains all the functions for logging in inside a service
        login_ssh.py # contains all the functions for SSH login
        models_default.py # contains all the functions for the default object
        models_custom.py # contains all the functions for a custom object
        and so on...

当然,在这一点上,将它们分成不同的 Python 文件并不重要,因为 Behave 会搜索 steps/ 中的所有 Python 文件调用,但为了组织起见,它实现了同样的效果。

这可能有点晚,但您可以执行以下操作:

结构如下:

tests/
    features/
        steps/
            login
            main_menu
            all_steps.py

在步骤的子文件夹中,您可以创建带有实现的 _steps.py 文件,然后在所有 _steps.py(或您想要的命名方式)中,您只需要导入它们:

from tests.steps.login.<feature>_step import *
from tests.steps.main_menu.<feature>_step import *
etc

并且当您 运行 执行此操作时,它应该会找到步骤文件。或者,您可以将文件放在项目的任何位置,只要您有 1 个步骤文件夹并且文件中有一个文件是您导入所有步骤

您可以使用其他方法来完成,如下所示:

def import_steps_from_subdirs(dir_path):
    for directory in walk(dir_path):
        current_directory = directory[0] + '/'

        all_modules = [module_info[1] for module_info in iter_modules(path=[current_directory])]

        current_directory = current_directory.replace(Resources.BASE_DIR + '/', '')

        for module in all_modules:
            import_module(current_directory.replace('/', '.') + module)

然后在before_all层调用这个方法