Tutorials ========= Getting started with ``pytest_container`` ----------------------------------------- .. note:: The following tutorial demonstrates how to use ``pytest_container`` for a Python project and to test the project's Command-line interface. The example uses `poetry `_ to manage the Python dependencies. If the :file:`pyproject.toml` doesn't already exist, create it using the :command:`poetry init` command. Start by adding ``pytest_container`` as a development dependency: .. code-block:: shell-session ❯ poetry add --group dev pytest_container Add `pytest-xdist `_, so that tests can be executed in parallel: .. code-block:: shell-session ❯ poetry add --group dev pytest-xdist It is recommended to create a new directory :file:`tests` for your tests to keep things tidy. Add an empty file called :file:`tests/__init__.py`. Create the :file:`tests/conftest.py` file with the following contents: .. code-block:: python from pytest_container import auto_container_parametrize def pytest_generate_tests(metafunc): auto_container_parametrize(metafunc) The above code snippet ensures that the ``auto_container`` and ``auto_container_per_test`` fixtures work correctly (that is, they use the images defined in ``CONTAINER_IMAGES``). We can now implement the actual tests. We will create a simple smoke test where we install the python wheel of our project inside a container and then check that the installed command line utility works as expected. For that, we will start out with the following :file:`Dockerfile`. There we base our image on openSUSE Tumbleweed, install :command:`pip` into it, copy the wheel of our python project into the image and install it in the container: .. code-block:: Dockerfile FROM registry.opensuse.org/opensuse/tumbleweed RUN zypper -n in python3-pip COPY dist/*whl . RUN pip install *whl Plug the :file:`Dockerfile` into ``pytest_container`` using the :py:class:`~pytest_container.container.DerivedContainer` class as follows: .. code-block:: python from textwrap import dedent from pytest_container import DerivedContainer TW_WITH_PKG = DerivedContainer( base="registry.opensuse.org/opensuse/tumbleweed", containerfile=dedent(""" RUN zypper -n in python3-pip COPY dist/*whl . RUN pip install *whl """) ) Note that the ``FROM`` line is omitted from the :py:attr:`~pytest_container.container.DerivedContainer.containerfile` parameter, as ``pytest_container`` includes it automatically. Add the above snippet to a new file :file:`tests/test_cli.py`, and add the following test function along with a global variable: .. code-block:: python CONTAINER_IMAGES = [TW_WITH_PKG] def test_help_works(auto_container): res = auto_container.connection.run_expect([0], "my-binary --help") assert "My cool project" in res.stdout The global variable ``CONTAINER_IMAGES`` instructs ``pytest_container`` to run all test functions that use the ``auto_container`` or ``auto_container_per_test`` fixtures once for each image defined in that list. This allows you to have a single file with multiple of tests that to be executed inside multiple container images, thus avoiding the task of parametrizing each of the test manually. The test function receives a :py:class:`~pytest_container.container.ContainerData` instance, where the :py:attr:`~pytest_container.container.ContainerData.connection` attribute provides a ``testinfra`` connection. The `run_expect `_ function is used to execute the binary and check that its exit code is ``0``. Afterwards, we check that a search string is in the standard output. You can now execute this test via :command:`poetry run pytest`.