def parse_step(self, json_element): """ s = { 'keyword': step.keyword, 'step_type': step.step_type, 'name': step.name, 'location': step.location, } if step.text: s['text'] = step.text if step.table: s['table'] = self.make_table(step.table) element = self.current_feature_element element['steps'].append(s) """ keyword = json_element.get("keyword", u"") name = json_element.get("name", u"") step_type = json_element.get("step_type", u"") location = json_element.get("location", u"") text = json_element.get("text", None) if isinstance(text, list): text = "\n".join(text) table = None json_table = json_element.get("table", None) if json_table: table = self.parse_table(json_table) filename, line = location.split(":") step = model.Step(filename, line, keyword, step_type, name) step.text = text step.table = table json_result = json_element.get("result", None) if json_result: self.add_step_result(step, json_result) return step
def parse_step(self, line): for step_type in ("given", "when", "then", "and", "but"): for kw in self.keywords[step_type]: # try to match the keyword; also attempt a purely lowercase # match if that'll work if not (line.startswith(kw) or line.lower().startswith(kw.lower())): # -- CASE: Line does not start w/ a step-keyword. continue # -- HINT: Trailing SPACE is used for most keywords. # BUT: Keywords in some languages (like Chinese, Japanese, ...) # do not need a whitespace as word separator. step_text_after_keyword = line[len(kw):].strip() if step_type in ("and", "but"): if not self.last_step: raise ParserError(u"No previous step", self.line) step_type = self.last_step else: self.last_step = step_type keyword = kw.rstrip() # HINT: Strip optional trailing SPACE. step = model.Step(self.filename, self.line, keyword, step_type, step_text_after_keyword) return step return None
def test_run_runs_before_hook_then_match_then_after_hook(self): step = model.Step('foo.feature', 17, u'Given', 'given', u'foo') match = Mock() self.step_registry.find_match.return_value = match side_effects = (None, AssertionError('whee'), Exception('whee')) for side_effect in side_effects: # Make match.run() and runner.run_hook() the same mock so # we can make sure things happen in the right order. self.runner.run_hook = match.run = Mock() def effect(thing): def raiser(*args, **kwargs): match.run.side_effect = None if thing: raise thing def nonraiser(*args, **kwargs): match.run.side_effect = raiser return nonraiser match.run.side_effect = effect(side_effect) with patch('behave.step_registry.registry', self.step_registry): step.run(self.runner) eq_( match.run.call_args_list, [ (('before_step', self.context, step), {}), ((self.context,), {}), (('after_step', self.context, step), {}), ] )
def parse_step(self, line): for step_type in ("given", "when", "then", "and", "but"): for kw in self.keywords[step_type]: if kw.endswith("<"): whitespace = "" kw = kw[:-1] else: whitespace = " " # try to match the keyword; also attempt a purely lowercase # match if that'll work if not (line.startswith(kw + whitespace) or line.lower().startswith(kw.lower() + whitespace)): continue name = line[len(kw):].strip() if step_type in ("and", "but"): if not self.last_step: raise ParserError(u"No previous step", self.line) step_type = self.last_step else: self.last_step = step_type step = model.Step(self.filename, self.line, kw, step_type, name) return step return None
def test_run_with_no_match_does_not_touch_formatter_when_quiet(self): step = model.Step('foo.feature', 17, u'Given', 'given', u'foo') self.step_registry.find_match.return_value = None with patch('behave.step_registry.registry', self.step_registry): assert not step.run(self.runner, quiet=True) assert not self.formatter.match.called assert not self.formatter.result.called
def test_run_reports_undefined_step_via_formatter_when_not_quiet(self): step = model.Step('foo.feature', 17, u'Given', 'given', u'foo') self.step_registry.find_match.return_value = None with patch('behave.step_registry.registry', self.step_registry): assert not step.run(self.runner) self.formatter.match.assert_called_with(model.NoMatch()) self.formatter.result.assert_called_with(step)
def test_run_appends_step_to_undefined_when_no_match_found(self): step = model.Step('foo.feature', 17, u'Given', 'given', u'foo') self.step_registry.find_match.return_value = None self.runner.undefined = [] with patch('behave.step_registry.registry', self.step_registry): assert not step.run(self.runner) assert step in self.runner.undefined eq_(step.status, 'undefined')
def test_run_sets_text_if_present(self): step = model.Step('foo.feature', 17, u'Given', 'given', u'foo', text=Mock(name='text')) self.step_registry.find_match.return_value = Mock() with patch('behave.step_registry.registry', self.step_registry): step.run(self.runner) eq_(self.context.text, step.text)
def test_run_captures_stdout_and_logging(self): step = model.Step('foo.feature', 17, u'Given', 'given', u'foo') match = Mock() self.step_registry.find_match.return_value = match with patch('behave.step_registry.registry', self.step_registry): assert step.run(self.runner) self.runner.start_capture.assert_called_with() self.runner.stop_capture.assert_called_with()
def test_run_sets_status_to_passed_if_nothing_goes_wrong(self): step = model.Step('foo.feature', 17, u'Given', 'given', u'foo') step.error_message = None self.step_registry.find_match.return_value = Mock() with patch('behave.step_registry.registry', self.step_registry): step.run(self.runner) eq_(step.status, 'passed') eq_(step.error_message, None)
def test_run_when_quiet_reports_nothing(self): step = model.Step('foo.feature', 17, u'Given', 'given', u'foo') match = Mock() self.step_registry.find_match.return_value = match side_effects = (None, raiser(AssertionError('whee')), raiser(Exception('whee'))) for side_effect in side_effects: match.run.side_effect = side_effect step.run(self.runner, quiet=True) assert not self.formatter.match.called assert not self.formatter.result.called
def test_run_appends_any_captured_logging_on_failure(self): step = model.Step('foo.feature', 17, u'Given', 'given', u'foo') match = Mock() self.step_registry.find_match.return_value = match self.log_capture.getvalue.return_value = 'toads' match.run.side_effect = raiser(AssertionError('kipper')) with patch('behave.step_registry.registry', self.step_registry): assert not step.run(self.runner) assert 'Captured logging:' in step.error_message assert 'toads' in step.error_message
def test_run_appends_any_captured_stdout_on_failure(self): step = model.Step('foo.feature', 17, u'Given', 'given', u'foo') match = Mock() self.step_registry.find_match.return_value = match self.stdout_capture.getvalue.return_value = 'frogs' match.run.side_effect = raiser(Exception('halibut')) with patch('behave.step_registry.registry', self.step_registry): assert not step.run(self.runner) assert 'Captured stdout:' in step.error_message assert 'frogs' in step.error_message
def test_run_sets_status_to_failed_on_assertion_error(self): step = model.Step('foo.feature', 17, u'Given', 'given', u'foo') step.error_message = None match = Mock() match.run.side_effect = raiser(AssertionError('whee')) self.step_registry.find_match.return_value = match with patch('behave.step_registry.registry', self.step_registry): step.run(self.runner) eq_(step.status, 'failed') assert step.error_message.startswith('Assertion Failed')
def test_run_sets_status_to_failed_on_exception(self, format_exc): step = model.Step('foo.feature', 17, u'Given', 'given', u'foo') step.error_message = None match = Mock() match.run.side_effect = raiser(Exception('whee')) self.step_registry.find_match.return_value = match format_exc.return_value = 'something to do with an exception' with patch('behave.step_registry.registry', self.step_registry): step.run(self.runner) eq_(step.status, 'failed') eq_(step.error_message, format_exc.return_value)
def test_run_when_not_quiet_reports_match_and_result(self): step = model.Step('foo.feature', 17, u'Given', 'given', u'foo') match = Mock() self.step_registry.find_match.return_value = match side_effects = (None, raiser(AssertionError('whee')), raiser(Exception('whee'))) for side_effect in side_effects: match.run.side_effect = side_effect with patch('behave.step_registry.registry', self.step_registry): step.run(self.runner) self.formatter.match.assert_called_with(match) self.formatter.result.assert_called_with(step)
def test_run_calculates_duration(self, time_time): step = model.Step('foo.feature', 17, u'Given', 'given', u'foo') match = Mock() self.step_registry.find_match.return_value = match def time_time_1(): def time_time_2(): return 23 time_time.side_effect = time_time_2 return 17 side_effects = (None, raiser(AssertionError('whee')), raiser(Exception('whee'))) for side_effect in side_effects: match.run.side_effect = side_effect time_time.side_effect = time_time_1 with patch('behave.step_registry.registry', self.step_registry): step.run(self.runner) eq_(step.duration, 23 - 17)