Pytest-bdd: Importing common steps

Viewed 3068

Edit: I am no longer working on this project, but I will leave this question open until answered in case it is of use to anyone.

I am working on implementing pytest-bdd and I am trying to import use steps from a different file named ui_shared.py.

Currently my directory is structured:

proj/lib/ui_file.py
proj/lib/ui_shared.py
proj/tests/test_file.py
proj/features/file.feature

Pytest-bdd is able to recognize the steps from ui_shared.py and execute the test as long as ui_file.py imports with:

from ui_shared import *

but I would like to avoid using import *.

I have tried import ui_shared.py and from ui_shared.py import common_step, where common_step is the step function I would like to import, and I get the error:

StepDefinitionNotFoundError: Step definition is not found: Given "common function".

There is a related question that I found: Behave: How to import steps from another file? as well as a few others, most of which says to import the steps into the common steps file, ui_shared.py in my case, which I have already done.

Here is the code for ui_shared.py:

#!/usr/bin/python

import pytest
from pytest_bdd import (
    scenario,
    given,
    when,
    then
)

@pytest.fixture(scope="function")
def context():
    return{}

@given('common step')
def common_step(input):
    #some method

Here are other relevant code:

In file.feature:

Scenario Outline: ui_file
    Given common step
    And another given step
    When some step
    Then last step

In test_file.py:

#!/usr/bin/python

@pytest.fixture
def pytestbdd_strict_gherkin():
    return False

@scenario('proj/features/file.feature', 'ui_file')
def test_ui_file():
    """ui_file"""

And in ui_file.py:

import pytest
from pytest_bdd import (
    scenario,
    given,
    when,
    then
)

from ui_shared import * #This is what I am trying to change

@given('another given step')
def another_given_step(input)
    #some method

@when('some step')
def some_step(input)
    #some method

@then('last step')
def last_step(input)
    #some method

The above should work as is, but if the import method is changed then the pytest fails with E StepDefinitionNotFoundError.

What I am looking for is a way to import all names defined in ui_shared.py except for the methods I am not using.

Basically, how do I import using from file import without the * and allow my ui_file.py to use the common steps from ui_shared.py?

2 Answers

Add the following lines inside your conftest.py

pytest_plugins = [
   "lib.ui_shared"
]

This way all fixtures or pytest-bdd steps inside ui_shared.py will be available to every other file as if it was inside conftest.py

NOTE
lib must be a package, meaning there should be a __init__.py file inside the lib folder

You can try something like this:

from .ui_file import *

That is what I wrote for my project:

from .devices_steps import *
Related