diff --git a/README.rst b/README.rst index d33ad27..14c5fdb 100644 --- a/README.rst +++ b/README.rst @@ -51,13 +51,15 @@ publish_article.feature: Feature: Blog A site where you can publish your articles. - Scenario: Publishing the article - Given I'm an author user - And I have an article - When I go to the article page - And I press the publish button - Then I should not see the error message - And the article should be published # Note: will query the database + Scenario: Publishing the article + Given I'm an author user + And I have an article + + When I go to the article page + And I press the publish button + + Then I should not see the error message + And the article should be published # Note: will query the database Note that only one feature is allowed per feature file. @@ -150,14 +152,15 @@ default author. .. code-block:: gherkin - Scenario: I'm the author - Given I'm an author - And I have an article + Feature: Resource owner + Scenario: I'm the author + Given I'm an author + And I have an article - Scenario: I'm the admin - Given I'm the admin - And there's an article + Scenario: I'm the admin + Given I'm the admin + And there's an article Given step scope @@ -174,14 +177,15 @@ pass optional ``scope`` argument: .. code-block:: gherkin - Scenario: I'm the author - Given I'm an author - And there is an article + Feature: Fixture scope + Scenario: I'm the author + Given I'm an author + And there is an article - Scenario: I'm the admin - Given I'm the admin - And there is an article + Scenario: I'm the admin + Given I'm the admin + And there is an article In this example, the step function for the 'there is an article' given step will be executed once, even though there @@ -257,13 +261,14 @@ Example: .. code-block:: gherkin - Scenario: Arguments for given, when, thens - Given there are 5 cucumbers + Feature: Step arguments + Scenario: Arguments for given, when, thens + Given there are 5 cucumbers - When I eat 3 cucumbers - And I eat 2 cucumbers + When I eat 3 cucumbers + And I eat 2 cucumbers - Then I should have 0 cucumbers + Then I should have 0 cucumbers The code will look like: @@ -367,9 +372,10 @@ it will stay untouched. To allow this, special parameter `target_fixture` exists .. code-block:: gherkin - Scenario: Test given fixture injection - Given I have injecting given - Then foo should be "injected foo" + Feature: Target fixture + Scenario: Test given fixture injection + Given I have injecting given + Then foo should be "injected foo" In this example existing fixture `foo` will be overridden by given step `I have injecting given` only for scenario it's used in. @@ -384,12 +390,13 @@ But in much cleaner and powerful way: .. code-block:: gherkin - Scenario: Multiline step using sub indentation - Given I have a step with: - Some - Extra - Lines - Then the text should be parsed with correct indentation + Feature: Multiline steps + Scenario: Multiline step using sub indentation + Given I have a step with: + Some + Extra + Lines + Then the text should be parsed with correct indentation Step is considered as multiline one, if the **next** line(s) after it's first line, is indented relatively to the first line. The step name is then simply extended by adding further lines with newlines. @@ -489,29 +496,31 @@ Example: .. code-block:: gherkin - Scenario Outline: Outlined given, when, thens - Given there are cucumbers - When I eat cucumbers - Then I should have cucumbers + Feature: Scenario outlines + Scenario Outline: Outlined given, when, thens + Given there are cucumbers + When I eat cucumbers + Then I should have cucumbers - Examples: - | start | eat | left | - | 12 | 5 | 7 | + Examples: + | start | eat | left | + | 12 | 5 | 7 | pytest-bdd feature file format also supports example tables in different way: .. code-block:: gherkin - Scenario Outline: Outlined given, when, thens - Given there are cucumbers - When I eat cucumbers - Then I should have cucumbers + Feature: Scenario outlines + Scenario Outline: Outlined given, when, thens + Given there are cucumbers + When I eat cucumbers + Then I should have cucumbers - Examples: Vertical - | start | 12 | 2 | - | eat | 5 | 1 | - | left | 7 | 1 | + Examples: Vertical + | start | 12 | 2 | + | eat | 5 | 1 | + | left | 7 | 1 | This form allows to have tables with lots of columns keeping the maximum text width predictable without significant readability change. @@ -782,8 +791,10 @@ This also declares a PyTest fixture "article" and any other step can depend on i .. code-block:: gherkin - Given I have a beautiful article - When I publish this article + Feature: Power of pytest + Scenario: Symbolic name across steps + Given I have a beautiful article + When I publish this article When step is referring the article to publish it. @@ -831,9 +842,11 @@ no sense. It won't be executed second time. .. code-block:: gherkin - Given I have a beautiful article - And some other thing - And I have a beautiful article # Won't be executed, exception is raised + Feature: Power of pytest + Scenario: Given is a fixture and evaluated only once + Given I have a beautiful article + And some other thing + And I have a beautiful article # Won't be executed, exception is raised pytest-bdd will raise an exception even in the case of the steps that use regular expression @@ -842,8 +855,10 @@ patterns to get arguments. .. code-block:: gherkin - Given I have 1 cucumbers - And I have 2 cucumbers # Exception is raised + Feature: Power of pytest + Scenario: Given is a fixture and evaluated only once + Given I have 1 cucumbers + And I have 2 cucumbers # Exception is raised Will raise an exception if the step is using the regular expression pattern. diff --git a/pytest_bdd/feature.py b/pytest_bdd/feature.py index d0dfc67..2446f72 100644 --- a/pytest_bdd/feature.py +++ b/pytest_bdd/feature.py @@ -10,13 +10,14 @@ provided in the pytest parametrization table. Syntax example: - Scenario: Publishing the article - Given I'm an author user - And I have an article - When I go to the article page - And I press the publish button - Then I should not see the error message - And the article should be published # Note: will query the database + Feature: Articles + Scenario: Publishing the article + Given I'm an author user + And I have an article + When I go to the article page + And I press the publish button + Then I should not see the error message + And the article should be published # Note: will query the database :note: The "#" symbol is used for comments. :note: There're no multiline steps, the description of the step must fit in diff --git a/tests/conftest.py b/tests/conftest.py index b433a8c..694d7d5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,10 +1 @@ -"""Configuration for pytest runner.""" - -from pytest_bdd import when - pytest_plugins = "pytester" - - -@when("I use a when step from the parent conftest") -def global_when(): - pass diff --git a/tests/feature/outline.feature b/tests/feature/outline.feature deleted file mode 100644 index f1c3ce4..0000000 --- a/tests/feature/outline.feature +++ /dev/null @@ -1,62 +0,0 @@ -Scenario Outline: Outlined given, when, thens - Given there are cucumbers - When I eat cucumbers - Then I should have cucumbers - - Examples: - | start | eat | left | - | 12 | 5 | 7 | - | 5 | 4 | 1 | - - -Scenario Outline: Outlined with wrong examples - Given there are cucumbers - When I eat cucumbers - Then I should have cucumbers - - Examples: - | start | eat | left | unknown_param | - | 12 | 5 | 7 | value | - - -Scenario Outline: Outlined with some examples failing - Given there are cucumbers - When I eat cucumbers - Then I should have cucumbers - - Examples: - | start | eat | left | - | 0 | 5 | 5 | - | 12 | 5 | 7 | - - -Scenario Outline: Outlined with vertical example table - Given there are cucumbers - When I eat cucumbers - Then I should have cucumbers - - Examples: Vertical - | start | 12 | 2 | - | eat | 5 | 1 | - | left | 7 | 1 | - - -Scenario Outline: Outlined with empty example values vertical - Given there are cucumbers - When I eat cucumbers - Then I should have cucumbers - - Examples: Vertical - | start | # | - | eat | | - | left | | - - -Scenario Outline: Outlined with empty example values - Given there are cucumbers - When I eat cucumbers - Then I should have cucumbers - - Examples: - | start | eat | left | - | # | | | diff --git a/tests/feature/outline_feature.feature b/tests/feature/outline_feature.feature deleted file mode 100644 index 98280b1..0000000 --- a/tests/feature/outline_feature.feature +++ /dev/null @@ -1,16 +0,0 @@ -Feature: Outline - - Examples: - | start | eat | left | - | 12 | 5 | 7 | - | 5 | 4 | 1 | - - Scenario Outline: Outlined given, when, thens - Given there are - When I eat - Then I should have - - Examples: - | fruits | - | oranges | - | apples | diff --git a/tests/feature/test_feature_base_dir.py b/tests/feature/test_feature_base_dir.py index 5826083..4ded8af 100644 --- a/tests/feature/test_feature_base_dir.py +++ b/tests/feature/test_feature_base_dir.py @@ -54,8 +54,9 @@ def prepare_testdir(testdir, ini_base_dir): feature_file = testdir.mkdir("features").join("steps.feature") feature_file.write( """ - Scenario: When scenario found - Given found + Feature: Feature path + Scenario: When scenario found + Given found """ ) diff --git a/tests/feature/test_outline.py b/tests/feature/test_outline.py index 6f7f135..4597620 100644 --- a/tests/feature/test_outline.py +++ b/tests/feature/test_outline.py @@ -1,18 +1,9 @@ """Scenario Outline tests.""" -from __future__ import unicode_literals -import re import textwrap -import pytest -from pytest_bdd import given, when, then, scenario -from pytest_bdd import exceptions -from pytest_bdd.utils import get_parametrize_markers_args - - -@scenario("outline.feature", "Outlined given, when, thens", example_converters=dict(start=int, eat=float, left=str)) -def test_outlined(request): - assert get_parametrize_markers_args(request.node) == (["start", "eat", "left"], [[12, 5.0, "7"], [5, 4.0, "1"]]) +STEPS = """\ +from pytest_bdd import given, when, then @given("there are cucumbers") @@ -34,193 +25,401 @@ def should_have_left_cucumbers(start_cucumbers, start, eat, left): assert start_cucumbers["start"] == start assert start_cucumbers["eat"] == eat +""" -def test_wrongly_outlined(request): + +def test_outlined(testdir): + testdir.makefile( + ".feature", + outline=textwrap.dedent( + """\ + Feature: Outline + Scenario Outline: Outlined given, when, thens + Given there are cucumbers + When I eat cucumbers + Then I should have cucumbers + + Examples: + | start | eat | left | + | 12 | 5 | 7 | + | 5 | 4 | 1 | + + """ + ), + ) + + testdir.makeconftest(textwrap.dedent(STEPS)) + + testdir.makepyfile( + textwrap.dedent( + """\ + from pytest_bdd.utils import get_parametrize_markers_args + from pytest_bdd import scenario + + @scenario( + "outline.feature", + "Outlined given, when, thens", + example_converters=dict(start=int, eat=float, left=str) + ) + def test_outline(request): + assert get_parametrize_markers_args(request.node) == ( + ["start", "eat", "left"], + [ + [12, 5.0, "7"], + [5, 4.0, "1"], + ], + ) + + """ + ) + ) + result = testdir.runpytest() + result.assert_outcomes(passed=2) + + +def test_wrongly_outlined(testdir): """Test parametrized scenario when the test function lacks parameters.""" - with pytest.raises(exceptions.ScenarioExamplesNotValidError) as exc: + + testdir.makefile( + ".feature", + outline=textwrap.dedent( + """\ + Feature: Outline + Scenario Outline: Outlined with wrong examples + Given there are cucumbers + When I eat cucumbers + Then I should have cucumbers + + Examples: + | start | eat | left | unknown_param | + | 12 | 5 | 7 | value | + + """ + ), + ) + testdir.makeconftest(textwrap.dedent(STEPS)) + + testdir.makepyfile( + textwrap.dedent( + """\ + from pytest_bdd import scenario @scenario("outline.feature", "Outlined with wrong examples") - def wrongly_outlined(): + def test_outline(request): pass - - assert re.match( - r"""Scenario \"Outlined with wrong examples\" in the feature \"(.+)\" has not valid examples\. """ - r"""Set of step parameters (.+) should match set of example values """ - r"""(.+)\.""", - exc.value.args[0], + """ + ) ) + result = testdir.runpytest() + result.assert_outcomes(error=1) + result.stdout.fnmatch_lines( + '*ScenarioExamplesNotValidError: Scenario "Outlined with wrong examples"*has not valid examples*', + ) + result.stdout.fnmatch_lines("*should match set of example values [[]'eat', 'left', 'start', 'unknown_param'[]].*",) def test_wrong_vertical_examples_scenario(testdir): """Test parametrized scenario vertical example table has wrong format.""" - features = testdir.mkdir("features") - feature = features.join("test.feature") - feature.write_text( - textwrap.dedent( + testdir.makefile( + ".feature", + outline=textwrap.dedent( + """\ + Feature: Outline + Scenario Outline: Outlined with wrong vertical example table + Given there are cucumbers + When I eat cucumbers + Then I should have cucumbers + + Examples: Vertical + | start | 12 | 2 | + | start | 10 | 1 | + | left | 7 | 1 | """ - Scenario Outline: Outlined with wrong vertical example table - Given there are cucumbers - When I eat cucumbers - Then I should have cucumbers - - Examples: Vertical - | start | 12 | 2 | - | start | 10 | 1 | - | left | 7 | 1 | - """ ), - "utf-8", - ensure=True, ) - with pytest.raises(exceptions.FeatureError) as exc: + testdir.makeconftest(textwrap.dedent(STEPS)) - @scenario(feature.strpath, "Outlined with wrong vertical example table") - def wrongly_outlined(): + testdir.makepyfile( + textwrap.dedent( + """\ + from pytest_bdd import scenario + + @scenario("outline.feature", "Outlined with wrong vertical example table") + def test_outline(request): pass - - assert exc.value.args[0] == ( - "Scenario has not valid examples. Example rows should contain unique parameters." - ' "start" appeared more than once' + """ + ) + ) + result = testdir.runpytest() + result.assert_outcomes(error=1) + result.stdout.fnmatch_lines( + "*Scenario has not valid examples. Example rows should contain unique parameters. " + '"start" appeared more than once.*' ) def test_wrong_vertical_examples_feature(testdir): """Test parametrized feature vertical example table has wrong format.""" - features = testdir.mkdir("features") - feature = features.join("test.feature") - feature.write_text( - textwrap.dedent( + testdir.makefile( + ".feature", + outline=textwrap.dedent( + """\ + Feature: Outlines + + Examples: Vertical + | start | 12 | 2 | + | start | 10 | 1 | + | left | 7 | 1 | + + Scenario Outline: Outlined with wrong vertical example table + Given there are cucumbers + When I eat cucumbers + Then I should have cucumbers """ - Feature: Outlines - - Examples: Vertical - | start | 12 | 2 | - | start | 10 | 1 | - | left | 7 | 1 | - - Scenario Outline: Outlined with wrong vertical example table - Given there are cucumbers - When I eat cucumbers - Then I should have cucumbers - """ ), - "utf-8", - ensure=True, ) - with pytest.raises(exceptions.FeatureError) as exc: + testdir.makeconftest(textwrap.dedent(STEPS)) - @scenario(feature.strpath, "Outlined with wrong vertical example table") - def wrongly_outlined(): + testdir.makepyfile( + textwrap.dedent( + """\ + from pytest_bdd import scenario + + @scenario("outline.feature", "Outlined with wrong vertical example table") + def test_outline(request): + pass + """ + ) + ) + result = testdir.runpytest() + result.assert_outcomes(error=1) + result.stdout.fnmatch_lines( + "*Feature has not valid examples. Example rows should contain unique parameters. " + '"start" appeared more than once.*' + ) + + +def test_outlined_with_other_fixtures(testdir): + """Test outlined scenario also using other parametrized fixture.""" + testdir.makefile( + ".feature", + outline=textwrap.dedent( + """\ + Feature: Outline + Scenario Outline: Outlined given, when, thens + Given there are cucumbers + When I eat cucumbers + Then I should have cucumbers + + Examples: + | start | eat | left | + | 12 | 5 | 7 | + | 5 | 4 | 1 | + + """ + ), + ) + + testdir.makeconftest(textwrap.dedent(STEPS)) + + testdir.makepyfile( + textwrap.dedent( + """\ + import pytest + from pytest_bdd.utils import get_parametrize_markers_args + from pytest_bdd import scenario + + + @pytest.fixture(params=[1, 2, 3]) + def other_fixture(request): + return request.param + + + @scenario( + "outline.feature", + "Outlined given, when, thens", + example_converters=dict(start=int, eat=float, left=str) + ) + def test_outline(other_fixture): pass - assert exc.value.args[0] == ( - "Feature has not valid examples. Example rows should contain unique parameters." - ' "start" appeared more than once' + """ + ) ) + result = testdir.runpytest() + result.assert_outcomes(passed=6) -@pytest.fixture(params=[1, 2, 3]) -def other_fixture(request): - return request.param - - -@scenario("outline.feature", "Outlined given, when, thens", example_converters=dict(start=int, eat=float, left=str)) -def test_outlined_with_other_fixtures(other_fixture): - """Test outlined scenario also using other parametrized fixture.""" - - -@scenario( - "outline.feature", "Outlined with vertical example table", example_converters=dict(start=int, eat=float, left=str) -) -def test_vertical_example(request): +def test_vertical_example(testdir): """Test outlined scenario with vertical examples table.""" - assert get_parametrize_markers_args(request.node) == (["start", "eat", "left"], [[12, 5.0, "7"], [2, 1.0, "1"]]) + testdir.makefile( + ".feature", + outline=textwrap.dedent( + """\ + Feature: Outline + Scenario Outline: Outlined with vertical example table + Given there are cucumbers + When I eat cucumbers + Then I should have cucumbers + Examples: Vertical + | start | 12 | 2 | + | eat | 5 | 1 | + | left | 7 | 1 | -@given("there are ") -def start_fruits(start, fruits): - assert isinstance(start, int) - return {fruits: dict(start=start)} - - -@when("I eat ") -def eat_fruits(start_fruits, eat, fruits): - assert isinstance(eat, float) - start_fruits[fruits]["eat"] = eat - - -@then("I should have ") -def should_have_left_fruits(start_fruits, start, eat, left, fruits): - assert isinstance(left, str) - assert start - eat == int(left) - assert start_fruits[fruits]["start"] == start - assert start_fruits[fruits]["eat"] == eat - - -@scenario( - "outline_feature.feature", "Outlined given, when, thens", example_converters=dict(start=int, eat=float, left=str) -) -def test_outlined_feature(request): - assert get_parametrize_markers_args(request.node) == ( - ["start", "eat", "left"], - [[12, 5.0, "7"], [5, 4.0, "1"]], - ["fruits"], - [["oranges"], ["apples"]], - ) - - -def test_outline_with_escaped_pipes(testdir): - """Test parametrized feature example table with escaped pipe characters in input.""" - features = testdir.mkdir("features") - feature = features.join("test.feature") - feature.write_text( - textwrap.dedent( - r""" - Feature: Outline With Special characters - - Scenario Outline: Outline with escaped pipe character - Given We have strings and - Then should be the base64 encoding of - - Examples: - | string1 | string2 | - | bork | Ym9yaw== | - | \|bork | fGJvcms= | - | bork \| | Ym9yayB8 | - | bork\|\|bork | Ym9ya3x8Ym9yaw== | - | \| | fA== | - | bork \\ | Ym9yayAgICAgIFxc | - | bork \\\| | Ym9yayAgICBcXHw= | """ ), - "utf-8", - ensure=True, + ) + + testdir.makeconftest(textwrap.dedent(STEPS)) + + testdir.makepyfile( + textwrap.dedent( + """\ + from pytest_bdd.utils import get_parametrize_markers_args + from pytest_bdd import scenario + + @scenario( + "outline.feature", + "Outlined with vertical example table", + example_converters=dict(start=int, eat=float, left=str) + ) + def test_outline(request): + assert get_parametrize_markers_args(request.node) == ( + ["start", "eat", "left"], + [ + [12, 5.0, "7"], + [2, 1.0, "1"], + ], + ) + + """ + ) + ) + result = testdir.runpytest() + result.assert_outcomes(passed=2) + + +def test_outlined_feature(testdir): + testdir.makefile( + ".feature", + outline=textwrap.dedent( + """\ + Feature: Outline + + Examples: + | start | eat | left | + | 12 | 5 | 7 | + | 5 | 4 | 1 | + + Scenario Outline: Outlined given, when, thens + Given there are + When I eat + Then I should have + + Examples: + | fruits | + | oranges | + | apples | + """ + ), ) testdir.makepyfile( textwrap.dedent( - """ - import base64 + """\ + from pytest_bdd.utils import get_parametrize_markers_args + from pytest_bdd import given, when, then, scenario - from pytest_bdd import scenario, given, when, then - from pytest_bdd.utils import get_parametrize_markers_args + @scenario( + "outline.feature", + "Outlined given, when, thens", + example_converters=dict(start=int, eat=float, left=str) + ) + def test_outline(request): + assert get_parametrize_markers_args(request.node) == ( + ["start", "eat", "left"], + [[12, 5.0, "7"], [5, 4.0, "1"]], + ["fruits"], + [["oranges"], ["apples"]], + ) + + @given("there are ") + def start_fruits(start, fruits): + assert isinstance(start, int) + return {fruits: dict(start=start)} - @scenario("features/test.feature", "Outline with escaped pipe character") - def test_outline_with_escaped_pipe_character(request): - pass + @when("I eat ") + def eat_fruits(start_fruits, eat, fruits): + assert isinstance(eat, float) + start_fruits[fruits]["eat"] = eat - @given("We have strings and ") - def we_have_strings_string1_and_string2(string1, string2): - pass + @then("I should have ") + def should_have_left_fruits(start_fruits, start, eat, left, fruits): + assert isinstance(left, str) + assert start - eat == int(left) + assert start_fruits[fruits]["start"] == start + assert start_fruits[fruits]["eat"] == eat - - @then(" should be the base64 encoding of ") - def string2_should_be_base64_encoding_of_string1(string2, string1): - assert string1.encode() == base64.b64decode(string2.encode()) - """ + """ ) ) result = testdir.runpytest() - result.stdout.fnmatch_lines(["* 7 passed *"]) + result.assert_outcomes(passed=4) + + +def test_outline_with_escaped_pipes(testdir): + """Test parametrized feature example table with escaped pipe characters in input.""" + testdir.makefile( + ".feature", + outline=textwrap.dedent( + r"""\ + Feature: Outline With Special characters + + Scenario Outline: Outline with escaped pipe character + Given We have strings and + Then should be the base64 encoding of + + Examples: + | string1 | string2 | + | bork | Ym9yaw== | + | \|bork | fGJvcms= | + | bork \| | Ym9yayB8 | + | bork\|\|bork | Ym9ya3x8Ym9yaw== | + | \| | fA== | + | bork \\ | Ym9yayAgICAgIFxc | + | bork \\\| | Ym9yayAgICBcXHw= | + """ + ), + ) + + testdir.makepyfile( + textwrap.dedent( + """\ + import base64 + + from pytest_bdd import scenario, given, when, then + from pytest_bdd.utils import get_parametrize_markers_args + + + @scenario("outline.feature", "Outline with escaped pipe character") + def test_outline_with_escaped_pipe_character(request): + pass + + + @given("We have strings and ") + def we_have_strings_string1_and_string2(string1, string2): + pass + + + @then(" should be the base64 encoding of ") + def string2_should_be_base64_encoding_of_string1(string2, string1): + assert string1.encode() == base64.b64decode(string2.encode()) + + """ + ) + ) + result = testdir.runpytest() + result.assert_outcomes(passed=7) diff --git a/tests/feature/test_outline_empty_values.py b/tests/feature/test_outline_empty_values.py index 323b0f2..0285b80 100644 --- a/tests/feature/test_outline_empty_values.py +++ b/tests/feature/test_outline_empty_values.py @@ -1,6 +1,9 @@ """Scenario Outline with empty example values tests.""" -from pytest_bdd import given, scenario, then, when -from pytest_bdd.utils import get_parametrize_markers_args +import textwrap + + +STEPS = """\ +from pytest_bdd import given, when, then @given("there are cucumbers") @@ -17,12 +20,77 @@ def eat_cucumbers(eat): def should_have_left_cucumbers(left): pass - -@scenario("outline.feature", "Outlined with empty example values") -def test_scenario_with_empty_example_values(request): - assert get_parametrize_markers_args(request.node) == ([u"start", u"eat", u"left"], [["#", "", ""]]) +""" -@scenario("outline.feature", "Outlined with empty example values vertical") -def test_scenario_with_empty_example_values_vertical(request): - assert get_parametrize_markers_args(request.node) == ([u"start", u"eat", u"left"], [["#", "", ""]]) +def test_scenario_with_empty_example_values(testdir): + testdir.makefile( + ".feature", + outline=textwrap.dedent( + """\ + Feature: Outline + Scenario Outline: Outlined with empty example values + Given there are cucumbers + When I eat cucumbers + Then I should have cucumbers + + Examples: + | start | eat | left | + | # | | | + """ + ), + ) + testdir.makeconftest(textwrap.dedent(STEPS)) + + testdir.makepyfile( + textwrap.dedent( + """\ + from pytest_bdd.utils import get_parametrize_markers_args + from pytest_bdd import scenario + + @scenario("outline.feature", "Outlined with empty example values") + def test_outline(request): + assert get_parametrize_markers_args(request.node) == ([u"start", u"eat", u"left"], [["#", "", ""]]) + + """ + ) + ) + result = testdir.runpytest() + result.assert_outcomes(passed=1) + + +def test_scenario_with_empty_example_values_vertical(testdir): + testdir.makefile( + ".feature", + outline=textwrap.dedent( + """\ + Feature: Outline + Scenario Outline: Outlined with empty example values vertical + Given there are cucumbers + When I eat cucumbers + Then I should have cucumbers + + Examples: Vertical + | start | # | + | eat | | + | left | | + """ + ), + ) + testdir.makeconftest(textwrap.dedent(STEPS)) + + testdir.makepyfile( + textwrap.dedent( + """\ + from pytest_bdd.utils import get_parametrize_markers_args + from pytest_bdd import scenario + + @scenario("outline.feature", "Outlined with empty example values vertical") + def test_outline(request): + assert get_parametrize_markers_args(request.node) == ([u"start", u"eat", u"left"], [["#", "", ""]]) + + """ + ) + ) + result = testdir.runpytest() + result.assert_outcomes(passed=1) diff --git a/tests/library/child/__init__.py b/tests/library/child/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/library/child/conftest.py b/tests/library/child/conftest.py deleted file mode 100644 index 1eaf9af..0000000 --- a/tests/library/child/conftest.py +++ /dev/null @@ -1,6 +0,0 @@ -from pytest_bdd import given - - -@given("I have the overriden fixture") -def overridable(): - return "child" diff --git a/tests/library/child/test_local_override.py b/tests/library/child/test_local_override.py deleted file mode 100644 index e9b98fd..0000000 --- a/tests/library/child/test_local_override.py +++ /dev/null @@ -1,36 +0,0 @@ -"""Test givens declared in the parent conftest and plugin files. - -Check the parent given steps are collected, override them locally. -""" - -from pytest_bdd import given -from pytest_bdd.steps import get_step_fixture_name, GIVEN - - -@given("I have locally overriden fixture") -def overridable(): - return "local" - - -@given("I have locally overriden parent fixture") -def parent(): - return "local" - - -def test_override(request, overridable): - """Test locally overriden fixture.""" - - # Test the fixture is also collected by the text name - fixture = request.getfixturevalue(get_step_fixture_name("I have locally overriden fixture", GIVEN)) - assert fixture(request) == "local" - - # 'I have the overriden fixture' stands for overridable and is overriden locally - fixture = request.getfixturevalue(get_step_fixture_name("I have the overriden fixture", GIVEN)) - assert fixture(request) == "local" - - assert overridable == "local" - - -def test_parent(parent): - """Test locally overriden parent fixture.""" - assert parent == "local" diff --git a/tests/library/child/test_parent_override.py b/tests/library/child/test_parent_override.py deleted file mode 100644 index 8f2545a..0000000 --- a/tests/library/child/test_parent_override.py +++ /dev/null @@ -1,14 +0,0 @@ -"""Test givens declared in the parent conftest and plugin files. - -Check the parent givens are collected and overriden in the local conftest. -""" - - -def test_parent(parent): - """Test parent given is collected.""" - assert parent == "parent" - - -def test_override(overridable): - """Test the child conftest overriding the fixture.""" - assert overridable == "child" diff --git a/tests/library/conftest.py b/tests/library/conftest.py deleted file mode 100644 index 56d0a26..0000000 --- a/tests/library/conftest.py +++ /dev/null @@ -1,11 +0,0 @@ -from pytest_bdd import given - - -@given("I have parent fixture") -def parent(): - return "parent" - - -@given("I have overridable parent fixture") -def overridable(): - return "parent" diff --git a/tests/library/test_parent.py b/tests/library/test_parent.py index 3059072..99f94ca 100644 --- a/tests/library/test_parent.py +++ b/tests/library/test_parent.py @@ -2,18 +2,190 @@ Check the parent givens are collected and overriden in the local conftest. """ -from pytest_bdd.steps import get_step_fixture_name, WHEN +import textwrap -def test_parent(parent, overridable): +def test_parent(testdir): """Test parent given is collected. Both fixtures come from the parent conftest. """ - assert parent == "parent" - assert overridable == "parent" + testdir.makeconftest( + textwrap.dedent( + """\ + from pytest_bdd import given -def test_global_when_step(request): + @given("I have parent fixture") + def parent(): + return "parent" + + + @given("I have overridable parent fixture") + def overridable(): + return "parent" + + """ + ) + ) + + testdir.makepyfile( + textwrap.dedent( + """\ + def test_parent(parent, overridable): + assert parent == "parent" + assert overridable == "parent" + + """ + ) + ) + result = testdir.runpytest() + result.assert_outcomes(passed=1) + + +def test_global_when_step(testdir, request): """Test when step defined in the parent conftest.""" - request.getfixturevalue(get_step_fixture_name("I use a when step from the parent conftest", WHEN)) + + testdir.makeconftest( + textwrap.dedent( + """\ + from pytest_bdd import when + + + @when("I use a when step from the parent conftest") + def global_when(): + pass + + """ + ) + ) + + subdir = testdir.mkpydir("subdir") + + subdir.join("test_library.py").write( + textwrap.dedent( + """\ + from pytest_bdd.steps import get_step_fixture_name, WHEN + + def test_global_when_step(request): + assert request.getfixturevalue( + get_step_fixture_name("I use a when step from the parent conftest", + WHEN, + ) + ) + """ + ) + ) + result = testdir.runpytest() + result.assert_outcomes(passed=1) + + +def test_child(testdir): + """Test the child conftest overriding the fixture.""" + testdir.makeconftest( + textwrap.dedent( + """\ + from pytest_bdd import given + + + @given("I have parent fixture") + def parent(): + return "parent" + + + @given("I have overridable parent fixture") + def overridable(): + return "parent" + + """ + ) + ) + + subdir = testdir.mkpydir("subdir") + + subdir.join("conftest.py").write( + textwrap.dedent( + """\ + from pytest_bdd import given + + @given("I have overridable parent fixture") + def overridable(): + return "child" + + """ + ) + ) + + subdir.join("test_library.py").write( + textwrap.dedent( + """\ + def test_override(parent, overridable): + assert parent == "parent" + assert overridable == "child" + + """ + ) + ) + result = testdir.runpytest() + result.assert_outcomes(passed=1) + + +def test_local(testdir): + """Test locally overridden fixtures.""" + testdir.makeconftest( + textwrap.dedent( + """\ + from pytest_bdd import given + + + @given("I have parent fixture") + def parent(): + return "parent" + + + @given("I have overridable parent fixture") + def overridable(): + return "parent" + + """ + ) + ) + + subdir = testdir.mkpydir("subdir") + + subdir.join("test_library.py").write( + textwrap.dedent( + """\ + from pytest_bdd import given + from pytest_bdd.steps import get_step_fixture_name, GIVEN + + + @given("I have locally overriden fixture") + def overridable(): + return "local" + + + @given("I have locally overriden parent fixture") + def parent(): + return "local" + + + def test_local(request, parent, overridable): + assert parent == "local" + assert overridable == "local" + + fixture = request.getfixturevalue( + get_step_fixture_name("I have locally overriden fixture", GIVEN) + ) + assert fixture(request) == "local" + + fixture = request.getfixturevalue( + get_step_fixture_name("I have locally overriden parent fixture", GIVEN) + ) + assert fixture(request) == "local" + + """ + ) + ) + result = testdir.runpytest() + result.assert_outcomes(passed=1) diff --git a/tests/steps/test_given.py b/tests/steps/test_given.py index d003be0..ca9b624 100644 --- a/tests/steps/test_given.py +++ b/tests/steps/test_given.py @@ -1,10 +1,6 @@ """Given tests.""" -import pytest import textwrap -from pytest_bdd import given, then, scenario -from pytest_bdd.steps import StepError - def test_root_alias(testdir): testdir.makefile(