【问题标题】:How to read and send CSV column data to PyTest test cases如何读取 CSV 列数据并将其发送到 PyTest 测试用例
【发布时间】:2022-01-13 12:11:03
【问题描述】:

我们有一个实用程序可以调用 API 并将其响应保存到 CSV。该 CSV(resp.csv)具有 API 请求(A 列)以及标头 (C 列)和有效载荷(B 列)。他们的响应正文存储在D 列中,响应代码存储在E 列中(在 CSV 图像中不可见)。

CSV 文件如下所示:

我想将每个响应传递给一组 PyTest 测试用例,这些测试用例将有一些特定于响应的断言。

为了检查状态代码,我可以通过函数调用来完成,它会在写入 CSV 之前返回响应代码。但要求是从 CSV 读取响应并将它们传递给断言/测试用例:

@pytest.mark.parametrize('test_input', check_response)
def test_APIResponse(test_input):
    print(check_response)
    assert test_input == 200, "Test pass"

如何调用存储在 CSV 中的响应正文(列 D)并通过使用 PyTest 测试用例进行断言?

有人可以指导我吗?

谢谢

【问题讨论】:

标签: python csv pytest


【解决方案1】:

我编写了一个名为Parametrize From File 的包,可用于执行此操作。我在另一篇 Stack Overflow 帖子中给出了如何load test parameters from an XLSX file 的详细示例,但我将在这里简要重申要点。

唯一的复杂之处是 Parametrize From File 希望能够将测试用例加载为字典列表的字典(有关更多信息,请参阅文档)。此布局适用于 YAML/TOML/NestedText 文件,但不适用于 XLSX/CSV 文件。所以我们需要提供一个函数来加载相关的 XSLX/CSV 文件并将其转换为预期的格式。如果您愿意添加依赖项,pandas 使这很容易做到,否则自己编写一些东西可能不会太难。


编辑:这是一个更具体的例子。首先,CSV 文件可能如下所示:

request_,payload,header,response,code
http://localhost:8080/c/u/t,{"ci":""},{},{"ss":""},200
http://localhost:8080/c/u/t?Id=x,{"ci":""},{},{"res":""},200

需要注意的几点:

  • 第一行为每一列提供了一个名称。我编写的代码依赖于此,并使用与参数化测试函数的参数相同的名称。如果您的文件没有这些标题,则需要对每列的名称进行硬编码。
  • “request”这个名字是pytest保留的,所以我们这里要使用“request_”。

下面是相应的测试脚本的样子:

import parametrize_from_file as pff
from csv import DictReader
from collections import defaultdict

def load_csv(path):
    with open(path) as f:
        cases = list(DictReader(f))
    return defaultdict(lambda: cases)

pff.add_loader('.csv', load_csv)

@pff.parametrize
def test_api_request_response(request_, payload, header, response, code):
    assert request_ == ...
    assert payload == ...
    assert headers == ...
    assert response == ...
    assert code == ...

需要注意的几点:

  • 这假定 CSV 文件与测试脚本具有相同的基本名称。如果不是这种情况,很容易指定不同的路径。
  • 加载函数应该返回一个字典映射测试名称(例如test_api_request_response)到测试用例列表,其中每个测试用例是一个字典映射参数名称(例如request_)到参数值(例如@987654329 @)。在这种情况下,文件没有指定任何测试名称,因此我们作弊并使用defaultdict 为任何测试名称返回相同的测试用例。

【讨论】:

  • @stackoverflow.com/users/2066725/kale-kundert 我对此有点困惑。如评论中所述,将此 CSV 转换为 dict 对象。现在我的 dict1 看起来像:{'column A1 value': ['{column b1}',"{column c1}",'{column d1}','column e1'],'column A2 value': ['{column b2}',"{column c2}",'{column d2}','column e2']...} 如果可能的话,请指导我如何传递这个 dict,特别是使用 PyTest 进行断言的 d 列和 e 列?在 D 列中存储了 xml 响应,我会进行架构检查并包含测试用例。在此先感谢羽衣甘蓝。干杯。
【解决方案2】:

看看这个,我认为它可能会帮助docs。对于您的具体示例,您可以使用类似

import pytest


def load_cases():
    # read_csv
    class Case:
        def __init__(self, number):
            self.i = number

        def __repr__(self):
            return '{number}'.format(number=self.i)

    return [Case(i) for i in range(5)]


def parametrize(name, values):
    # function for readable description
    return pytest.mark.parametrize(name, values, ids=map(repr, values))


@parametrize("case", load_cases())
def test_responses(case):
    print(case.i)

您正在创建类Case 并将您需要的所有内容存储在该类中,然后从测试访问属性。您还可以使用 indirect 为固定装置参数化,但不要使您的代码过于复杂。

要读取特定列,请使用 pandas 之类的内容,或者只是拆分您的字符串。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-17
    • 1970-01-01
    • 2012-08-16
    • 2021-05-25
    • 2018-09-14
    • 2013-09-10
    • 2022-11-27
    相关资源
    最近更新 更多