我是python和合同测试的新手。我正在尝试使用pact-python
测试我的消费者应用程序。
这是测试文件test_posts_controller.py
import unittest
import atexit
from pact import Consumer, Provider, Term
import requests
pact = Consumer('Consumer').has_pact_with(Provider('Provider'))
pact.start_service()
atexit.register(pact.stop_service)
class GetPostsContract(unittest.TestCase):
def test_get_all_posts(self):
expected = {
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
(pact
.given('posts exist')
.upon_receiving('a request for post by id')
.with_request('GET', '/posts/1')
.will_respond_with(200, body=expected))
with pact:
result = requests.get('https://jsonplaceholder.typicode.com/posts/1')
self.assertEqual(result.json(), expected)
我在这里尝试打JSONPlaceholder。
我正在使用pytest
命令来运行测试。
但是我遇到了以下错误。我不知道我在想什么。
self = <pact.pact.Pact object at 0x10cc8c8d0>
def verify(self):
"""
Have the mock service verify all interactions occurred.
Calls the mock service to verify that all interactions occurred as
expected, and has it write out the contracts to disk.
:raises AssertionError: When not all interactions are found.
"""
self._interactions = []
resp = requests.get(
self.uri + '/interactions/verification',
headers=self.HEADERS)
> assert resp.status_code == 200, resp.text
E AssertionError: Actual interactions do not match expected interactions for mock MockService.
E
E Missing requests:
E GET /posts/1
E
E See pact-mock-service.log for details.
venv/lib/python3.7/site-packages/pact/pact.py:209: AssertionError
我也尝试过pact.setup()
和pact.verify()
,但仍然遇到相同的错误。有人可以帮我解决这个问题吗?
它也不会创建pactfile。我必须设置什么?
答案 0 :(得分:1)
契约告诉您互动从未触发。您永远不会在契约模拟服务器上调用GET /posts/1
,因此,当您尝试验证它时,会说它缺少交互作用,因为它失败了,因此不会生成契约文件。
除非https://jsonplaceholder.typicode.com/posts/1
指向协定模拟服务(我猜不是),否则它将无法正常工作。无论您使用的端口是什么(通常在localhost:上),都是您需要的端口。
从pact本身获取基本URI,而不是您编写的代码:
with pact:
result = requests.get(pact.uri + '/posts/1')
self.assertEqual(result.json(), expected)
pact.verify()
答案 1 :(得分:1)
AssertionError:实际交互与模拟MockService的预期交互不匹配。
^此错误表明pact模拟没有收到Pact测试中描述的交互。
E Missing requests:
E GET /posts/1
^这部分说模拟没有收到GET
的{{1}}请求。如果模拟服务器收到了其他请求(例如,没想到的/posts/1
),它们也会在此处列出。
因此,我们知道在测试过程中没有请求到达模拟服务器。
阅读其余的测试类,我们有:
POST
这表明测试达到 with pact:
result = requests.get('https://jsonplaceholder.typicode.com/posts/1')
,而不是测试期间设置的模拟。因此,错误是正确的-要解决该错误,我们需要点击模拟服务器:
要解决此问题,您需要联系条约模拟服务器:
jsonplaceholder.typicode.com
(或您配置了Pact进行侦听的任何端口)。
您也可以直接从Pact获取此信息:
with pact:
result = requests.get('https://localhost:1234/posts/1')
您可能会发现此消费者测试图很有用(摘自Pact文档的How Pact Works部分):
您的消费者代码是橙色部分,蓝色部分是Pact提供的模拟。
在Pact测试期间,使用者不与实际提供者联系,而仅与模拟提供者联系。对于提供者验证,情况恰恰相反-只有模拟消费者才与真正的提供者联系。
这意味着您不需要一起测试消费者和提供者来进行测试。这一优势是合同测试的主要卖点。
答案 2 :(得分:0)
主机名和端口以覆盖默认值
http:// localhost:1234模拟服务URL
例如:
pact = Consumer('Consumer').has_pact_with(Provider('Provider'), port='<port>', host_name='<host>')