使用py.test fixture定义Docker集成测试环境的一组特定帮助程序。
pytest_docker_tools的Python项目详细描述
Pytest Docker工具
您已经编写了一个软件应用程序(使用任何语言),并已打包为Docker映像。现在,您希望在发布构建的映像之前对其进行冒烟测试,或者与其他容器进行一些集成测试。你:
- 想用类似于docker compose.yml的方式来解释您的环境
- 希望在测试运行时自动创建和销毁环境
- 不想为创建测试环境编写大量样板代码
- 希望能够并行运行测试
- 希望测试可靠
py test docker tools
是一组自以为是的助手,用于为烟雾测试和集成测试需求创建py.test
设备。它努力使您的环境定义保持声明性,就像docker-compose.yml一样。它包含py.test fixture过载。它尽量不太神奇。
此库提供的主界面是一组"fixture factories"。它提供了一个fixture的"类内最佳"实现,然后允许您将其视为一个模板—以声明方式注入您自己的配置。您可以在conftest.py
中定义您的fixture并从所有测试中访问它们,您还可以根据需要在各个测试模块中覆盖它们。
api是直接的,并且隐式地捕获规范中的相互依赖关系。例如,如果您构建了一个微服务并希望指向它的dns和一个模拟dns服务器,那么它可能是这样的:
# conftest.pyfromhttp.clientimportHTTPConnectionimportpytestfrompytest_docker_toolsimportbuild,containerfakedns_image=build(path='examples/resolver-service/dns',)fakedns=container(image='{fakedns_image.id}',environment={'DNS_EXAMPLE_COM__A':'127.0.0.1',})apiserver_image=build(path='examples/resolver-service/api',)apiserver=container(image='{apiserver_image.id}',ports={'8080/tcp':None,},dns=['{fakedns.ips.primary}'])@pytest.fixturedefapiclient(apiserver):port=apiserver.ports['8080/tcp'][0]returnHTTPConnection(f'localhost:{port}')
现在您可以创建一个测试来练习您的微服务:
# test_smoketest.pyimportsocketdeftest_my_frobulator(apiserver):sock=socket.socket()sock.connect(('127.0.0.1',apiserver.ports['8080/tcp'][0]))deftest_my_frobulator_works_after_restart(apiserver):apiserver.restart()sock=socket.socket()sock.connect(('127.0.0.1',apiserver.ports['8080/tcp'][0]))
在本例中,所有依赖项都将按顺序和每次会话解析一次:
- 将获取最新的redis:latest
- 容器映像将从
db
文件夹中的dockerfile
生成。
每次测试一次:
- 将创建一个新卷
- 将从
redis:latest
创建新的"后端"容器。它将附加到新卷。 - 将从新构建的容器创建新的"前端"容器。如果后端通过一个环境变量被赋予IP。容器中的端口3679将作为主机上的临时端口公开。
然后,测试可以运行并通过其短暂的高端口访问容器。测试结束时,环境将被丢弃。
如果测试失败,将捕获每个容器的docker日志
输出并将其添加到测试输出中。
在这个例子中,您会注意到我们定义了一个apiclient
fixture。当然,如果您使用它,它将隐式地拉入两个服务器设备和"工作":
# test_smoketest.pyimportjsondeftest_api_server(apiclient):apiclient.request('GET','/')response=apiclient.getresponse()assertresponse.status==200assertjson.loads(response.read())=={'result':'127.0.0.1'}
范围
所有的fixture工厂都使用scope
关键字。使用这些工厂创建的夹具的行为将类似于具有该范围的任何py.test夹具。
在本例中,我们创建一个memcache,它的作用域是session
和另一个module
作用域。
# conftest.pyfrompytest_docker_toolsimportcontainer,fetchmemcache_image=fetch(repository='memcached:latest')memcache_session=container(image='{memcache_image.id}',scope='session',ports={'11211/tcp':None,},)memcache_module=container(image='{memcache_image.id}',scope='module',ports={'11211/tcp':None,},)
当test_scope_1.py
运行时,两个容器都没有运行,因此每个容器都会启动一个新实例。它们的作用域比单个的函数要长,因此它们在下一次需要它们的测试中保持活动状态。
# test_scope_1.pyimportsocketdeftest_session_1(memcache_session):sock=socket.socket()sock.connect(('127.0.0.1',memcache_session.ports['11211/tcp'][0]))sock.sendall(b'set mykey 0 600 4\r\ndata\r\n')sock.close()deftest_session_2(memcache_session):sock=socket.socket()sock.connect(('127.0.0.1',memcache_session.ports['11211/tcp'][0]))sock.sendall(b'get mykey\r\n')assertsock.recv(1024)==b'VALUE mykey 0 4\r\ndata\r\nEND\r\n'sock.close()deftest_module_1(memcache_module):sock=socket.socket()sock.connect(('127.0.0.1',memcache_module.ports['11211/tcp'][0]))sock.sendall(b'set mykey 0 600 4\r\ndata\r\n')sock.close()deftest_module_2(memcache_module):sock=socket.socket()sock.connect(('127.0.0.1',memcache_module.ports['11211/tcp'][0]))sock.sendall(b'get mykey\r\n')assertsock.recv(1024)==b'VALUE mykey 0 4\r\ndata\r\nEND\r\n'sock.close()
当test_scope_2.py
运行会话时,作用域容器仍在运行,因此它将被重用。但我们现在在一个新的模块中,因此
模块
作用域容器将被销毁。将创建一个新的空实例。
# test_scope_2.pyimportsocketdeftest_session_3(memcache_session):sock=socket.socket()sock.connect(('127.0.0.1',memcache_session.ports['11211/tcp'][0]))sock.sendall(b'get mykey\r\n')assertsock.recv(1024)==b'VALUE mykey 0 4\r\ndata\r\nEND\r\n'sock.close()deftest_module_3(memcache_module):sock=socket.socket()sock.connect(('127.0.0.1',memcache_module.ports['11211/tcp'][0]))sock.sendall(b'get mykey\r\n')assertsock.recv(1024)==b'END\r\n'sock.close()
平行度
集成测试和冒烟测试通常很慢,但是要花很多时间等待。所以并行运行测试是加快测试速度的一个很好的方法。pytest docker tools
避免创建可能发生冲突的资源名称。也很容易不在乎你的服务势必如此。这意味着它非常适合与pytest xdist
一起使用。
下面是一个最简单的例子,它只是测试在xdist下运行的redis fixture的100个实例的创建和销毁。创建一个test\u xlist.py
插件:
importpytestfrompytest_docker_toolsimportcontainer,fetchmy_redis_image=fetch(repository='redis:latest')my_redis=container(image='{my_redis_image.id}',)@pytest.mark.parametrize("i",list(range(100)))deftest_xdist(i,my_redis):assertmy_redis.status=="running"
并使用:
pytest test_xdist.py -n auto
它将为每个核心创建一个worker并并行运行测试:
===================================== test session starts ======================================
platform darwin -- Python 3.6.5, pytest-3.6.3, py-1.5.4, pluggy-0.6.0
rootdir: ~/pytest-docker-tools, inifile:
plugins: xdist-1.22.2, forked-0.2, docker-tools-0.0.2
gw0 [100] / gw1 [100] / gw2 [100] / gw3 [100] / gw4 [100] / gw5 [100] / gw6 [100] / gw7 [100]
scheduling tests via LoadScheduling
......................................................................................... [ 82%]
........... [100%]
================================= 100 passed in 70.08 seconds ==================================
工厂参考
容器
要在测试中创建容器,请使用容器
fixture factory。
# conftest.pyfromhttp.clientimportHTTPConnectionimportpytestfrompytest_docker_toolsimportbuild,containerfakedns_image=build(path='examples/resolver-service/dns',)fakedns=container(image='{fakedns_image.id}',environment={'DNS_EXAMPLE_COM__A':'127.0.0.1',})apiserver_image=build(path='examples/resolver-service/api',)apiserver=container(image='{apiserver_image.id}',ports={'8080/tcp':None,},dns=['{fakedns.ips.primary}'])@pytest.fixturedefapiclient(apiserver):port=apiserver.ports['8080/tcp'][0]returnHTTPConnection(f'localhost:{port}')0
此工厂的默认范围是函数
。这意味着将为每个测试创建一个新容器。
fixture factory支持可以传递给docker pyrun
方法的所有参数。请参见这里的了解所有信息。
任何字符串变量都是根据其他定义的fixture插值的。这意味着一个固定装置可以依赖于其他固定装置,它们将按顺序构建和运行。
例如:
# conftest.pyfromhttp.clientimportHTTPConnectionimportpytestfrompytest_docker_toolsimportbuild,containerfakedns_image=build(path='examples/resolver-service/dns',)fakedns=container(image='{fakedns_image.id}',environment={'DNS_EXAMPLE_COM__A':'127.0.0.1',})apiserver_image=build(path='examples/resolver-service/api',)apiserver=container(image='{apiserver_image.id}',ports={'8080/tcp':None,},dns=['{fakedns.ips.primary}'])@pytest.fixturedefapiclient(apiserver):port=apiserver.ports['8080/tcp'][0]returnHTTPConnection(f'localhost:{port}')1
这将首先获取最新的redis:latest
,然后从所提取的确切图像运行容器。请注意,如果不使用build
或fetch
来准备docker映像,则指定的标记或哈希必须已存在于运行测试的主机上。不存在对Docker图像的隐式获取。
测试完成后,容器将自动删除。
IP地址
如果容器仅连接到单个网络,则可以通过帮助器属性获取其IP地址。在这种环境下:
# conftest.pyfromhttp.clientimportHTTPConnectionimportpytestfrompytest_docker_toolsimportbuild,containerfakedns_image=build(path='examples/resolver-service/dns',)fakedns=container(image='{fakedns_image.id}',environment={'DNS_EXAMPLE_COM__A':'127.0.0.1',})apiserver_image=build(path='examples/resolver-service/api',)apiserver=container(image='{apiserver_image.id}',ports={'8080/tcp':None,},dns=['{fakedns.ips.primary}'])@pytest.fixturedefapiclient(apiserver):port=apiserver.ports['8080/tcp'][0]returnHTTPConnection(f'localhost:{port}')2
您可以通过容器助手访问IP:
# conftest.pyfromhttp.clientimportHTTPConnectionimportpytestfrompytest_docker_toolsimportbuild,containerfakedns_image=build(path='examples/resolver-service/dns',)fakedns=container(image='{fakedns_image.id}',environment={'DNS_EXAMPLE_COM__A':'127.0.0.1',})apiserver_image=build(path='examples/resolver-service/api',)apiserver=container(image='{apiserver_image.id}',ports={'8080/tcp':None,},dns=['{fakedns.ips.primary}'])@pytest.fixturedefapiclient(apiserver):port=apiserver.ports['8080/tcp'][0]returnHTTPConnection(f'localhost:{port}')3
如果您想通过网络查找它的IP地址,您还可以更具体地访问它:
# conftest.pyfromhttp.clientimportHTTPConnectionimportpytestfrompytest_docker_toolsimportbuild,containerfakedns_image=build(path='examples/resolver-service/dns',)fakedns=container(image='{fakedns_image.id}',environment={'DNS_EXAMPLE_COM__A':'127.0.0.1',})apiserver_image=build(path='examples/resolver-service/api',)apiserver=container(image='{apiserver_image.id}',ports={'8080/tcp':None,},dns=['{fakedns.ips.primary}'])@pytest.fixturedefapiclient(apiserver):port=apiserver.ports['8080/tcp'][0]returnHTTPConnection(f'localhost:{port}')4
端口
工厂采用与官方python docker api相同的端口参数。我们建议使用短暂的高端口语法:
# conftest.pyfromhttp.clientimportHTTPConnectionimportpytestfrompytest_docker_toolsimportbuild,containerfakedns_image=build(path='examples/resolver-service/dns',)fakedns=container(image='{fakedns_image.id}',environment={'DNS_EXAMPLE_COM__A':'127.0.0.1',})apiserver_image=build(path='examples/resolver-service/api',)apiserver=container(image='{apiserver_image.id}',ports={'8080/tcp':None,},dns=['{fakedns.ips.primary}'])@pytest.fixturedefapiclient(apiserver):port=apiserver.ports['8080/tcp'][0]returnHTTPConnection(f'localhost:{port}')5
Docker会将容器中的8080端口映射到主机上的一个随机端口。为了从测试中访问它,您可以从容器实例中获取绑定端口:
# conftest.pyfromhttp.clientimportHTTPConnectionimportpytestfrompytest_docker_toolsimportbuild,containerfakedns_image=build(path='examples/resolver-service/dns',)fakedns=container(image='{fakedns_image.id}',environment={'DNS_EXAMPLE_COM__A':'127.0.0.1',})apiserver_image=build(path='examples/resolver-service/api',)apiserver=container(image='{apiserver_image.id}',ports={'8080/tcp':None,},dns=['{fakedns.ips.primary}'])@pytest.fixturedefapiclient(apiserver):port=apiserver.ports['8080/tcp'][0]returnHTTPConnection(f'localhost:{port}')6
日志
您可以使用logs方法检查容器的日志:
# conftest.pyfromhttp.clientimportHTTPConnectionimportpytestfrompytest_docker_toolsimportbuild,containerfakedns_image=build(path='examples/resolver-service/dns',)fakedns=container(image='{fakedns_image.id}',environment={'DNS_EXAMPLE_COM__A':'127.0.0.1',})apiserver_image=build(path='examples/resolver-service/api',)apiserver=container(image='{apiserver_image.id}',ports={'8080/tcp':None,},dns=['{fakedns.ips.primary}'])@pytest.fixturedefapiclient(apiserver):port=apiserver.ports['8080/tcp'][0]returnHTTPConnection(f'localhost:{port}')7
图像
要从默认存储库中提取图像,请使用fetch
fixture factory。要从本地源构建图像,请使用build
fixture factory。如果您正在对已在本地生成的工件进行烟雾测试,则可以使用图像
fixture factory来引用它。
# conftest.pyfromhttp.clientimportHTTPConnectionimportpytestfrompytest_docker_toolsimportbuild,containerfakedns_image=build(path='examples/resolver-service/dns',)fakedns=container(image='{fakedns_image.id}',environment={'DNS_EXAMPLE_COM__A':'127.0.0.1',})apiserver_image=build(path='examples/resolver-service/api',)apiserver=container(image='{apiserver_image.id}',ports={'8080/tcp':None,},dns=['{fakedns.ips.primary}'])@pytest.fixturedefapiclient(apiserver):port=apiserver.ports['8080/tcp'][0]returnHTTPConnection(f'localhost:{port}')8
fixture factory支持可以传递给docker pybuild
方法的所有参数。请参见这里的了解所有内容。fixture factory支持可以传递给docker pypull
方法的所有参数。请参见这里的了解所有信息。
此工厂的默认范围是会话
。这意味着fixture每次py.test调用只构建或获取一次。在测试(或其他设备)尝试使用之前,设备不会被触发。这意味着如果不运行使用图像的测试,就不会浪费时间构建图像。
网络
默认情况下,使用container()
fixture factory创建的任何容器都将在默认Docker网络上运行。您可以使用network()
fixture factory为您的测试创建一个专用网络。
# conftest.pyfromhttp.clientimportHTTPConnectionimportpytestfrompytest_docker_toolsimportbuild,containerfakedns_image=build(path='examples/resolver-service/dns',)fakedns=container(image='{fakedns_image.id}',environment={'DNS_EXAMPLE_COM__A':'127.0.0.1',})apiserver_image=build(path='examples/resolver-service/api',)apiserver=container(image='{apiserver_image.id}',ports={'8080/tcp':None,},dns=['{fakedns.ips.primary}'])@pytest.fixturedefapiclient(apiserver):port=apiserver.ports['8080/tcp'][0]returnHTTPConnection(f'localhost:{port}')9
fixture factory支持可以传递给docker py networkcreate
方法的所有参数。S请参见此处为他们所有人创建" rel="nofollow"。
此工厂的默认范围是函数
。这意味着将为执行的每个测试创建一个新网络。
使用网络完成测试后,网络将被删除。
体积
理想情况下,Docker容器实例是只读的。如果容器中的数据是卷的,则不会写入容器中的数据。如果您正在测试您的服务是否可以以只读方式运行,则可能需要装载一个rw卷。您可以使用volume()
fixture工厂创建一个docker卷,该卷的生命周期与您的测试绑定。
# test_smoketest.pyimportsocketdeftest_my_frobulator(apiserver):sock=socket.socket()sock.connect(('127.0.0.1',apiserver.ports['8080/tcp'][0]))deftest_my_frobulator_works_after_restart(apiserver):apiserver.restart()sock=socket.socket()sock.connect(('127.0.0.1',apiserver.ports['8080/tcp'][0]))0
fixture factory支持可以传递给docker py volumecreate
方法的所有参数。请参见这里的了解所有这些文件。
此外,您还可以指定一个初始目录
字典。这允许您以一小组初始状态为卷设定种子。在下面的示例中,我们将展示一个minio服务,其中一个bucket中有两个bucket和一个object。
# test_smoketest.pyimportsocketdeftest_my_frobulator(apiserver):sock=socket.socket()sock.connect(('127.0.0.1',apiserver.ports['8080/tcp'][0]))deftest_my_frobulator_works_after_restart(apiserver):apiserver.restart()sock=socket.socket()sock.connect(('127.0.0.1',apiserver.ports['8080/tcp'][0]))1
将使用一个空文件夹(bucket-1
)和一个名为example.txt的文本文件在一个名为
bucket-2
的单独文件夹中创建minio-u卷
容器
此工厂的默认范围是函数
。这意味着将为执行的每个测试创建一个新卷。测试完成后,将删除卷。
固定装置
Docker_客户端
docker客户端的fixture返回官方docker客户端的一个实例。
# test_smoketest.pyimportsocketdeftest_my_frobulator(apiserver):sock=socket.socket()sock.connect(('127.0.0.1',apiserver.ports['8080/tcp'][0]))deftest_my_frobulator_works_after_restart(apiserver):apiserver.restart()sock=socket.socket()sock.connect(('127.0.0.1',apiserver.ports['8080/tcp'][0]))2
直接使用Docker_客户端时要小心:
- 显然,在测试结束时,不会自动删除通过api创建的必需资源
- 很容易破坏xdist的兼容性
- 始终使用
ignore_removed
与docker_client.containers.list()一起使用
- 很容易找到正在使用的资源的其他实例(在其他worker中创建)。注意这个!
- 始终使用
- 不要采取破坏性措施-可能有人在机器上运行测试,而其他(非测试)容器正在运行,附带损坏很容易,应该避免。
这是我们夹具厂使用的夹具。这意味着如果你定义了一个自己的docker客户机fixture,那么测试将使用这个fixture。
提示和技巧
测试构建工件
我们经常发现自己对在测试时构建的容器(使用build()
)使用一组测试,但随后又希望对在ci平台上生成的工件(使用image()
)使用相同的测试。结果是这样的:
# test_smoketest.pyimportsocketdeftest_my_frobulator(apiserver):sock=socket.socket()sock.connect(('127.0.0.1',apiserver.ports['8080/tcp'][0]))deftest_my_frobulator_works_after_restart(apiserver):apiserver.restart()sock=socket.socket()sock.connect(('127.0.0.1',apiserver.ports['8080/tcp'][0]))3
但现在你可以做到:
# test_smoketest.pyimportsocketdeftest_my_frobulator(apiserver):sock=socket.socket()sock.connect(('127.0.0.1',apiserver.ports['8080/tcp'][0]))deftest_my_frobulator_works_after_restart(apiserver):apiserver.restart()sock=socket.socket()sock.connect(('127.0.0.1',apiserver.ports['8080/tcp'][0]))4
dev env和ci之间的网络差异
开发环境和ci环境之间的另一个常见区别可能是,测试最终在ci上的docker中运行。如果绑定mount yourdocker.sock
,则测试可能最终在与测试容器相同的容器网络上运行,并且无法访问映射到主机盒的任何端口。换句话说:
- 在您的开发机器上,您的测试可能会访问locahost:8000以访问您的测试实例(映射到主机的端口)
- 在您的ci机器上,他们可能需要访问172.16.0.5:8000才能访问您的测试实例
container对象有一个get\u addr
帮助程序,它将根据所在的环境返回正确的内容。
# test_smoketest.pyimportsocketdeftest_my_frobulator(apiserver):sock=socket.socket()sock.connect(('127.0.0.1',apiserver.ports['8080/tcp'][0]))deftest_my_frobulator_works_after_restart(apiserver):apiserver.restart()sock=socket.socket()sock.connect(('127.0.0.1',apiserver.ports['8080/tcp'][0]))5
客户设备
您可能需要为正在测试的服务创建一个api客户端. 尽管我们已经在自述文件中做了这些,但值得一提。你可以定义一个客户端fixture,让它依赖于你的docker容器,然后只需要从你的测试中引用客户端。
# conftest.pyfromhttp.clientimportHTTPConnectionimportpytestfrompytest_docker_toolsimportbuild,containerfakedns_image=build(path='examples/resolver-service/dns',)fakedns=container(image='{fakedns_image.id}',environment={'DNS_EXAMPLE_COM__A':'127.0.0.1',})apiserver_image=build(path='examples/resolver-service/api',)apiserver=container(image='{apiserver_image.id}',ports={'8080/tcp':None,},dns=['{fakedns.ips.primary}'])@pytest.fixturedefapiclient(apiserver):port=apiserver.ports['8080/tcp'][0]returnHTTPConnection(f'localhost:{port}')
然后从测试中引用:
# test_smoketest.pyimportsocketdeftest_my_frobulator(apiserver):sock=socket.socket()sock.connect(('127.0.0.1',apiserver.ports['8080/tcp'][0]))deftest_my_frobulator_works_after_restart(apiserver):apiserver.restart()sock=socket.socket()sock.connect(('127.0.0.1',apiserver.ports['8080/tcp'][0]))7
在本例中,任何使用hpfeeds_client
fixture的测试都将获得一个正确配置的客户端,该客户端连接到在临时高端口上的Docker容器中运行的代理。测试完成后,客户端将完全断开连接,Docker容器将被丢弃。
夹具过载
复杂的环境可以用夹具工厂来定义。它们形成有向无环图。通过使用fixture重载,可以(在单个测试模块的上下文中)替换依赖关系图中的节点,而无需重新定义整个环境。
无需重新定义其从属项即可更换容器夹具
您可以在 然后可以在测试模块中重载这些设备。例如,如果redis有一个神奇的复制特性,并且您想用api测试一个edge case,那么您可以在 在这里,我们在 你也可以从你的夹具工厂拉入普通的py.test夹具。这意味着我们可以使用fixture重载并传入config。在 当测试现在使用apiclient fixture时,他们将得到fakedns容器的配置为normal。但是,您可以在测试模块中重新定义fixture,其他fixture仍然会尊重它。例如: 您的 可以创建参数化装置。也许您需要对两个身份验证后端运行所有的 在 测试与第一个示例相同,只是现在将针对两种不同的假配置进行测试。 此测试将调用两次-一次针对内存后端,一次针对sqlite后端。 你可以用一个包装类来包装你的设备。这允许您向fixture添加helper方法,以便在测试中使用。对于 在以前的测试中,我们创建了一个完整的测试客户机fixture。使用wrapper类,我们可以把这个方便的方法挂在fixture本身上:conftest.py中定义一个fixture
# conftest.pyfromhttp.clientimportHTTPConnectionimportpytestfrompytest_docker_toolsimportbuild,containerfakedns_image=build(path='examples/resolver-service/dns',)fakedns=container(image='{fakedns_image.id}',environment={'DNS_EXAMPLE_COM__A':'127.0.0.1',})apiserver_image=build(path='examples/resolver-service/api',)apiserver=container(image='{apiserver_image.id}',ports={'8080/tcp':None,},dns=['{fakedns.ips.primary}'])@pytest.fixturedefapiclient(apiserver):port=apiserver.ports['8080/tcp'][0]returnHTTPConnection(f'localhost:{port}')
test戥smoketest戥alternate.py
:# test_smoketest.pyimportsocketdeftest_my_frobulator(apiserver):sock=socket.socket()sock.connect(('127.0.0.1',apiserver.ports['8080/tcp'][0]))deftest_my_frobulator_works_after_restart(apiserver):apiserver.restart()sock=socket.socket()sock.connect(('127.0.0.1',apiserver.ports['8080/tcp'][0]))
9
test\u smoketest\u alternate
中重新定义了fakedns容器。它能够使用我们在conftest.py
中定义的fakedns廑image
fixture。更重要的是,当我们使用coreapiclient
fixture时,它实际上引入了fakedns
的本地定义,而不是来自conftest.py
的定义!你不必重新定义任何东西。它只是工作。通过夹具注入夹具配置
conftest.py中:
# test_smoketest.pyimportjsondeftest_api_server(apiclient):apiclient.request('GET','/')response=apiclient.getresponse()assertresponse.status==200assertjson.loads(response.read())=={'result':'127.0.0.1'}
0
# test_smoketest.pyimportjsondeftest_api_server(apiclient):apiclient.request('GET','/')response=apiclient.getresponse()assertresponse.status==200assertjson.loads(response.read())=={'result':'127.0.0.1'}
1
api_server
容器(及其redis
后端)将正常构建,只有在这一个测试模块中,它将使用其sqlite后端。夹具参数化
api_服务器
测试。可能您有一个要测试的多个配置的赝品。conftest.py中:
# test_smoketest.pyimportjsondeftest_api_server(apiclient):apiclient.request('GET','/')response=apiclient.getresponse()assertresponse.status==200assertjson.loads(response.read())=={'result':'127.0.0.1'}
2
# test_smoketest.pyimportjsondeftest_api_server(apiclient):apiclient.request('GET','/')response=apiclient.getresponse()assertresponse.status==200assertjson.loads(response.read())=={'result':'127.0.0.1'}
3
夹具包装
容器
夹具工厂,您还可以实现ready()
以添加额外的容器就绪检查。# test_smoketest.pyimportjsondeftest_api_server(apiclient):apiclient.request('GET','/')response=apiclient.getresponse()assertresponse.status==200assertjson.loads(response.read())=={'result':'127.0.0.1'}
4
推荐PyPI第三方库