Commit 29921321 by Gabriel Falcão

a lot of code, it must be refactored

parent e0502e44
......@@ -115,6 +115,7 @@ class Step(object):
ran = False
passed = None
failed = None
related_outline = None
def __init__(self, sentence, remaining_lines, line=None, filename=None):
self.sentence = sentence
......@@ -182,8 +183,10 @@ class Step(object):
return matched, StepDefinition(self, func)
def pre_run(self, ignore_case):
def pre_run(self, ignore_case, with_outline=None):
matched, step_definition = self._get_match(ignore_case)
self.related_outline = with_outline
if not self.defined_at:
if not matched:
raise NoDefinitionFound(self)
......@@ -238,6 +241,9 @@ class Scenario(object):
original_string)
self.keys = keys
self.outlines = outlines
self.with_file = with_file
self.original_string = original_string
if with_file and original_string:
scenario_definition = ScenarioDescription(self, with_file,
original_string)
......@@ -290,6 +296,17 @@ class Scenario(object):
def __repr__(self):
return u'<Scenario: "%s">' % self.name
def evaluated(self):
for outline in self.outlines:
steps = []
for step in self.steps:
sentence = step.sentence
for k, v in outline.items():
sentence = sentence.replace(u'<%s>' % k, v)
steps.append(step)
yield (outline, steps)
def run(self, ignore_case):
"""Runs a scenario, running each of its steps. Also call
before_each and after_each callbacks for steps and scenario"""
......@@ -301,30 +318,41 @@ class Scenario(object):
for callback in CALLBACK_REGISTRY['scenario']['before_each']:
callback(self)
for step in self.steps:
try:
step.pre_run(ignore_case)
for callback in CALLBACK_REGISTRY['step']['before_each']:
callback(step)
def run_scenario(almost_self, steps, outline=None, run_callbacks=False):
for step in steps:
try:
step.pre_run(ignore_case, with_outline=outline)
if run_callbacks:
for callback in CALLBACK_REGISTRY['step']['before_each']:
callback(step)
if not steps_failed and not steps_undefined:
step.run(ignore_case)
steps_passed.append(step)
if not steps_failed and not steps_undefined:
step.run(ignore_case)
steps_passed.append(step)
except AssertionError:
steps_failed.append(step)
except AssertionError:
steps_failed.append(step)
except NoDefinitionFound, e:
steps_undefined.append(e.step)
except NoDefinitionFound, e:
steps_undefined.append(e.step)
finally:
if run_callbacks:
for callback in CALLBACK_REGISTRY['step']['after_each']:
callback(step)
finally:
for callback in CALLBACK_REGISTRY['step']['after_each']:
callback(step)
if self.outlines:
first = True
for outline, steps in self.evaluated():
run_scenario(self, steps, outline, run_callbacks=first)
first = False
else:
run_scenario(self, self.steps, run_callbacks=True)
for callback in CALLBACK_REGISTRY['scenario']['after_each']:
callback(self)
skip = lambda x: x not in steps_passed and x not in steps_undefined and x not in steps_failed
steps_skipped = filter(skip, self.steps)
......@@ -558,7 +586,11 @@ class TotalResult(object):
self.steps = 0
for feature_result in self.feature_results:
for scenario_result in feature_result.scenario_results:
self.scenario_results.append(scenario_result)
for outline in scenario_result.scenario.outlines:
self.scenario_results.append(scenario_result)
else:
self.scenario_results.append(scenario_result)
self.steps_passed += len(scenario_result.steps_passed)
self.steps_failed += len(scenario_result.steps_failed)
self.steps_skipped += len(scenario_result.steps_skipped)
......
......@@ -9,7 +9,7 @@
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# MERsteps.pyCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
......
Feature: Failful Scenario Outline
As lettuce author
In order to finish the first release
I want to make scenario outlines work :)
Scenario Outline: fill a web form
Given I open browser at "http://www.my-website.com/"
And click on "sign-up"
When I fill the field "username" with "<username>"
And I fill the field "password" with "<password>"
And I fill the field "password-confirm" with "<password>"
And I fill the field "email" with "<email>"
And I click "done"
Then I see the message "<message>"
Examples:
| username | password | email | message |
| john | doe-1234 | john@gmail.org | Welcome, John |
| mary | wee-9876 | mary@email.com | Welcome, Mary |
| foo | foo-bar | foo@bar.com | Welcome, Foo |
# -*- coding: utf-8 -*-
# <Lettuce - Behaviour Driven Development for python>
# Copyright (C) <2010> Gabriel Falcão <gabriel@nacaolivre.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from lettuce import step
@step(r'Given I open browser at "http://(.*)"')
def given_i_open_browser_at_http_address(step, address):
pass
@step(r'And click on "sign[-]up"')
def and_click_on_sign_up(step):
pass
@step(r'I fill the field "(.*)" with "(.*)"')
def when_i_fill_the_field_x_with_y(step, field, value):
if field == 'password' and value == 'wee-9876': assert False
@step(r'And I click "done"')
def and_i_click_done(step):
pass
@step(r'Then I see the message "(.*)"')
def then_i_see_the_message_message(step, message):
pass
Feature: Successful Scenario Outline
As lettuce author
In order to finish the first release
I want to make scenario outlines work :)
Scenario Outline: fill a web form
Given I open browser at "http://www.my-website.com/"
And click on "sign-up"
When I fill the field "username" with "<username>"
And I fill the field "password" with "<password>"
And I fill the field "password-confirm" with "<password>"
And I fill the field "email" with "<email>"
And I click "done"
Then I see the message "<message>"
Examples:
| username | password | email | message |
| john | doe-1234 | john@gmail.org | Welcome, John |
| mary | wee-9876 | mary@email.com | Welcome, Mary |
| foo | foo-bar | foo@bar.com | Welcome, Foo |
# -*- coding: utf-8 -*-
# <Lettuce - Behaviour Driven Development for python>
# Copyright (C) <2010> Gabriel Falcão <gabriel@nacaolivre.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from lettuce import step
@step(r'Given I open browser at "http://(.*)"')
def given_i_open_browser_at_http_address(step, address):
pass
@step(r'And click on "sign[-]up"')
def and_click_on_sign_up(step):
pass
@step(r'I fill the field "(.*)" with "(.*)"')
def when_i_fill_the_field_x_with_y(step, field, value):
pass
@step(r'And I click "done"')
def and_i_click_done(step):
pass
@step(r'Then I see the message "(.*)"')
def then_i_see_the_message_message(step, message):
pass
......@@ -494,8 +494,8 @@ def test_output_with_successful_outline_colorless():
' | foo | foo-bar | foo@bar.com | Welcome, Foo |\n'
'\n'
'1 feature (1 passed)\n'
'1 scenario (1 passed)\n'
'8 steps (8 passed)\n'
'4 scenarios (4 passed)\n'
'24 steps (24 passed)\n'
)
@with_setup(prepare_stdout)
......@@ -529,7 +529,49 @@ def test_output_with_successful_outline_colorful():
'\033[1;32m \033[1;37m |\033[1;32m foo \033[1;37m |\033[1;32m foo-bar \033[1;37m |\033[1;32m foo@bar.com \033[1;37m |\033[1;32m Welcome, Foo \033[1;37m |\033[1;32m\033[0m\n'
'\n'
"\033[1;37m1 feature (\033[1;32m1 passed\033[1;37m)\033[0m\n" \
"\033[1;37m1 scenario (\033[1;32m1 passed\033[1;37m)\033[0m\n" \
"\033[1;37m8 steps (\033[1;32m8 passed\033[1;37m)\033[0m\n"
"\033[1;37m4 scenarios (\033[1;32m4 passed\033[1;37m)\033[0m\n" \
"\033[1;37m24 steps (\033[1;32m24 passed\033[1;37m)\033[0m\n"
)
@with_setup(prepare_stdout)
def test_output_with_failful_outline_colorless():
"Testing the colorless output of a scenario outline"
runner = Runner(feature_name('fail_outline'), verbosity=3)
runner.run()
assert_stdout_lines(
'\n'
'Feature: Failful Scenario Outline # tests/functional/output_features/fail_outline/fail_outline.feature:1\n'
' As lettuce author # tests/functional/output_features/fail_outline/fail_outline.feature:2\n'
' In order to finish the first release # tests/functional/output_features/fail_outline/fail_outline.feature:3\n'
' I want to make scenario outlines work :) # tests/functional/output_features/fail_outline/fail_outline.feature:4\n'
'\n'
' Scenario Outline: fill a web form # tests/functional/output_features/fail_outline/fail_outline.feature:6\n'
' Given I open browser at "http://www.my-website.com/" # tests/functional/output_features/fail_outline/fail_outline_steps.py:21\n'
' And click on "sign-up" # tests/functional/output_features/fail_outline/fail_outline_steps.py:25\n'
' When I fill the field "username" with "<username>" # tests/functional/output_features/fail_outline/fail_outline_steps.py:29\n'
' And I fill the field "password" with "<password>" # tests/functional/output_features/fail_outline/fail_outline_steps.py:29\n'
' And I fill the field "password-confirm" with "<password>" # tests/functional/output_features/fail_outline/fail_outline_steps.py:29\n'
' And I fill the field "email" with "<email>" # tests/functional/output_features/fail_outline/fail_outline_steps.py:29\n'
' And I click "done" # tests/functional/output_features/fail_outline/fail_outline_steps.py:33\n'
' Then I see the message "<message>" # tests/functional/output_features/fail_outline/fail_outline_steps.py:37\n'
'\n'
' Examples:\n'
' | username | password | email | message |\n'
' | john | doe-1234 | john@gmail.org | Welcome, John |\n'
' | mary | wee-9876 | mary@email.com | Welcome, Mary |\n'
' File "%(lettuce_core_file)s", line 54, in __call__\n'
" ret = self.function(self.step, *args, **kw)\n"
' File "%(step_file)s", line 31, in when_i_fill_the_field_x_with_y\n'
" assert False\n"
" AssertionError\n"
' | foo | foo-bar | foo@bar.com | Welcome, Foo |\n'
'\n'
'1 feature (1 passed)\n'
'1 scenario (1 passed)\n'
'8 steps (8 passed)\n' % {
'lettuce_core_file':'/Users/gabriel.falcao/Projetos/lettuce/lettuce/core.py',
'step_file': '/Users/gabriel.falcao/Projetos/lettuce/tests/functional/output_features/fail_outline/fail_outline_steps.py'
}
)
......@@ -249,21 +249,33 @@ def test_full_featured_feature():
for step, expected_sentence in zip(scenario1.solved_steps, expected_sentences):
assert_equals(step.sentence, expected_sentence)
assert_equals(len(scenario4.solved_steps), 12)
expected_sentences = [
'Given I have entered 20 into the calculator',
'And I have entered 30 into the calculator',
'When I press add',
'Then the result should be 50 on the screen',
'Given I have entered 2 into the calculator',
'And I have entered 5 into the calculator',
'When I press add',
'Then the result should be 7 on the screen',
'Given I have entered 0 into the calculator',
'And I have entered 40 into the calculator',
'When I press add',
'Then the result should be 40 on the screen',
]
for step, expected_sentence in zip(scenario4.solved_steps, expected_sentences):
assert_equals(step.sentence, expected_sentence)
expected_evaluated = (
(
{'button': 'add', 'input_1': '20', 'input_2': '30', 'output': '50'}, [
'Given I have entered 20 into the calculator',
'And I have entered 30 into the calculator',
'When I press add',
'Then the result should be 50 on the screen',
]
),
(
{'button': 'add', 'input_1': '2', 'input_2': '5', 'output': '7'}, [
'Given I have entered 2 into the calculator',
'And I have entered 5 into the calculator',
'When I press add',
'Then the result should be 7 on the screen',
]
),
(
{'button': 'add', 'input_1': '0', 'input_2': '40', 'output': '40'}, [
'Given I have entered 0 into the calculator',
'And I have entered 40 into the calculator',
'When I press add',
'Then the result should be 40 on the screen',
],
)
)
for ((got_examples, got_steps), (expected_examples, expected_steps)) in zip(scenario4.evaluated(), expected_evaluated):
sentences_of = lambda x: x.sentence
assert_equals(got_examples, expected_examples)
assert_equals(map(sentences_of, got_steps), expected_steps)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment