diff --git a/README.md b/README.md index f4e541f9..177c0244 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ The repository contains adaptors for Python-based test frameworks. Documentation is available [online](https://docs.qameta.io/allure-report/), also you can get help at -[gitter channel](https://gitter.im/allure-framework/allure-core) +[gitter channel](https://gitter.im/allure-framework/allure-core). ## Pytest [![Release @@ -13,7 +13,9 @@ Status](https://img.shields.io/pypi/v/allure-pytest)](https://pypi.python.org/py Allure [pytest](http://pytest.org) integration. It's developed as pytest plugin and distributed via -[pypi](https://pypi.python.org/pypi/allure-pytest) +[pypi](https://pypi.python.org/pypi/allure-pytest). + +Examples are available [here](allure-pytest/examples). ## Behave [![Release diff --git a/allure-behave/README.rst b/allure-behave/README.rst index cfbcf9ae..179bcef6 100644 --- a/allure-behave/README.rst +++ b/allure-behave/README.rst @@ -1,9 +1,9 @@ Allure Behave Formatter ======================= -.. image:: https://pypip.in/v/allure-behave/badge.png +.. image:: https://img.shields.io/pypi/v/allure-behave :alt: Release Status :target: https://pypi.python.org/pypi/allure-behave -.. image:: https://pypip.in/d/allure-behave/badge.png +.. image:: https://img.shields.io/pypi/dm/allure-behave :alt: Downloads :target: https://pypi.python.org/pypi/allure-behave diff --git a/allure-pytest/README.rst b/allure-pytest/README.rst index 3a7c9e27..64a73fd0 100644 --- a/allure-pytest/README.rst +++ b/allure-pytest/README.rst @@ -1,9 +1,9 @@ Allure Pytest Plugin ==================== -.. image:: https://pypip.in/v/allure-pytest/badge.png +.. image:: https://img.shields.io/pypi/v/allure-pytest :alt: Release Status :target: https://pypi.python.org/pypi/allure-pytest -.. image:: https://pypip.in/d/allure-pytest/badge.png +.. image:: https://img.shields.io/pypi/dm/allure-pytest :alt: Downloads :target: https://pypi.python.org/pypi/allure-pytest diff --git a/allure-pytest/examples/parameter/dynamic_parameter.rst b/allure-pytest/examples/parameter/dynamic_parameter.rst new file mode 100644 index 00000000..0723c048 --- /dev/null +++ b/allure-pytest/examples/parameter/dynamic_parameter.rst @@ -0,0 +1,74 @@ +Dynamic parameter +------------------- + +It's possible to dynamically add a parameter to a test result: + + + >>> import allure + + >>> def test_dynamic_parameter(): + ... allure.dynamic.parameter("username", "John Doe") + + +The parameter name and value are shown in the "Parameters" section of the test +details view. Additionally, the value is shown near the test name in the test +tree view. + + +Affecting the history of test execution in Allure TestOps +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Parameters also affect how Allure TestOps keeps history and retry records +across test results. Two test results that differs from each other in a +parameter value are considered as belonging to different test cases, thus +forming separate histories. + +This behavior can be changed with ``excluded`` argument: + + + >>> import allure + ... import os + + >>> def test_excluded_dynamic_parameter(): + ... allure.dynamic.parameter("work-dir", os.getcwd(), excluded=True) + + +Such a parameter isn't taken into account by Allure TestOps when it decides +whether two test results actually belong to a single test case. This is useful +if you want to add environment-related information (such as host names, OS, PID, +paths, versions, etc.) but keep history the same if the information is changed. + + +Masking a sensitive parameter +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A parameter value can be masked with ``mode`` argument. The masked value is shown +as ``******`` in the report. This is useful for sensitive parameters like +passwords or key phrases: + + + >>> import allure + + >>> def test_masked_dynamic_parameter(): + ... allure.dynamic.parameter("password", "qwerty", mode=allure.parameter_mode.MASKED) + + +WARNING: Although the value is masked in the report, it is still present in the +test result files (but not in report files, i.e., the files generated by +allure reporter). + + +Hiding a parameter from the report +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +A parameter can be hidden from the report completely. It still affects the +history of the test case though. This is useful if you want to force Allure +TestOps to distribute otherwise indistinguishable test results across different +test cases: + + + >>> import allure + ... import socket + + >>> def test_hidden_dynamic_parameter(): + ... allure.dynamic.parameter("hostname", socket.gethostname(), mode=allure.parameter_mode.HIDDEN) diff --git a/allure-pytest/test/acceptance/parametrization/dynamic_parameter_test.py b/allure-pytest/test/acceptance/parametrization/dynamic_parameter_test.py new file mode 100644 index 00000000..919321f0 --- /dev/null +++ b/allure-pytest/test/acceptance/parametrization/dynamic_parameter_test.py @@ -0,0 +1,60 @@ +""" ./examples/parameter/dynamic_parameter.rst """ + +from hamcrest import assert_that +from allure_commons_test.report import has_test_case +from allure_commons_test.result import ( + has_parameter, + get_parameter_matcher, + with_excluded, + with_mode +) + + +def test_dynamic_parameter(executed_docstring_path): + assert_that( + executed_docstring_path.allure_report, + has_test_case( + "test_dynamic_parameter", + has_parameter("username", "'John Doe'") + ) + ) + + +def test_masked_dynamic_parameter(executed_docstring_path): + assert_that( + executed_docstring_path.allure_report, + has_test_case( + "test_masked_dynamic_parameter", + has_parameter( + "password", + "'qwerty'", + with_mode("masked") + ) + ) + ) + + +def test_hidden_dynamic_parameter(executed_docstring_path): + assert_that( + executed_docstring_path.allure_report, + has_test_case( + "test_hidden_dynamic_parameter", + get_parameter_matcher( + "hostname", + with_mode("hidden") + ) + ) + ) + + +def test_excluded_dynamic_parameter(executed_docstring_path): + assert_that( + executed_docstring_path.allure_report, + has_test_case( + "test_excluded_dynamic_parameter", + get_parameter_matcher( + "work-dir", + with_excluded() + ) + ) + ) diff --git a/allure-python-commons-test/src/result.py b/allure-python-commons-test/src/result.py index 87ee0e0e..969ea442 100644 --- a/allure-python-commons-test/src/result.py +++ b/allure-python-commons-test/src/result.py @@ -91,15 +91,24 @@ def has_step(name, *matchers): )) +def get_parameter_matcher(name, *matchers): + return has_entry( + 'parameters', + has_item( + all_of( + has_entry('name', equal_to(name)), + *matchers + ) + ) + ) + + def has_parameter(name, value, *matchers): - return has_entry('parameters', - has_item( - all_of( - has_entry('name', equal_to(name)), - has_entry('value', equal_to(value)), - *matchers - ) - )) + return get_parameter_matcher( + name, + has_entry('value', equal_to(value)), + *matchers + ) def doesnt_have_parameter(name): diff --git a/allure-robotframework/README.rst b/allure-robotframework/README.rst index a4b8ec64..2c17149f 100644 --- a/allure-robotframework/README.rst +++ b/allure-robotframework/README.rst @@ -1,9 +1,9 @@ Allure Robot Framework Listener =============================== -.. image:: https://pypip.in/v/allure-robotframework/badge.png +.. image:: https://img.shields.io/pypi/v/allure-robotframework :alt: Release Status :target: https://pypi.python.org/pypi/allure-robotframework -.. image:: https://pypip.in/d/allure-robotframework/badge.png +.. image:: https://img.shields.io/pypi/dm/allure-robotframework :alt: Downloads :target: https://pypi.python.org/pypi/allure-robotframework