Package: testinfra-bdd
testinfra-bddAn interface betweenpytest-bddandpytest-testinfra.Defining ScenariosGiven a directory structure of:"."└──"tests"├──"features"│├──"example.feature"└──"step_defs"└──"test_example.py"The filetests/features/example.featurecould look something like:Feature:Example of Testinfra BDDGive an example of all the possible Given, When and Then steps.The Given steps to skip the address and port tests when running underGitHub actions are not part of the testinfra-bdd package itself, but arerequired as GitHub/Azure does not allow Ping/ICMP traffic.Scenario:Skip Tests if Host is WindozeGiventhe TestInfra host with URL "docker://sut" is ready within10seconds# The system property can be one of:#   - type (e.g. linux).#   - distribution (e.g. debian).#   - release (e.g. 11).#   - codename (e.g. bullseye).#   - arch (e.g. x86_64).#   - hostname (e.g. sut).#   - connection_type (e.g. docker or ssh).Whenthe TestInfra system property type is not Windoze skip testsScenario Outline:Test for Absent ResourcesGiventhe TestInfra host with URL "docker://sut" is ready within10secondsWhenthe TestInfra<resource_type>is "foo"Thenthe TestInfra<resource_type>is absentExamples:|resource_type||user||group||package||file||pip package|Scenario Outline:Test for Absent Non-Quoted Resources# Same as the example above except the resources are not quoted.Giventhe TestInfra host with URL "docker://sut" is ready within10secondsWhenthe TestInfra<resource_type>is fooThenthe TestInfra<resource_type>state is absentExamples:|resource_type||user||group||package||file||pip package|Scenario:User ChecksGiventhe TestInfra host with URL "docker://sut" is readyWhenthe TestInfra user is "ntp"Thenthe TestInfra user is present# Alternative method of checking the state of a resource.Andthe TestInfra user state is presentAndthe TestInfra user group is ntpAndthe TestInfra user uid is101Andthe TestInfra user gid is101Andthe TestInfra user home is /nonexistentAndthe TestInfra user shell is /usr/sbin/nologinScenario:File ChecksGiventhe TestInfra host with URL "docker://sut" is readyWhenthe TestInfra file is /etc/ntp.conf# Expected state can be present or absent.Thenthe TestInfra file is present# Alternative method of checking the state of a resource.Andthe TestInfra file state is present# Valid types to check for are file, directory, pipe, socket or symlink.Andthe TestInfra file type is fileAndthe TestInfra file owner is ntpAndthe TestInfra file group is ntpAndthe TestInfra file contents contains "debian.pool.ntp"Andthe TestInfra file contents contains the regex ".*pool [0-9].debian.pool.ntp.org iburst"# The expected mode must be specified as an octal.Andthe TestInfra file mode is0o544Scenario:File Executable ChecksGiventhe TestInfra host with URL "docker://sut" is readyWhenthe TestInfra file is /bin/lsThenthe TestInfra file is presentAndthe TestInfra file is executableScenario:Group ChecksGiventhe TestInfra host with URL "docker://sut" is readyWhenthe TestInfra group is "ntp"# Can check if the group is present or absent.Thenthe TestInfra group is present# Alternative method of checking the state of a resource.Andthe TestInfra group state is presentAndthe TestInfra group gid is101Scenario:Group MembershipGiventhe TestInfra host with URL "docker://sut" is readyWhenthe TestInfra group is "sudo"Andthe TestInfra user is "bar"Thenthe TestInfra group contains the user "bar"Andthe TestInfra user groups include "sudo"Scenario:Running CommandsGiventhe TestInfra host with URL "docker://sut" is readyWhenthe TestInfra command is "ntpq -np"Thenthe TestInfra command return code is0Andthe TestInfra command "ntpq" exists in pathAndthe TestInfra command stdout contains "remote"Andthe TestInfra command stdout does not contain "foo"Scenario:System PackageGiventhe TestInfra host with URL "docker://sut" is readyWhenthe TestInfra package is ntp# Can check if the package is absent, present or installed.Thenthe TestInfra package is installedScenario:Python PackageGiventhe TestInfra host with URL "docker://sut" is readyWhenthe TestInfra pip package is testinfra-bdd# Can check if the package is absent or present.Thenthe TestInfra pip package is presentAndthe TestInfra pip package version is3.0.0# Check that installed packages have compatible dependencies.Andthe TestInfra pip check is OKScenario Outline:Service ChecksGiventhe TestInfra host with URL "docker://sut" is readyWhenthe TestInfra service is<service>Thenthe TestInfra service is<running_state>Andthe TestInfra service is<enabled_state>Examples:|service|running_state|enabled_state||ntp|running|enabled||named|not running|not enabled|Scenario:Test Running ProcessesGiventhe TestInfra host with URL "docker://sut" is ready# Processes are selected using filter() attributes names are# described in the ps man page.Whenthe TestInfra process filter is "user=root,comm=ntpd"Thenthe TestInfra process count is1Scenario Outline:Test Pip Packages are Latest VersionsGiventhe TestInfra host with URL "docker://sut" is readyWhenthe TestInfra pip package is<pip_package>Thenthe TestInfra pip package is presentAndthe TestInfra pip package is<status>Examples:|pip_package|status||pytest-bdd|latest||pytest-testinfra|latest||testinfra-bdd|latest|Scenario Outline:Check Sockets# This checks that NTP is listening but SSH isn't.# The socket url is defined at https://testinfra.readthedocs.io/en/latest/modules.html#socketGiventhe TestInfra host with URL "docker://sut" is ready within10secondsWhenthe TestInfra socket is<url>Thenthe TestInfra socket is<expected_state>Examples:|url|expected_state||udp://123|listening||tcp://22|not listening|Scenario:Skip Tests Due to Environment VariableGiventhe TestInfra host with URL "docker://java11" is readyWhenthe TestInfra environment variable PYTHONPATH is .:.. skip testsScenario:Check Network AddressGiventhe TestInfra host with URL "docker://sut" is ready within10secondsWhenthe TestInfra environment variable GITHUB_ACTIONS is true skip testsAndthe TestInfra address is www.google.comThenthe TestInfra address is resolvableAndthe TestInfra address is reachableScenario:Check Network Address With PortGiventhe TestInfra host with URL "docker://sut" is ready within10secondsWhenthe TestInfra environment variable GITHUB_ACTIONS is true skip testsAndthe TestInfra address and port is www.google.com:443Thenthe TestInfra address is resolvableAndthe TestInfra address is reachableAndthe TestInfra port is reachableScenario:Check Java is Installed in the PathGiventhe TestInfra host with URL "docker://java11" is ready within10secondsThenthe TestInfra command "java" exists in pathScenario:Check Java 11 is InstalledGiventhe TestInfra host with URL "docker://java11" is readyWhenthe TestInfra command is "java -version"Andthe TestInfra package is java-11-amazon-corretto-develThenthe TestInfra command stderr contains "Corretto-11"Andthe TestInfra command stderr contains the regex "openjdk version \"11\\W[0-9]"And the TestInfra command stdout is emptyAnd the TestInfra command return code is 0And the TestInfra package is installedScenario: Check for an Expected Value# In this example we set the expected_value to"foo"Given the TestInfra host with URL"docker://sut"is readyAnd the TestInfra expected value is"foo"When the TestInfra command is"echo foo"Then the TestInfra command stdout contains the expected valueScenario Outline: Check Contents of JSON File With JMESPathGiven the TestInfra host with URL"docker://sut"is readyWhen the TestInfra file is /tmp/john-smith.jsonThen the TestInfra JMESPath expression<expression>returns<expected_value>Examples:| expression    | expected_value || firstName     | John           || lastName      | Smith          || age           | 27             || address.state | NY             || spouse        | None           |andtests/step_defs/test_example.pycontains the following:"""Examples of step definitions for Testinfra BDD feature tests."""importtestinfra_bddfrompytest_bddimportgiven,scenariosscenarios('../features/example.feature')# Ensure that the PyTest fixtures provided in testinfra-bdd are available to# your test suite.pytest_plugins=testinfra_bdd.PYTEST_MODULES@given('the TestInfra expected value is "foo"',target_fixture='expected_value')defthe_expected_value_is_foo():"""The expected value is "foo".The name and code is up to the user to develop.  However, the targetfixture must be called 'expected_value'."""return'foo'"Given" StepsGiven steps require that the URL of the system to be tested (SUT) is provided.
This URL should comply to the connection string for theTestinfra connection
string(e.g.
docker://my-host).  Please note that the URLmustbe enclosed in double
quotes.Examples:To connect to a Docker container called sut (fail if the target host is
not ready):Giventhe TestInfra host with URL "docker://java11" is readyTo connect to a Docker container called sut but give it 60 seconds to become
ready, use the following:Giventhe TestInfra host with URL "docker://sut" is ready within60secondsIf the host does not become available after 60 seconds, fail the tests.Writing a customized "Given" StepIt may be that you may want to create a customized "Given" step.  An example
could be that the hosts to be tested may be parametrized.  The "Given" step
must return a target fixture called "testinfra_bdd_host" so that the rest of
the Testinfra BDD fixtures will function.  This fixture is a instance of thetestinfra_bdd.The "Given" step should also ascertain that the target host is ready (one
can use theis_host_readyfunction for that).An example is:frompytest_bddimportgivenfromtestinfra_bddimportTestinfraBDD@given('my host is ready',target_fixture='testinfra_bdd_host')defmy_host_is_ready():"""Specify that the target host is a docker container called"my-host" and wait up to 60 seconds for the host to be ready."""host=TestinfraBDD('docker://my-host')asserthost.is_host_ready(60),'My host is not ready.'returnhost..."When" StepsWhen steps require that a "Given" step has been executed beforehand.  They
allow the user to either skip tests if the host does not match an expected
profile.  They also allow the user to specify which resource or is to be
tested.Skip Tests if Host Profile Does Not MatchIt may be useful to skip tests if you find that the system under test doesn't
match an expected profile (e.g. the system is not debian as expected).  This
can be achieved by comparing against the following configurations:The OS Type (e.g. linux).The distribution name (e.g. debian).The OS release (e.g. 11).The OS codename if relevant (e.g. bullseye).The host architecture (e.g. x86_64).The hostname (e.g. sut)Example:Scenario:Skip Tests if Host is WindozeGiventhe TestInfra host with URL "docker://sut" is ready within10secondsWhenthe TestInfra system property type is not Windoze skip testsUpgrading from 2.Y.Z to 3.0.0We introduced a number of breaking changes, namely:A change to the Domain Specific Language (DSL).Moving to TestInfra 9 and dropping support for 6, 7 and 8.Dropping support for EOL versions of Python (3.6, 3.7 and 3.8).The changes for the DSL are pretty basic.  We identified a need to namespace
the TestInfra tests to stop clashes with other BDD feature code.  If your
old code looked something like:Scenario:System PackageGiventhe host with URL "docker://sut" is readyWhenthe package is ntpThenthe package is installedThen change the code to:Scenario:System PackageGiventhe TestInfra host with URL "docker://sut" is readyWhenthe TestInfra package is ntpThenthe TestInfra package is installedAll example code above has been updated to the new format for guidance.Upgrading from 1.Y.Z to 2.0.0We split the single package into multiple source files.  This means a minor
but nonetheless breaking change in your step definitions (all feature files
can remain as they are).  The change is how one setspytest_plugins.Old Codepytest_plugins=['testinfra_bdd']New Codepytest_plugins=testinfra_bdd.PYTEST_MODULES