Skip to content

Commit

Permalink
Adds the ability to use a custom runner in the behave command
Browse files Browse the repository at this point in the history
  • Loading branch information
kingbuzzman authored and bittner committed Jul 7, 2021
1 parent 994dbfe commit 49f4ca4
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 1 deletion.
2 changes: 1 addition & 1 deletion behave/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ def main(args=None):
:return: 0, if successful. Non-zero, in case of errors/failures.
"""
config = Configuration(args)
return run_behave(config)
return run_behave(config, runner_class=config.runner_class)


if __name__ == "__main__":
Expand Down
16 changes: 16 additions & 0 deletions behave/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import sys
import shlex
import six
from importlib import import_module
from six.moves import configparser

from behave.model import ScenarioOutline
Expand Down Expand Up @@ -65,6 +66,16 @@ def to_string(level):
# -----------------------------------------------------------------------------
# CONFIGURATION SCHEMA:
# -----------------------------------------------------------------------------

def valid_python_module(path):
try:
module_path, class_name = path.rsplit('.', 1)
module = import_module(module_path)
return getattr(module, class_name)
except (ValueError, AttributeError, ImportError):
raise argparse.ArgumentTypeError("No module named '%s' was found." % path)


options = [
(("-c", "--no-color"),
dict(action="store_false", dest="color",
Expand Down Expand Up @@ -111,6 +122,11 @@ def to_string(level):
dict(metavar="PATH", dest="junit_directory",
default="reports",
help="""Directory in which to store JUnit reports.""")),

(("--runner-class",),
dict(action="store",
default="behave.runner.Runner", type=valid_python_module,
help="Tells Behave to use a specific runner. (default: %(default)s)")),

((), # -- CONFIGFILE only
dict(dest="default_format",
Expand Down
5 changes: 5 additions & 0 deletions docs/behave.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ You may see the same information presented below at any time using ``behave

Directory in which to store JUnit reports.

.. option:: --runner-class

This allows you to use your own custom runner. The default is
``behave.runner.Runner``.

.. option:: -f, --format

Specify a formatter. If none is specified the default formatter is
Expand Down
19 changes: 19 additions & 0 deletions tests/unit/test_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import pytest
from behave import configuration
from behave.configuration import Configuration, UserData
from behave.runner import Runner as BaseRunner
from unittest import TestCase


Expand Down Expand Up @@ -37,6 +38,10 @@
ROOTDIR_PREFIX = os.environ.get("BEHAVE_ROOTDIR_PREFIX", ROOTDIR_PREFIX_DEFAULT)


class CustomTestRunner(BaseRunner):
"""Custom, dummy runner"""


class TestConfiguration(object):

def test_read_file(self):
Expand Down Expand Up @@ -92,6 +97,20 @@ def test_settings_with_stage_from_envvar(self):
assert "STAGE2_environment.py" == config.environment_file
del os.environ["BEHAVE_STAGE"]

def test_settings_runner_class(self, capsys):
config = Configuration("")
assert BaseRunner == config.runner_class

def test_settings_runner_class_custom(self, capsys):
config = Configuration(["--runner-class=tests.unit.test_configuration.CustomTestRunner"])
assert CustomTestRunner == config.runner_class

def test_settings_runner_class_invalid(self, capsys):
with pytest.raises(SystemExit):
Configuration(["--runner-class=does.not.exist.Runner"])
captured = capsys.readouterr()
assert "No module named 'does.not.exist.Runner' was found." in captured.err


class TestConfigurationUserData(TestCase):
"""Test userdata aspects in behave.configuration.Configuration class."""
Expand Down

0 comments on commit 49f4ca4

Please sign in to comment.