def test_getas__with_known_param_and_valid_text(self): userdata = UserData(param="42") assert "param" in userdata, "ENSURE: known param" value = userdata.getas(int, "param") assert isinstance(value, int) assert value == 42
def test_getas__with_unknown_param_returns_default_value(self): userdata = UserData() assert "param" not in userdata, "ENSURE: unknown param" value = userdata.getas(int, "param", 123) assert isinstance(value, int) self.assertEqual(value, 123)
def test_getas__with_known_param_and_preconverted_value(self): userdata = UserData(param=42) assert "param" in userdata, "ENSURE: known param" value = userdata.getas(int, "param") assert isinstance(value, int) self.assertEqual(value, 42)
def test_userdata_is_dictlike(self): userdata = UserData(name="Foo", number=42) value1 = userdata["name"] value2 = userdata.get("number") value3 = userdata.get("unknown", Unknown) assert isinstance(userdata, dict) self.assertEqual(value1, "Foo") self.assertEqual(value2, 42) assert value3 is Unknown
def test_getas__with_known_param_and_preconverted_value_and_valuetype(self): userdata = UserData(param=42) assert "param" in userdata, "ENSURE: known param" def parse_int(text): return int(text) value = userdata.getas(parse_int, "param", valuetype=int) assert isinstance(value, int) self.assertEqual(value, 42)
def test_getas__with_known_param_and_preconverted_value_and_valuetype( self): userdata = UserData(param=42) assert "param" in userdata, "ENSURE: known param" def parse_int(text): return int(text) value = userdata.getas(parse_int, "param", valuetype=int) assert isinstance(value, int) self.assertEqual(value, 42)
def test_getbool__with_known_param_and_valid_text(self): for true_text in ["true", "TRUE", "True", "yes", "on", "1"]: userdata = UserData(param=true_text) value = userdata.getbool("param") assert isinstance(value, bool), "text=%s" % true_text self.assertEqual(value, True) for false_text in ["false", "FALSE", "False", "no", "off", "0"]: userdata = UserData(param=false_text) value = userdata.getbool("param") assert isinstance(value, bool), "text=%s" % false_text self.assertEqual(value, False)
def test_read_from_file(mock_cp): mock_context = mock.Mock() mock_context._config.userdata = UserData.make({"config_file": "some_path"}) mock_cp().__getitem__.return_value = { "endpoint": "endpoint", "project": "project", "token": "token", "launch_name": "launch_name", "launch_description": "launch_description", "launch_attributes": "X Y Z", "step_based": "False", "is_skipped_an_issue": "True", "retries": "2", "rerun": "True", "rerun_of": "launch_id", } cfg = read_config(mock_context) expect(cfg.endpoint == "endpoint") expect(cfg.token == "token") expect(cfg.project == "project") expect(cfg.launch_name == "launch_name") expect(cfg.step_based is False) expect(cfg.is_skipped_an_issue is True) expect(cfg.launch_attributes == ["X", "Y", "Z"]) expect(cfg.launch_description == "launch_description") expect(cfg.retries == 2) expect(cfg.rerun is True) expect(cfg.rerun_of == "launch_id") expect(cfg.enabled is True) assert_expectations()
def test_read_config_from_cmd(mock_cp): mock_cp().has_section.return_value = False mock_context = mock.Mock() mock_context._config.userdata = UserData.make({ "config_file": "some_path", "endpoint": "endpoint", "project": "project", "token": "token", "launch_name": "launch_name", "launch_attributes": "A B C", "launch_description": "launch_description", "step_based": "True", "is_skipped_an_issue": "False", "retries": 3, "rerun": "True", "rerun_of": "launch_id", }) cfg = read_config(mock_context) expect(cfg.endpoint == "endpoint") expect(cfg.token == "token") expect(cfg.project == "project") expect(cfg.launch_name == "launch_name") expect(cfg.step_based is True) expect(cfg.launch_attributes == ["A", "B", "C"]) expect(cfg.launch_description == "launch_description") expect(cfg.is_skipped_an_issue is False) expect(cfg.retries == 3) expect(cfg.rerun is True) expect(cfg.rerun_of == "launch_id") expect(cfg.enabled is True) assert_expectations()
def test_read_config_file_path(mock_cp, cmd_args, path): mock_context = mock.Mock() mock_context._config.userdata = UserData.make(cmd_args) read_config(mock_context) expect(mock_cp().read.call_count == 1) expect(mock_cp().read.call_args[0][0] == path) expect(mock_cp().has_section.call_count == 1) expect(mock_cp().has_section.call_args[0][0] == RP_CFG_SECTION) assert_expectations()
def test_items__with_scoped_params(self): userdata = UserData({ "my.other_scope.param1": "__OTHER1__", "my.scope.param1": "123", "my.scope.param2": "456", "my.other_scope.param2": "__OTHER2__", }) config = UserDataNamespace("my.scope", userdata) assert sorted(config.items()) == [("param1", "123"), ("param2", "456")]
def test_setitem__stores_value(self): userdata = UserData({"my.scope.param1": "123"}) config = UserDataNamespace("my.scope", userdata) scoped_name = "my.scope.new_param" config["new_param"] = 1234 assert "new_param" in config assert config["new_param"] == 1234 assert scoped_name in config.data assert config.data[scoped_name] == 1234
def test_scoped_keys__with_scoped_params(self): userdata = UserData({ "my.other_scope.param1": "123", "my.scope.param1": "123", "my.scope.param2": "456", "my.other_scope.param2": "123", }) config = UserDataNamespace("my.scope", userdata) assert sorted( config.scoped_keys()) == ["my.scope.param1", "my.scope.param2"]
def test_length__with_scoped_params(self): userdata1 = UserData({"my.scope.param1": "123"}) userdata2 = UserData({ "my.other_scope.param1": "123", "my.scope.param1": "123", "my.scope.param2": "456", }) userdata3 = UserData({ "my.other_scope.param1": "123", "my.scope.param1": "123", "my.scope.param2": "456", "my.scope.param3": "789", "my.other_scope.param2": "123", }) config = UserDataNamespace("my.scope") config.data = userdata1 assert len(config) == 1 config.data = userdata2 assert len(config) == 2 config.data = userdata3 assert len(config) == 3
def test_read_config_default_values(mock_cp): mock_cp().has_section.return_value = False mock_context = mock.Mock() mock_context._config.userdata = UserData.make({"config_file": "some_path"}) cfg = read_config(mock_context) expect(cfg.endpoint is None) expect(cfg.token is None) expect(cfg.project is None) expect(cfg.launch_name == DEFAULT_LAUNCH_NAME) expect(cfg.step_based is False) expect(cfg.launch_attributes is None) expect(cfg.launch_description is None) expect(cfg.is_skipped_an_issue is False) expect(cfg.retries is None) expect(cfg.rerun is False) expect(cfg.rerun_of is None) expect(cfg.enabled is False) assert_expectations()
def test_getint__with_known_param_and_valid_text(self): userdata = UserData(param="42") value = userdata.getint("param") assert isinstance(value, int) self.assertEqual(value, 42)
def test_getbool__with_known_param_and_valid_false_text(self, text): false_text = text userdata = UserData(param=false_text) value = userdata.getbool("param") assert isinstance(value, bool), "text=%s" % false_text assert value is False
def test_length__returns_zero_without_params(self): userdata = UserData({"my.other_scope.param1": "123"}) config = UserDataNamespace("my.scope", userdata) assert len(config) == 0
def test_getas__with_known_param_and_invalid_text_raises_ValueError(self): userdata = UserData(param="__BAD_NUMBER__") assert "param" in userdata, "ENSURE: known param" with pytest.raises(ValueError): userdata.getas(int, "param")
def test_getbool__with_known_param_and_invalid_text_raises_ValueError(self): userdata = UserData(param="__BAD_VALUE__") with pytest.raises(ValueError): userdata.getbool("param")
def test_getfloat__with_unknown_param_without_default_returns_zero(self): userdata = UserData() value = userdata.getfloat("param") self.assertEqual(value, 0.0)
class Configuration(object): """Configuration object for behave and behave runners.""" # pylint: disable=too-many-instance-attributes defaults = dict( color=sys.platform != "win32", show_snippets=True, show_skipped=True, dry_run=False, show_source=True, show_timings=True, stdout_capture=True, stderr_capture=True, log_capture=True, logging_format="%(levelname)s:%(name)s:%(message)s", logging_level=logging.INFO, steps_catalog=False, summary=True, junit=False, stage=None, userdata={}, # -- SPECIAL: default_format="pretty", # -- Used when no formatters are configured. default_tags="", # -- Used when no tags are defined. scenario_outline_annotation_schema= u"{name} -- @{row.id} {examples.name}") cmdline_only_options = set("userdata_defines") def __init__(self, command_args=None, load_config=True, verbose=None, **kwargs): """ Constructs a behave configuration object. * loads the configuration defaults (if needed). * process the command-line args * store the configuration results :param command_args: Provide command args (as sys.argv). If command_args is None, sys.argv[1:] is used. :type command_args: list<str>, str :param load_config: Indicate if configfile should be loaded (=true) :param verbose: Indicate if diagnostic output is enabled :param kwargs: Used to hand-over/overwrite default values. """ # pylint: disable=too-many-branches, too-many-statements if command_args is None: command_args = sys.argv[1:] elif isinstance(command_args, six.string_types): encoding = select_best_encoding() or "utf-8" if six.PY2 and isinstance(command_args, six.text_type): command_args = command_args.encode(encoding) elif six.PY3 and isinstance(command_args, six.binary_type): command_args = command_args.decode(encoding) command_args = shlex.split(command_args) elif isinstance(command_args, (list, tuple)): command_args = to_texts(command_args) if verbose is None: # -- AUTO-DISCOVER: Verbose mode from command-line args. verbose = ("-v" in command_args) or ("--verbose" in command_args) self.version = None self.tags_help = None self.lang_list = None self.lang_help = None self.default_tags = None self.junit = None self.logging_format = None self.logging_datefmt = None self.name = None self.scope = None self.steps_catalog = None self.userdata = None self.wip = None defaults = self.defaults.copy() for name, value in six.iteritems(kwargs): defaults[name] = value self.defaults = defaults self.formatters = [] self.reporters = [] self.name_re = None self.outputs = [] self.include_re = None self.exclude_re = None self.scenario_outline_annotation_schema = None # pylint: disable=invalid-name self.steps_dir = "steps" self.environment_file = "environment.py" self.userdata_defines = None self.more_formatters = None if load_config: load_configuration(self.defaults, verbose=verbose) parser = setup_parser() parser.set_defaults(**self.defaults) args = parser.parse_args(command_args) for key, value in six.iteritems(args.__dict__): if key.startswith("_") and key not in self.cmdline_only_options: continue setattr(self, key, value) self.paths = [os.path.normpath(path) for path in self.paths] self.setup_outputs(args.outfiles) if self.steps_catalog: # -- SHOW STEP-CATALOG: As step summary. self.default_format = "steps.catalog" self.format = ["steps.catalog"] self.dry_run = True self.summary = False self.show_skipped = False self.quiet = True if self.wip: # Only run scenarios tagged with "wip". # Additionally: # * use the "plain" formatter (per default) # * do not capture stdout or logging output and # * stop at the first failure. self.default_format = "plain" self.tags = ["wip"] + self.default_tags.split() self.color = False self.stop = True self.log_capture = False self.stdout_capture = False self.tags = TagExpression(self.tags or self.default_tags.split()) if self.quiet: self.show_source = False self.show_snippets = False if self.exclude_re: self.exclude_re = re.compile(self.exclude_re) if self.include_re: self.include_re = re.compile(self.include_re) if self.name: # -- SELECT: Scenario-by-name, build regular expression. self.name_re = self.build_name_re(self.name) if self.stage is None: # pylint: disable=access-member-before-definition # -- USE ENVIRONMENT-VARIABLE, if stage is undefined. self.stage = os.environ.get("BEHAVE_STAGE", None) self.setup_stage(self.stage) self.setup_model() self.setup_userdata() # -- FINALLY: Setup Reporters and Formatters # NOTE: Reporters and Formatters can now use userdata information. if self.junit: # Buffer the output (it will be put into Junit report) self.stdout_capture = True self.stderr_capture = True self.log_capture = True self.reporters.append(JUnitReporter(self)) if self.summary: self.reporters.append(SummaryReporter(self)) self.setup_formats() unknown_formats = self.collect_unknown_formats() if unknown_formats: parser.error("format=%s is unknown" % ", ".join(unknown_formats)) def setup_outputs(self, args_outfiles=None): if self.outputs: assert not args_outfiles, "ONLY-ONCE" return # -- NORMAL CASE: Setup only initially (once). if not args_outfiles: self.outputs.append(StreamOpener(stream=sys.stdout)) else: for outfile in args_outfiles: if outfile and outfile != "-": self.outputs.append(StreamOpener(outfile)) else: self.outputs.append(StreamOpener(stream=sys.stdout)) def setup_formats(self): """Register more, user-defined formatters by name.""" if self.more_formatters: for name, scoped_class_name in self.more_formatters.items(): _format_registry.register_as(name, scoped_class_name) def collect_unknown_formats(self): unknown_formats = [] if self.format: for format_name in self.format: if (format_name == "help" or _format_registry.is_formatter_valid(format_name)): continue unknown_formats.append(format_name) return unknown_formats @staticmethod def build_name_re(names): """ Build regular expression for scenario selection by name by using a list of name parts or name regular expressions. :param names: List of name parts or regular expressions (as text). :return: Compiled regular expression to use. """ # -- NOTE: re.LOCALE is removed in Python 3.6 (deprecated in Python 3.5) # flags = (re.UNICODE | re.LOCALE) # -- ENSURE: Names are all unicode/text values (for issue #606). names = to_texts(names) pattern = u"|".join(names) return re.compile(pattern, flags=re.UNICODE) def exclude(self, filename): if isinstance(filename, FileLocation): filename = six.text_type(filename) if self.include_re and self.include_re.search(filename) is None: return True if self.exclude_re and self.exclude_re.search(filename) is not None: return True return False def setup_logging(self, level=None, configfile=None, **kwargs): """ Support simple setup of logging subsystem. Ensures that the logging level is set. But note that the logging setup can only occur once. SETUP MODES: * :func:`logging.config.fileConfig()`, if ``configfile`` is provided. * :func:`logging.basicConfig()`, otherwise. .. code-block: python # -- FILE: features/environment.py def before_all(context): context.config.setup_logging() :param level: Logging level of root logger. If None, use :attr:`logging_level` value. :param configfile: Configuration filename for fileConfig() setup. :param kwargs: Passed to :func:`logging.basicConfig()` """ if level is None: level = self.logging_level # pylint: disable=no-member if configfile: from logging.config import fileConfig fileConfig(configfile) else: # pylint: disable=no-member format_ = kwargs.pop("format", self.logging_format) datefmt = kwargs.pop("datefmt", self.logging_datefmt) logging.basicConfig(format=format_, datefmt=datefmt, **kwargs) # -- ENSURE: Default log level is set # (even if logging subsystem is already configured). logging.getLogger().setLevel(level) def setup_model(self): if self.scenario_outline_annotation_schema: name_schema = six.text_type( self.scenario_outline_annotation_schema) ScenarioOutline.annotation_schema = name_schema.strip() def setup_stage(self, stage=None): """Setup the test stage that selects a different set of steps and environment implementations. :param stage: Name of current test stage (as string or None). EXAMPLE:: # -- SETUP DEFAULT TEST STAGE (unnamed): config = Configuration() config.setup_stage() assert config.steps_dir == "steps" assert config.environment_file == "environment.py" # -- SETUP PRODUCT TEST STAGE: config.setup_stage("product") assert config.steps_dir == "product_steps" assert config.environment_file == "product_environment.py" """ steps_dir = "steps" environment_file = "environment.py" if stage: # -- USE A TEST STAGE: Select different set of implementations. prefix = stage + "_" steps_dir = prefix + steps_dir environment_file = prefix + environment_file self.steps_dir = steps_dir self.environment_file = environment_file def setup_userdata(self): if not isinstance(self.userdata, UserData): self.userdata = UserData(self.userdata) if self.userdata_defines: # -- ENSURE: Cmd-line overrides configuration file parameters. self.userdata.update(self.userdata_defines) def update_userdata(self, data): """Update userdata with data and reapply userdata defines (cmdline). :param data: Provides (partial) userdata (as dict) """ self.userdata.update(data) if self.userdata_defines: # -- REAPPLY: Cmd-line defines (override configuration file data). self.userdata.update(self.userdata_defines)
def test_getitem__raises_error_when_param_not_exists(self): userdata = UserData({"my.scope.param": "123"}) config = UserDataNamespace("my.scope", userdata) with pytest.raises(KeyError): _ = config["UNKNOWN_PARAM"]
def test_getbool__with_unknown_param_returns_default_value(self): userdata = UserData() value = userdata.getint("param", 1.2) assert isinstance(value, float) self.assertEqual(value, 1.2)
def test_getbool__with_known_param_and_invalid_text_raises_ValueError( self): userdata = UserData(param="__BAD_VALUE__") self.assertRaises(ValueError, userdata.getbool, "param")
def test_getbool__with_unknown_param_without_default_returns_false(self): userdata = UserData() value = userdata.getfloat("param") self.assertEqual(value, False)
def test_getfloat__with_known_param_and_valid_text(self): for valid_text in ["1.2", "2", "-1E+3", "+2.34E-5"]: userdata = UserData(param=valid_text) value = userdata.getfloat("param") assert isinstance(value, float) self.assertEqual(value, float(valid_text))
def test_getfloat__with_known_param_and_invalid_text_raises_ValueError( self): userdata = UserData(param="__BAD_NUMBER__") self.assertRaises(ValueError, userdata.getfloat, "param")
def test_contains__when_scoped_param_not_exists(self): userdata = UserData({"my.scope.param": 12}) config = UserDataNamespace("my.scope", userdata) assert "UNKNOWN_PARAM" not in config assert not ("UNKNOWN_PARAM" in config)
def test_getas__with_known_param_and_invalid_text_raises_ValueError(self): userdata = UserData(param="__BAD_NUMBER__") assert "param" in userdata, "ENSURE: known param" self.assertRaises(ValueError, userdata.getas, int, "param")
class Configuration(object): """Configuration object for behave and behave runners.""" # pylint: disable=too-many-instance-attributes defaults = dict( color=sys.platform != "win32", show_snippets=True, show_skipped=True, dry_run=False, show_source=True, show_timings=True, stdout_capture=True, stderr_capture=True, log_capture=True, logging_format="%(levelname)s:%(name)s:%(message)s", logging_level=logging.INFO, steps_catalog=False, summary=True, junit=False, stage=None, userdata={}, # -- SPECIAL: default_format="pretty", # -- Used when no formatters are configured. default_tags="", # -- Used when no tags are defined. scenario_outline_annotation_schema=u"{name} -- @{row.id} {examples.name}" ) cmdline_only_options = set("userdata_defines") def __init__(self, command_args=None, load_config=True, verbose=None, **kwargs): """ Constructs a behave configuration object. * loads the configuration defaults (if needed). * process the command-line args * store the configuration results :param command_args: Provide command args (as sys.argv). If command_args is None, sys.argv[1:] is used. :type command_args: list<str>, str :param load_config: Indicate if configfile should be loaded (=true) :param verbose: Indicate if diagnostic output is enabled :param kwargs: Used to hand-over/overwrite default values. """ # pylint: disable=too-many-branches, too-many-statements if command_args is None: command_args = sys.argv[1:] elif isinstance(command_args, six.string_types): if six.PY2 and isinstance(command_args, six.text_type): command_args = command_args.encode("utf-8") elif six.PY3 and isinstance(command_args, six.binary_type): command_args = command_args.decode("utf-8") command_args = shlex.split(command_args) if verbose is None: # -- AUTO-DISCOVER: Verbose mode from command-line args. verbose = ("-v" in command_args) or ("--verbose" in command_args) self.version = None self.tags_help = None self.lang_list = None self.lang_help = None self.default_tags = None self.junit = None self.logging_format = None self.logging_datefmt = None self.name = None self.scope = None self.steps_catalog = None self.userdata = None self.wip = None defaults = self.defaults.copy() for name, value in six.iteritems(kwargs): defaults[name] = value self.defaults = defaults self.formatters = [] self.reporters = [] self.name_re = None self.outputs = [] self.include_re = None self.exclude_re = None self.scenario_outline_annotation_schema = None # pylint: disable=invalid-name self.steps_dir = "steps" self.environment_file = "environment.py" self.userdata_defines = None self.more_formatters = None if load_config: load_configuration(self.defaults, verbose=verbose) parser = setup_parser() parser.set_defaults(**self.defaults) args = parser.parse_args(command_args) for key, value in six.iteritems(args.__dict__): if key.startswith("_") and key not in self.cmdline_only_options: continue setattr(self, key, value) self.paths = [os.path.normpath(path) for path in self.paths] self.setup_outputs(args.outfiles) if self.steps_catalog: # -- SHOW STEP-CATALOG: As step summary. self.default_format = "steps.catalog" self.format = ["steps.catalog"] self.dry_run = True self.summary = False self.show_skipped = False self.quiet = True if self.wip: # Only run scenarios tagged with "wip". # Additionally: # * use the "plain" formatter (per default) # * do not capture stdout or logging output and # * stop at the first failure. self.default_format = "plain" self.tags = ["wip"] + self.default_tags.split() self.color = False self.stop = True self.log_capture = False self.stdout_capture = False self.tags = TagExpression(self.tags or self.default_tags.split()) if self.quiet: self.show_source = False self.show_snippets = False if self.exclude_re: self.exclude_re = re.compile(self.exclude_re) if self.include_re: self.include_re = re.compile(self.include_re) if self.name: # -- SELECT: Scenario-by-name, build regular expression. self.name_re = self.build_name_re(self.name) if self.stage is None: # pylint: disable=access-member-before-definition # -- USE ENVIRONMENT-VARIABLE, if stage is undefined. self.stage = os.environ.get("BEHAVE_STAGE", None) self.setup_stage(self.stage) self.setup_model() self.setup_userdata() # -- FINALLY: Setup Reporters and Formatters # NOTE: Reporters and Formatters can now use userdata information. if self.junit: # Buffer the output (it will be put into Junit report) self.stdout_capture = True self.stderr_capture = True self.log_capture = True self.reporters.append(JUnitReporter(self)) if self.summary: self.reporters.append(SummaryReporter(self)) self.setup_formats() unknown_formats = self.collect_unknown_formats() if unknown_formats: parser.error("format=%s is unknown" % ", ".join(unknown_formats)) def setup_outputs(self, args_outfiles=None): if self.outputs: assert not args_outfiles, "ONLY-ONCE" return # -- NORMAL CASE: Setup only initially (once). if not args_outfiles: self.outputs.append(StreamOpener(stream=sys.stdout)) else: for outfile in args_outfiles: if outfile and outfile != "-": self.outputs.append(StreamOpener(outfile)) else: self.outputs.append(StreamOpener(stream=sys.stdout)) def setup_formats(self): """Register more, user-defined formatters by name.""" if self.more_formatters: for name, scoped_class_name in self.more_formatters.items(): _format_registry.register_as(name, scoped_class_name) def collect_unknown_formats(self): unknown_formats = [] if self.format: for format_name in self.format: if (format_name == "help" or _format_registry.is_formatter_valid(format_name)): continue unknown_formats.append(format_name) return unknown_formats @staticmethod def build_name_re(names): """ Build regular expression for scenario selection by name by using a list of name parts or name regular expressions. :param names: List of name parts or regular expressions (as text). :return: Compiled regular expression to use. """ # -- NOTE: re.LOCALE is removed in Python 3.6 (deprecated in Python 3.5) # flags = (re.UNICODE | re.LOCALE) pattern = u"|".join(names) return re.compile(pattern, flags=re.UNICODE) def exclude(self, filename): if isinstance(filename, FileLocation): filename = six.text_type(filename) if self.include_re and self.include_re.search(filename) is None: return True if self.exclude_re and self.exclude_re.search(filename) is not None: return True return False def setup_logging(self, level=None, configfile=None, **kwargs): """ Support simple setup of logging subsystem. Ensures that the logging level is set. But note that the logging setup can only occur once. SETUP MODES: * :func:`logging.config.fileConfig()`, if ``configfile`` is provided. * :func:`logging.basicConfig()`, otherwise. .. code-block: python # -- FILE: features/environment.py def before_all(context): context.config.setup_logging() :param level: Logging level of root logger. If None, use :attr:`logging_level` value. :param configfile: Configuration filename for fileConfig() setup. :param kwargs: Passed to :func:`logging.basicConfig()` """ if level is None: level = self.logging_level # pylint: disable=no-member if configfile: from logging.config import fileConfig fileConfig(configfile) else: # pylint: disable=no-member format_ = kwargs.pop("format", self.logging_format) datefmt = kwargs.pop("datefmt", self.logging_datefmt) logging.basicConfig(format=format_, datefmt=datefmt, **kwargs) # -- ENSURE: Default log level is set # (even if logging subsystem is already configured). logging.getLogger().setLevel(level) def setup_model(self): if self.scenario_outline_annotation_schema: name_schema = six.text_type(self.scenario_outline_annotation_schema) ScenarioOutline.annotation_schema = name_schema.strip() def setup_stage(self, stage=None): """Setup the test stage that selects a different set of steps and environment implementations. :param stage: Name of current test stage (as string or None). EXAMPLE:: # -- SETUP DEFAULT TEST STAGE (unnamed): config = Configuration() config.setup_stage() assert config.steps_dir == "steps" assert config.environment_file == "environment.py" # -- SETUP PRODUCT TEST STAGE: config.setup_stage("product") assert config.steps_dir == "product_steps" assert config.environment_file == "product_environment.py" """ steps_dir = "steps" environment_file = "environment.py" if stage: # -- USE A TEST STAGE: Select different set of implementations. prefix = stage + "_" steps_dir = prefix + steps_dir environment_file = prefix + environment_file self.steps_dir = steps_dir self.environment_file = environment_file def setup_userdata(self): if not isinstance(self.userdata, UserData): self.userdata = UserData(self.userdata) if self.userdata_defines: # -- ENSURE: Cmd-line overrides configuration file parameters. self.userdata.update(self.userdata_defines) def update_userdata(self, data): """Update userdata with data and reapply userdata defines (cmdline). :param data: Provides (partial) userdata (as dict) """ self.userdata.update(data) if self.userdata_defines: # -- REAPPLY: Cmd-line defines (override configuration file data). self.userdata.update(self.userdata_defines)
def test_getitem__returns_value_when_param_exists(self): userdata = UserData({"my.scope.param": "123"}) config = UserDataNamespace("my.scope", userdata) assert config["param"] == "123"
def test_getfloat__with_known_param_and_invalid_text_raises_ValueError(self): userdata = UserData(param="__BAD_NUMBER__") with pytest.raises(ValueError): userdata.getfloat("param")
def test_getint__with_unknown_param_returns_default_value(self): userdata = UserData() value = userdata.getint("param", 123) assert isinstance(value, int) assert value == 123
def test_getas__with_unknown_param_without_default_returns_none(self): userdata = UserData() assert "param" not in userdata, "ENSURE: unknown param" value = userdata.getas(int, "param") assert value is None
def setup_userdata(self): if not isinstance(self.userdata, UserData): self.userdata = UserData(self.userdata) if self.userdata_defines: # -- ENSURE: Cmd-line overrides configuration file parameters. self.userdata.update(self.userdata_defines)
def test_getbool__returns_default_when_scoped_param_not_exists(self): userdata = UserData({}) config = UserDataNamespace("my.scope", userdata) assert config.getint("UNKNOWN_PARAM", True) == True assert config.getint("UNKNOWN_PARAM", False) == False
def test_getint__with_unknown_param_without_default_returns_zero(self): userdata = UserData() value = userdata.getint("param") assert value == 0