def test_executes_setup_teardown_pairs(self): source = """ Feature: setUp/tearDown pairs Scenario: passing scenario When step passes And next step passes Scenario: failing scenario When step fails """ steps = Parser().parse_feature(source) try: execute_script(steps[0], self) except AssertionError: pass expected_sequence = [ "setUpFeature", "setUpScenario", "setUpStep", "step passes", "tearDownStep", "setUpStep", "next step passes", "tearDownStep", "tearDownScenario", "setUpScenario", "setUpStep", "step fails", "tearDownStep", "tearDownScenario", "tearDownFeature", ] assert expected_sequence == self.executed
def test_handle_exceptions(self): source = "Given exceptional" s = Given(source=source, line_number=42) try: execute_script(s, self) assert False # should raise! # pragma: nocover except ZeroDivisionError as e: assert "Given exceptional" in str(e.__cause__) assert "division by zero" in str(e)
def test_another_two_dimensional_table(self): self.crunks = [] self.zones = [] scene = self.assemble_scene_table_source( "Step my milkshake brings all the boys to the yard\n" ) feature = Parser().parse_features(scene) execute_script(feature, self) assert ["work", "mall", "jail", "work", "mall", "jail"] == self.crunks assert ["beach", "beach", "beach", "hotel", "hotel", "hotel"] == self.zones
def test_hides_irrevelant_traceback_parts(self): try: execute_script(self.feature, self) except Exception as exc: tb = traceback.format_tb(exc.__traceback__) # should have only 3 lines: # - one with test_hides_irrevelant_traceback_parts frame # - one with execute_script frame # - one with step causing error assert len(tb) == 3
def test_two_dimensional_table(self): self.elements = [] self.factions = [] scene = self.assemble_short_scene_table() feature = Parser().parse_features(scene) execute_script(feature, self) assert [["Pangolin", "Glyptodon"], ["Pangea", "Laurasia"]] == [ self.factions, self.elements, ]
def step_Morelia_evaluates_the_file(self): self.diagnostic = None try: p = Parser() self.file_contents.replace( "\\#", "#") # note - this is how to unescape characters - DIY prefix = "Feature: Sample\nScenario: Sample\n" feature = p.parse_features(prefix + self.file_contents) execute_script(feature, self) except (MissingStepError, AssertionError) as e: self.diagnostic = str(e)
def test_supports_languages_other_than_english(self): source = """# language: pl Właściwość: obsługa języków obcych Scenariusz: Dopasowuje kroki według języka Zakładając, że wykonany został krok przygotowujący Gdy wykonuję akcję Wtedy weryfikuję wynik """ feature = Parser().parse_feature(source)[0] execute_script(feature, self) assert ["given", "when", "then"] == self.executed
def step_a_file_contains_statements_produce_diagnostics_( self, statements, diagnostics): r"a file contains (.+), it produces (.+)" try: statements = statements.replace("\\n", "\n") statements = statements.replace("\\", "") feature = Parser().parse_features(statements) execute_script(feature, self) raise Exception("we expect syntax errors here") # pragma: nocover except (SyntaxError, AssertionError) as e: e = e.args[0] self.assert_regex_contains(re.escape(diagnostics), e)
def step_a_file_contains_statements_produce_diagnostics_( self, statements, diagnostics ): r"a file contains (.+), it produces (.+)" try: statements = statements.replace("\\n", "\n") statements = statements.replace("\\", "") feature = Parser().parse_features(statements) execute_script(feature, self) raise Exception("we expect syntax errors here") # pragma: nocover except (SyntaxError, AssertionError) as e: e = e.args[0] self.assert_regex_contains(re.escape(diagnostics), e)
def step_Morelia_evaluates_the_file(self): self.diagnostic = None try: p = Parser() self.file_contents.replace( "\\#", "#" ) # note - this is how to unescape characters - DIY prefix = "Feature: Sample\nScenario: Sample\n" feature = p.parse_features(prefix + self.file_contents) execute_script(feature, self) except (MissingStepError, AssertionError) as e: self.diagnostic = str(e)
def run(filename, suite, as_str=None, scenario=r".*", verbose=False, show_all_missing=True, **kwargs): # NOQA """Parse file and run tests on given suite. :param str filename: file name :param unittest.TestCase suite: TestCase instance :param string as_str: None to use file or a string containing the feature to parse :param string scenario: a regex pattern to match the scenario to run :param boolean verbose: be verbose :param boolean show_all_missing: show all missing steps """ formatter = kwargs.get("formatter", None) if verbose and not formatter: if has_color_support(): formatter = ColorTextFormatter() else: formatter = PlainTextFormatter() kwargs["formatter"] = formatter kwargs["show_all_missing"] = show_all_missing if as_str is None: source = File(filename) else: source = Text(as_str, filename) feature = Parser().parse_features(source) return execute_script(feature, suite, scenario=scenario, **kwargs)
def test_does_not_leak_too_much(self): tracemalloc.start() gc.collect() series = [] snapshot1 = tracemalloc.take_snapshot() for i in range(100): try: execute_script(self.feature, self) except Exception: pass gc.collect() snapshot2 = tracemalloc.take_snapshot() stats = snapshot2.compare_to(snapshot1, "lineno") snapshot1 = snapshot2 series.append(sum(stat.size / 1024 for stat in stats)) tracemalloc.stop() series = series[1:] # ignore first run, which creates regex cv = statistics.stdev(series) / statistics.mean(series) assert cv < 0.1
def verify(script, suite, scenario: str = ".*", config: str = "default") -> None: """Verifies script with steps from suite. :param script: feature script :param suite: object with steps defined :param str scenario: regex pattern for selecting single scenarios :param str config: section from configuration to apply Script can be passed directly to verify method as first argument. .. code-block:: python >>> from morelia import verify >>> verify( ... \""" ... Feature: Addition ... Scenario: Add two numbers ... Given I have entered 50 into the calculator ... And I have entered 70 into the calculator ... When I press add ... Then the result should be 120 on the screen ... \""", ... test_case_with_steps, ) When given path to file with script morelia will read that file and verify: .. code-block:: python >>> verify('calculator.feature', test_case_with_steps) Similary url pointing to script can be given: .. code-block:: python >>> verify('http://example.com/calculator.feature', test_case_with_steps) Two last invocations will work only for single line strings. If it starts with "http[s]://" it is considered an url. If it ends with ".feature" it is considered a file. To explicity mark what type of parameter it can be wrapped in helper classes: - :py:func:`File` - :py:func:`Url` - :py:func:`Text` >>> from morelia import verify, File, Text, Url >>> verify(File('calculator.feature'), test_case_with_steps) >>> verify(Url('http://example.com/calculator.feature'), test_case_with_steps) >>> verify( ... Text(\""" ... Feature: Addition ... Scenario: Add two numbers ... Given I have entered 50 into the calculator ... And I have entered 70 into the calculator ... When I press add ... Then the result should be 120 on the screen ... \"""), ... test_case_with_steps, ) """ conf = TOMLConfig(config) script = _coerce_type(script) feature = Parser().parse_features(script) execute_script(feature, suite, scenario=scenario, config=conf, formatter=PlainTextFormatter())
def test_step_multiline_predicate(self): feature = "When multiline predicate" steps = Parser().parse_feature(feature) execute_script(steps[0], self)
def step_evaluate_step_by_doc_string(self): step = Given("Given my milkshake brings all the girls to a yard") self.youth = "boys" execute_script(step, self) self.assertEqual("girls", self.youth) # Uh...
def test_evaluate_file(self): feature = Parser().parse_file(features_dir / "morelia.feature") execute_script(feature, self)
def test_evaluate_file(self): feature = Parser().parse_features( File(features_dir / "morelia.feature")) execute_script(feature, self)
def test_background(self): filename = features_dir / "background.feature" feature = Parser().parse_file(filename) self.__scenarios_num = sum(1 for s in feature.steps if isinstance(s, Scenario)) execute_script(feature, self)
def test_labels(self): filename = features_dir / "labels.feature" feature = Parser().parse_file(filename) execute_script(feature, self)