From 8209470b27b243773e6947d84d2d6ca76ab8a231 Mon Sep 17 00:00:00 2001 From: Anatoly Bubenkov Date: Thu, 4 Jun 2015 14:01:36 +0200 Subject: [PATCH] Make feature and scenario tags to be fully compartible with pytest markers. closes #112 --- CHANGES.rst | 5 +++ README.rst | 9 +++-- pytest_bdd/__init__.py | 2 +- pytest_bdd/feature.py | 2 +- tests/feature/tags.feature | 6 ++-- tests/feature/test_cucumber_json.py | 6 ++-- tests/feature/test_tags.py | 52 +++++++++++++++++++++++++---- 7 files changed, 65 insertions(+), 17 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index ad901c5..2d82ad2 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,11 @@ Changelog ========= +2.10.0 +------ + +- Make feature and scenario tags to be fully compartible with pytest markers (bubenkoff, kevinastone) + 2.9.1 ----- diff --git a/README.rst b/README.rst index aab0b2d..98df821 100644 --- a/README.rst +++ b/README.rst @@ -646,11 +646,14 @@ scenario test, so we can use standard test selection: .. code-block:: bash - py.test -k "@backend and @login and @successful" + py.test -k "backend and login and successful" -The `@` helps to separate normal markers from the bdd ones. +The feature and scenario markers are not different from standard pytest markers, and the `@` symbol is stripped out +automatically to allow test selector expressions. If you want to have bdd-related tags to be distinguishable from the +other test markers, use prefix like `bdd`. Note that if you use pytest `--strict` option, all bdd tags mentioned in the feature files should be also in the -`markers` setting of the `pytest.ini` config. +`markers` setting of the `pytest.ini` config. Also for tags please use names which are python-compartible variable +names, eg starts with a non-number, underscore alphanumberic, etc. That way you can safely use tags for tests filtering. Test setup diff --git a/pytest_bdd/__init__.py b/pytest_bdd/__init__.py index 7bbeb15..035f5aa 100644 --- a/pytest_bdd/__init__.py +++ b/pytest_bdd/__init__.py @@ -1,6 +1,6 @@ """pytest-bdd public API.""" -__version__ = '2.9.1' +__version__ = '2.10.0' try: from pytest_bdd.steps import given, when, then diff --git a/pytest_bdd/feature.py b/pytest_bdd/feature.py index a26e91d..20ee768 100644 --- a/pytest_bdd/feature.py +++ b/pytest_bdd/feature.py @@ -146,7 +146,7 @@ def get_tags(line): :return: List of tags. """ return ( - set((tag for tag in line.split() if tag.startswith("@") and len(tag) > 1)) + set((tag[1:] for tag in line.split() if tag.startswith("@") and len(tag) > 1)) if line else set() ) diff --git a/tests/feature/tags.feature b/tests/feature/tags.feature index da1ae98..dd07889 100644 --- a/tests/feature/tags.feature +++ b/tests/feature/tags.feature @@ -1,10 +1,10 @@ -@feature-tag-1 @feature-tag-2 +@feature_tag_1 @feature_tag_2 Feature: Tags - @scenario-tag-1 @scenario-tag-2 + @scenario_tag_1 @scenario_tag_2 Scenario: Tags Given I have a bar - @scenario-tag-10 @scenario-tag-20 + @scenario_tag_10 @scenario_tag_20 Scenario: Tags 2 Given I have a bar diff --git a/tests/feature/test_cucumber_json.py b/tests/feature/test_cucumber_json.py index 5c053ff..eb88019 100644 --- a/tests/feature/test_cucumber_json.py +++ b/tests/feature/test_cucumber_json.py @@ -110,7 +110,7 @@ def test_step_trace(testdir): ], "tags": [ { - 'name': '@scenario-passing-tag', + 'name': 'scenario-passing-tag', 'line': 4, } ], @@ -151,7 +151,7 @@ def test_step_trace(testdir): ], "tags": [ { - 'name': '@scenario-failing-tag', + 'name': 'scenario-failing-tag', 'line': 9, } ], @@ -164,7 +164,7 @@ def test_step_trace(testdir): "name": "One passing scenario, one failing scenario", "tags": [ { - 'name': '@feature-tag', + 'name': 'feature-tag', 'line': 1, } ], diff --git a/tests/feature/test_tags.py b/tests/feature/test_tags.py index c5676c8..7f3fbe7 100644 --- a/tests/feature/test_tags.py +++ b/tests/feature/test_tags.py @@ -11,13 +11,53 @@ def test_tags(request): def test(): pass - assert test.__scenario__.tags == set(['@scenario-tag-1', '@scenario-tag-2']) - assert test.__scenario__.feature.tags == set(['@feature-tag-1', '@feature-tag-2']) + assert test.__scenario__.tags == set(['scenario_tag_1', 'scenario_tag_2']) + assert test.__scenario__.feature.tags == set(['feature_tag_1', 'feature_tag_2']) - assert getattr(test, '@scenario-tag-1') - assert getattr(test, '@scenario-tag-2') + assert getattr(test, 'scenario_tag_1') + assert getattr(test, 'scenario_tag_2') - assert getattr(test, '@feature-tag-1') - assert getattr(test, '@feature-tag-2') + assert getattr(test, 'feature_tag_1') + assert getattr(test, 'feature_tag_2') test(request) + + +def test_tags_selector(testdir): + """Test tests selection by tags.""" + testdir.makefile('.feature', test=""" + @feature_tag_1 @feature_tag_2 + Feature: Tags + + @scenario_tag_01 @scenario_tag_02 + Scenario: Tags + Given I have a bar + + @scenario_tag_10 @scenario_tag_20 + Scenario: Tags 2 + Given I have a bar + + """) + testdir.makepyfile(""" + import pytest + from pytest_bdd import given, scenarios + + @given('I have a bar') + def i_have_bar(): + return 'bar' + + scenarios('test.feature') + """) + result = testdir.runpytest('-k', 'scenario_tag_10 and not scenario_tag_01', '-vv').parseoutcomes() + assert result['passed'] == 1 + assert result['deselected'] == 1 + + result = testdir.runpytest('-k', 'scenario_tag_01 and not scenario_tag_10', '-vv').parseoutcomes() + assert result['passed'] == 1 + assert result['deselected'] == 1 + + result = testdir.runpytest('-k', 'feature_tag_1', '-vv').parseoutcomes() + assert result['passed'] == 2 + + result = testdir.runpytest('-k', 'feature_tag_10', '-vv').parseoutcomes() + assert result['deselected'] == 2