跳转到主要内容

在集成测试期间管理Docker容器

项目描述

https://circleci.com/gh/pytest-docker-compose/pytest-docker-compose/tree/master.svg?style=svg

此软件包包含一个 pytest 插件,用于将Docker Compose集成到您的自动化集成测试中。

给定一个指向 docker-compose.yml 文件的路径,它将在测试运行开始时自动构建项目,在每个测试开始前启动容器,并在每个测试结束后将其拆解。

依赖关系

请确保已安装 Docker

此插件自动测试以下软件

  • Python 3.5和3.6。

  • pytest 3、4和5。

在本地,我已成功将其与Python 3.7进行了测试,但3.7难以集成到circleCI中,因此它不受官方支持。

安装

使用pip安装插件

> pip install pytest-docker-compose

用法

出于性能原因,插件默认未启用,因此您必须在使用它的测试中手动激活它

pytest_plugins = ["docker_compose"]

有关更多信息,请参阅安装和使用插件

要在测试中与Docker容器交互,请使用以下 fixtures,这些 fixtures 告诉 docker-compose 启动所有服务,然后它们可以获取相关的容器以供测试使用

function_scoped_container_getter

一个获取测试期间运行的Docker compose.container.Container 容器的对象。这些容器通过使用 function_scoped_container_getter.get('service_name') 来获取。每个容器都有一个额外的属性,称为 network_info,并添加到它们中。这个属性包含一个 pytest_docker_compose.NetworkInfo 对象的列表。

这些信息可用于配置API客户端和其他将连接到测试中Docker容器暴露的服务对象。

NetworkInfo 是一个包含以下字段的容器

  • container_port:容器内部公开的端口(通常也是协议名称)。当容器公开多个端口时,您可以使用此值找到测试中正确的端口。

  • hostname:连接到主机上的服务时要使用的计算机名(通常是“localhost”)。

  • host_port:从主机连接到服务时要使用的端口号。

docker_project

构建容器的 compose.project.Project 对象。此固定装置通常仅由插件内部使用。

要使用以下固定装置,请阅读 使用更广泛的固定装置

class_scoped_container_getter

类似于 function_scoped_container_getter,只是范围更广。

module_scoped_container_getter

类似于 function_scoped_container_getter,只是范围更广。

session_scoped_container_getter

类似于 function_scoped_container_getter,只是范围更广。

等待服务上线

名为 'scope'_scoped_container_getter 的固定装置将在将控制权交给测试之前等待每个容器启动。

然而,仅仅因为容器已启动,并不意味着其上运行的服务已经准备好接受传入的请求!

如果您的测试需要等待特定条件(例如,等待HTTP健康检查端点返回200响应),请确保您的固定装置考虑到了这一点。

以下是一个名为 wait_for_api 的固定装置示例,它等待HTTP服务上线,然后才能运行名为 test_read_and_write 的测试。

import pytest
import requests
from urllib.parse import urljoin
from urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter

pytest_plugins = ["docker_compose"]

# Invoking this fixture: 'function_scoped_container_getter' starts all services
@pytest.fixture(scope="function")
def wait_for_api(function_scoped_container_getter):
    """Wait for the api from my_api_service to become responsive"""
    request_session = requests.Session()
    retries = Retry(total=5,
                    backoff_factor=0.1,
                    status_forcelist=[500, 502, 503, 504])
    request_session.mount('http://', HTTPAdapter(max_retries=retries))

    service = function_scoped_container_getter.get("my_api_service").network_info[0]
    api_url = "http://%s:%s/" % (service.hostname, service.host_port)
    assert request_session.get(api_url)
    return request_session, api_url


def test_read_and_write(wait_for_api):
    """The Api is now verified good to go and tests can interact with it"""
    request_session, api_url = wait_for_api
    data_string = 'some_data'
    request_session.put('%sitems/2?data_string=%s' % (api_url, data_string))
    item = request_session.get(urljoin(api_url, 'items/2')).json()
    assert item['data'] == data_string
    request_session.delete(urljoin(api_url, 'items/2'))

使用更广泛的固定装置

function_scoped_container_getter 固定装置使用“函数”范围,这意味着在每次单独测试之后,所有容器都会被拆除。

这样做是为了确保每个测试都在“干净”的环境中运行。然而,这可能会使测试套件完成时间非常长。

有两种方法可以使容器在单个测试之后持续存在。最好的方法是用不同范围显式范围化的固定装置。为此有三个额外的固定装置:class_scoped_container_gettermodule_scoped_container_gettersession_scoped_container_getter。请注意,使用这些时需要小心!有两个主要注意事项需要记住

  1. 正确管理您的范围,使用单个文件中的“模块”范围和“函数”范围将引发错误!这是因为模块范围固定装置将启动容器,然后函数范围固定装置将尝试再次启动容器。Docker compose 不允许您启动容器两次。

  2. 在每次测试后清理您的环境。因为容器不会被重新启动,所以它们的环境可能会携带来自以前测试的信息。因此,您在设计测试时需要非常小心,以确保测试将容器留在与启动时相同的状态,否则您可能会遇到难以理解的行为。

使容器在单个测试之后持续存在的第二种方法是向pytest提供 –use-running-containers 标志,如下所示

pytest --use-running-containers

使用此标志,pytest-docker-compose会在项目创建过程中检查所有容器是否正在运行。如果它们没有运行,将会显示警告,但仍然会启动它们。然后它们将被用于所有测试,并在之后不会销毁。

此模式最好与“–docker-compose-no-build”标志结合使用,因为新构建的容器本来也不会使用。如下所示:

pytest --docker-compose-no-build --use-running-containers

当然,可以将这些选项添加到pytest.ini文件中。

请注意,对于此模式,固定项的作用域变得不那么重要,因为容器在整个测试过程中都是完全持久的。我只建议在您的网络启动或关闭时间过长时使用此功能。这应该是一个最后的手段,并且您可能需要考虑加快网络速度而不是使用此功能。

运行集成测试

使用pytest以正常方式运行测试

pytest

默认情况下,它将在当前工作目录中查找docker-compose.yml文件。您可以通过--docker-compose选项指定不同的文件

pytest --docker-compose=/path/to/docker-compose.yml

Docker Compose允许指定多个组合文件,如此处文档所述。要指定多个组合文件,请用,分隔它们

pytest --docker-compose=/path/to/docker-compose.yml,/another/docker-compose.yml,/third/docker-compose.yml

测试后删除卷

还有一个配置选项,在运行后删除容器的卷。

pytest --docker-compose-remove-volumes

如果未使用此插件,则此选项将被忽略。同样,此选项也可以添加到pytest.ini文件中。

有关如何使用此插件的更多示例,请查看此插件的测试套件!它将为您提供一些配置pytest.ini和使用不同的固定项运行Docker容器的示例。

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于安装软件包的信息。

源分布

pytest-docker-compose-3.2.1.tar.gz (15.3 kB 查看散列)

上传时间

构建分布

pytest_docker_compose-3.2.1-py3-none-any.whl (12.4 kB 查看散列)

上传时间 Python 3

由以下支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面