简体   繁体   中英

Pytest-bdd: Importing common steps

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 ?

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 *

I just found a way to make this work, although it's not as elegant. If you change from ui_shared import * to from ui_shared import common_step and THEN you also add (given('common_step'))(common_step) in the same ui_file.py, then you will be able to run the test importing common_step and without using import *. So you would have this:

In ui_file.py:

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

from ui_shared import common_step

(given('common_step'))(common_step)

@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 rest of the files would remain unchanged.

Now, the reason why this works is unclear to me, but it looks like importing the decorated function doesn't work using the syntactic sugar for decorators and so you can use the imported steps only if you decorate the function explicitly (without the syntactic sugar with @).

EDIT: Updated paranthesis in added given lines.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM