def test_scenario_not_found(testdir, pytest_params): """Test the situation when scenario is not found.""" testdir.makefile( ".feature", not_found=textwrap.dedent( """\ Feature: Scenario is not found """ ), ) testdir.makepyfile( textwrap.dedent( """\ import re import pytest from pytest_bdd import parsers, given, then, scenario @scenario("not_found.feature", "NOT FOUND") def test_not_found(): pass """ ) ) result = testdir.runpytest_subprocess(*pytest_params) assert_outcomes(result, errors=1) result.stdout.fnmatch_lines('*Scenario "NOT FOUND" in feature "Scenario is not found" in*')
def test_wrong_vertical_examples_feature(testdir): """Test parametrized feature vertical example table has wrong format.""" 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 <start> cucumbers When I eat <eat> cucumbers Then I should have <left> cucumbers """), ) testdir.makeconftest(textwrap.dedent(STEPS)) 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() assert_outcomes(result, errors=1) result.stdout.fnmatch_lines( "*Feature has not valid examples. Example rows should contain unique parameters. " '"start" appeared more than once.*')
def test_scenarios_none_found(testdir, pytest_params): """Test scenarios shortcut when no scenarios found.""" testpath = testdir.makepyfile(""" import pytest from pytest_bdd import scenarios scenarios('.') """) result = testdir.runpytest_subprocess(testpath, *pytest_params) assert_outcomes(result, errors=1) result.stdout.fnmatch_lines(["*NoScenariosFound*"])
def test_generate_missing_with_step_parsers(testdir): """Test that step parsers are correctly discovered and won't be part of the missing steps.""" testdir.makefile( ".feature", generation=textwrap.dedent("""\ Feature: Missing code generation with step parsers Scenario: Step parsers are correctly discovered Given I use the string parser without parameter And I use parsers.parse with parameter 1 And I use parsers.re with parameter 2 And I use parsers.cfparse with parameter 3 """), ) testdir.makepyfile( textwrap.dedent("""\ import functools from pytest_bdd import scenarios, given, parsers scenarios("generation.feature") @given("I use the string parser without parameter") def i_have_a_bar(): return None @given(parsers.parse("I use parsers.parse with parameter {param}")) def i_have_n_baz(param): return param @given(parsers.re(r"^I use parsers.re with parameter (?P<param>.*?)$")) def i_have_n_baz(param): return param @given(parsers.cfparse("I use parsers.cfparse with parameter {param:d}")) def i_have_n_baz(param): return param """)) result = testdir.runpytest("--generate-missing", "--feature", "generation.feature") assert_outcomes(result, passed=0, failed=0, errors=0) assert not result.stderr.str() assert result.ret == 0 output = result.stdout.str() assert "I use the string parser" not in output assert "I use parsers.parse" not in output assert "I use parsers.re" not in output assert "I use parsers.cfparse" not in output
def test_multiple_features_single_file(testdir): """Test validation error when multiple features are placed in a single file.""" testdir.makefile( ".feature", wrong=textwrap.dedent("""\ Feature: Feature One Background: Given I have A And I have B Scenario: Do something with A When I do something with A Then something about B Feature: Feature Two Background: Given I have A Scenario: Something that just needs A When I do something else with A Then something else about B Scenario: Something that needs B again Given I have B When I do something else with B Then something else about A and B """), ) testdir.makepyfile( textwrap.dedent("""\ import pytest from pytest_bdd import then, scenario @scenario("wrong.feature", "Do something with A") def test_wrong(): pass """)) result = testdir.runpytest() assert_outcomes(result, errors=1) result.stdout.fnmatch_lines( "*FeatureError: Multiple features are not allowed in a single feature file.*" )
def test_wrongly_outlined(testdir): """Test parametrized scenario when the test function lacks parameters.""" testdir.makefile( ".feature", outline=textwrap.dedent("""\ Feature: Outline Scenario Outline: Outlined with wrong examples Given there are <start> cucumbers When I eat <eat> cucumbers Then I should have <left> 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 test_outline(request): pass """)) result = testdir.runpytest() assert_outcomes(result, errors=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_generate_missing(testdir): """Test generate missing command.""" testdir.makefile( ".feature", generation=textwrap.dedent("""\ Feature: Missing code generation Background: Given I have a foobar Scenario: Scenario tests which are already bound to the tests stay as is Given I have a bar Scenario: Code is generated for scenarios which are not bound to any tests Given I have a bar Scenario: Code is generated for scenario steps which are not yet defined(implemented) Given I have a custom bar """), ) testdir.makepyfile( textwrap.dedent("""\ import functools from pytest_bdd import scenario, given scenario = functools.partial(scenario, "generation.feature") @given("I have a bar") def i_have_a_bar(): return "bar" @scenario("Scenario tests which are already bound to the tests stay as is") def test_foo(): pass @scenario("Code is generated for scenario steps which are not yet defined(implemented)") def test_missing_steps(): pass """)) result = testdir.runpytest("--generate-missing", "--feature", "generation.feature") assert_outcomes(result, passed=0, failed=0, errors=0) assert not result.stderr.str() assert result.ret == 0 result.stdout.fnmatch_lines([ 'Scenario "Code is generated for scenarios which are not bound to any tests" is not bound to any test *' ]) result.stdout.fnmatch_lines([ 'Step Given "I have a custom bar" is not defined in the scenario ' '"Code is generated for scenario steps which are not yet defined(implemented)" *' ]) result.stdout.fnmatch_lines([ 'Step Given "I have a foobar" is not defined in the background of the feature "Missing code generation" *' ]) result.stdout.fnmatch_lines( ["Please place the code above to the test file(s):"])
def test_scenarios(testdir, pytest_params): """Test scenarios shortcut (used together with @scenario for individual test override).""" testdir.makeini(""" [pytest] console_output_style=classic """) testdir.makeconftest(""" import pytest from pytest_bdd import given @given('I have a bar') def i_have_bar(): print('bar!') return 'bar' """) features = testdir.mkdir("features") features.join("test.feature").write_text( textwrap.dedent(""" Scenario: Test scenario Given I have a bar """), "utf-8", ensure=True, ) features.join("subfolder", "test.feature").write_text( textwrap.dedent(""" Scenario: Test subfolder scenario Given I have a bar Scenario: Test failing subfolder scenario Given I have a failing bar Scenario: Test already bound scenario Given I have a bar Scenario: Test scenario Given I have a bar """), "utf-8", ensure=True, ) testdir.makepyfile(""" import pytest from pytest_bdd import scenarios, scenario @scenario('features/subfolder/test.feature', 'Test already bound scenario') def test_already_bound(): pass scenarios('features') """) result = testdir.runpytest_subprocess("-v", "-s", *pytest_params) assert_outcomes(result, passed=4, failed=1) result.stdout.fnmatch_lines(["*collected 5 items"]) result.stdout.fnmatch_lines( ["*test_test_subfolder_scenario *bar!", "PASSED"]) result.stdout.fnmatch_lines(["*test_test_scenario *bar!", "PASSED"]) result.stdout.fnmatch_lines( ["*test_test_failing_subfolder_scenario *FAILED"]) result.stdout.fnmatch_lines(["*test_already_bound *bar!", "PASSED"]) result.stdout.fnmatch_lines(["*test_test_scenario_1 *bar!", "PASSED"])