QC Analytics

Blog

Blog
Importing behave python steps from subdirectories

Importing behave python steps from subdirectories


The problem

While using the python behave 1.2.7, you may soon end up with multiple steps trying to find a way to organize them into subdirectories.

tests/
+-- feature/
+-- *.feature
+-- steps/
+-- menu_steps/
+-- user_menu_steps.py
+-- admin_menu_steps.py
+-- organisation_menu_steps.py
+-- profile_steps/
+-- user_profile_steps.py
+-- admin_profile_steps.py
environment.py
behave.ini

However, the above strategy will leave the behave runner complaining that the steps could not be found.

"Undefined step. Rest part of scenario is skipped"

The Solution

A way to go resolve this issue is the following

Step 1

Convert all step subdirectories into modules by adding an empty __init__.py file in every step subdirectory.

+-- steps/
+-- __init__.py
+-- menu_steps/
+-- __init__.py
+-- user_menu_steps.py
+-- admin_menu_steps.py
+-- organisation_menu_steps.py
+-- profile_steps/
+-- __init__.py
+-- user_profile_steps.py
+-- admin_profile_steps.py

Step 2

Import dynamically all step submodules within the steps directory by adding the following at the steps/__init__.py

import os
import pkgutil

__all__ = []
PATH = [os.path.dirname(__file__)]
for loader, module_name, is_pkg in pkgutil.walk_packages(PATH):
__all__.append(module_name)
_module = loader.find_module(module_name).load_module(module_name)
globals()[module_name] = _module

(Based on: https://stackoverflow.com/questions/3365740/how-to-import-all-submodules/3365846#3365846 )

Done !

We have tested the above code using Python 3.7 and python-behave 1.2.7 .