0

我对 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。我必须设置什么?

4

3 回答 3

5

如何找出它发生的原因

AssertionError:实际交互与模拟 MockService 的预期交互不匹配。

^ 此错误表示协议模拟没有收到协议测试中描述的交互。

E       Missing requests:
E           GET /posts/1

^ 这部分说模拟没有GET收到/posts/1. 如果模拟服务器收到了其他请求(例如POST,它没有预料到的请求),它们也会在此处列出。

因此,我们知道在测试期间没有请求到达模拟服务器。

阅读测试课的其余部分,我们有:

    with pact: 
        result = requests.get('https://jsonplaceholder.typicode.com/posts/1')

这表明测试是命中jsonplaceholder.typicode.com而不是在测试期间设置的模拟。所以,错误是正确的——要修复它,我们需要访问模拟服务器:

如何修复它

要解决您的问题,您需要联系 pact 模拟服务器:

    with pact: 
        result = requests.get('https://localhost:1234/posts/1') 

(或者你配置 Pact 监听的任何端口)。

你也可以直接从 Pact 获得这个:

    with pact: 
        result = requests.get(pact.uri + '/posts/1') 

如何了解更多

您可能会发现这个消费者测试图表很有用(取自 Pact 文档的How Pact Works部分):

消费者测试

你的消费者代码是橙色部分,蓝色部分是 Pact 提供的 mock。

在 Pact 测试期间,消费者不联系实际的提供者,它只联系模拟提供者。提供者验证正好相反——只有模拟消费者联系真正的提供者。

这意味着您不需要同时启动消费者和提供者来进行测试。这一优势是合同测试的主要卖点。

于 2019-02-27T05:53:28.533 回答
1

Pact 告诉你交互从未被触发。您永远不会调用GET /posts/1pact 模拟服务器,因此当您尝试验证它时,它会说它缺少交互并且由于失败而没有生成 pact 文件。

除非https://jsonplaceholder.typicode.com/posts/1指向协议模拟服务(我猜它不是),否则这是行不通的。无论它在哪个端口上(通常在 localhost 上:),都是您需要点击的。

而不是您所做的代码,而是从协议本身获取基本 URI:

with pact: 
    result = requests.get(pact.uri + '/posts/1')

self.assertEqual(result.json(), expected)
pact.verify()
于 2019-02-27T05:51:30.433 回答
0

可以提供主机名和端口来覆盖默认的
http://localhost:1234 模拟服务 URL
示例:

pact = Consumer('Consumer').has_pact_with(Provider('Provider'), port='<port>', host_name='<host>')  
于 2020-10-04T20:29:17.687 回答