Making Steps - RMuskovets/pytest-stepper-plugin GitHub Wiki
Each step consists of a "configurator" - a function that accepts the user-provided parameters for the step, and
the "actual" step - this one is nested in the configurator and is actually the one that the plugin calls.
For example, look at this little step named do_something:
def do_something():
    def do_something(vars):
        print('I did something!')
    return do_something
The outer function is the configurator, and the inner is the step. This one doesn't need any user-provided parameters so configurator doesn't take any arguments.
But the inner function does: vars is the only argument present in the inner function. It is a dict of variables that a step can optionally set and the steps that run after it will receive.
Now let's make another step that does take a argument. This step will be named greet:
def greet(whom):
    def greet(vars):
        print(f'Hello, {whom}!')
    return greet
And it does that, this test will say hello to everyone:
test_greet = [
    greet('everyone')
]
Moving to the vars, a use case of it is auto-tests using Selenium - you probably don't want to reopen the browser window for every single step. Here's two steps that open and close the browser window respectively (imports omitted):
def open_browser():
    def open_browser(vars):
        browser = Chrome()
        vars['browser'] = browser
    return open_browser
def close_browser():
    def close_browser(vars):
        if vars.get('browser') is None:
            fail('to close the window, you need to open it first')
        else:
            vars['browser'].quit()
As you can see, the close_browser fails when you have no browser window.
This is everything I wanted to put in this article, so go read other ones!