Pytest中5种不同的方法解析JSON数据

关注开源优测不迷路

大数据测试过程、策略及挑战

测试框架原理,构建成功的基石

在自动化测试工作之前,你应该知道的10条建议

在自动化测试中,重要的不是工具

JavaScript 对象表示法(JSON)可以说是网络上最流行的数据交换格式之一。

Web 服务使用序列化技术将数据从底层数据结构转换为 JSON 格式,以便接收服务能够轻松地对其进行反序列化。

在编写单元测试时,测试 JSON 输入和输出的需求至关重要。

测试数据、API 响应,有时甚至配置文件都是用 JSON 定义的,这使得使用 Pytest 理解如何读取和写入 JSON 变得十分必要。

在本文中,我们将探索在 Pytest 中读取 JSON 数据的 5 种简单方法,这样你就可以用它来验证输入的测试数据、配置文件、API 响应等等。

目标

在本文结束时,你应该能够:

  1. 使用 5 种不同的方法在 Pytest 中解析 JSON 数据。

  2. 理解如何使用 Pytest 的 fixture(夹具)和参数将 JSON 数据解析到单元测试中。

入门

在开始操作前,请按以下目录组织你的代码结构

本文中不需要特殊的库,只需要 pytest 和一个代码格式化检查工具。

现在让我们来看看在 Pytest 中解析 JSON 输入的 5 种不同方法。

源代码

我们的源代码是一个非常简单的示例,它接受一个 JSON 字符串输入,并根据 "age" 字段计算出 "birth_year"(出生年份)。

read_json/core.py

kotlin 复制代码
import json  def compute_birth_year(input_data: str):      # 将JSON数据解析为Python字典            data = json.loads(input_data)                  # 计算出生年份            birth_year = 2023 - data["age"]                  return f"{data['name']} was born in {birth_year}"
go 复制代码
让我们看看如何用5种不同的方式来测试这个函数。
  1. 在测试中定义 JSON

测试这个函数最简单的方法之一是在我们的单元测试中定义输入的 JSON。

tests/unit/test_read_json.py

makefile 复制代码
def test_compute_birth_year_1():  input_data = '{"name": "John", "age": 30, "city": "New York"}'              expected = "John was born in 1993"              assert compute_birth_year(input_data) == expected
go 复制代码
虽然这种方法很简单,但灵活性较差。

如果你想用新的 JSON 数据运行测试,就必须修改测试模块(这很不方便)。

  1. 读取外部 JSON 文件

一种有趣且方便的读取 JSON 文件的方法是将其单独保存,放在测试模块之外。

这样你就可以动态地对其进行修改,而无需更改测试本身。

tests/unit/test_read_json.py

cs 复制代码
def test_compute_birth_year_2():      file = pathlib.Path("tests/unit/test_data/input1.json")                  with open(file) as f:                input_data = f.read()                      expected = "Jerry was born in 1968"                  assert compute_birth_year(input_data) == expected
go 复制代码
在这里,我们使用了 pathlib 模块来解析文件,但你也可以使用 json 模块。

这种方法的好处是我们将输入与测试模块解耦了,但如果输入文件不可用,你就会遇到测试错误。

  1. 将 JSON 数据作为 fixture 提供

另一种方法(也是我非常喜欢的一种)是将输入数据作为 Pytest 的 fixture 提供。

如果你不熟悉 Pytest 的 fixture 及其工作原理,这篇文章提供了很好的基础介绍。

简而言之,fixture 是 Pytest 函数(通常在 conftest.py 中定义),可以在一个或多个测试模块中轻松使用,并通过 scope 参数进行状态控制。

我们定义 JSON 的 fixture:

tests/unit/conftest.py

ruby 复制代码
@pytest.fixture(scope="session")  def input_json():       return json.dumps({        "name": "Eric",         "age": 32,         "city": "London"        })
go 复制代码
现在我们可以在单元测试中使用它了。

tests/unit/test_read_json.py

cpp 复制代码
def test_compute_birth_year_3(input_json):    expected = "Eric was born in 1991"          assert compute_birth_year(input_json) == expected
go 复制代码
4. 使用 Pytest 参数定义 JSON

你也可以利用 Pytest 中的参数来定义测试输入。

为此,我们使用 @pytest.mark.parametrize 标记。让我们来看一下。

tests/unit/test_read_json.py

swift 复制代码
@pytest.mark.parametrize( "input_data, expected", [('{"name": "Robin", "age": 55, "city": "Los Angeles"}', "Robin was born in 1968"),])  def test_compute_birth_year_4(input_data, expected):
      assert compute_birth_year(input_data) == expected
go 复制代码
在标记中,我们定义了输入数据和预期值,然后定义了一个输入值列表(每个元素都是一个元组)。

Pytest 会将这个输入值列表传递给测试。非常简洁!

  1. 在运行时提供 JSON

将 JSON 解析到单元测试中的最后一种方法是在运行时将其作为命令行界面(CLI)输入提供。

为此,我们在 conftest.py 中定义几个 fixture。

conftest.py

swift 复制代码
def pytest_addoption(parser):      parser.addoption(    "--input-json",     action="store",     default='{"name":"Rick", "age": 50, "city": "NY"}',     help="Input JSON")        @pytest.fixture  def input_json_command_line(request):      return request.config.getoption("--input-json")
go 复制代码
我们使用内置的解析器将 --input-json 标志解析给 Pytest,指定一个默认值,最后将其用作 fixture。

然后我们可以在单元测试中使用它。

tests/unit/test_read_json.py

ruby 复制代码
@pytest.fixture  def input_json_command_line(request):      return request.config.getoption("--input-json")
go 复制代码
这种方法虽然简单,但扩展性不好,特别是当你需要解析多个 JSON 时。

运行单元测试

要运行单元测试,只需运行:

bash 复制代码
pytest tests/unit/test_read_json.py -v -s --input-json="{'name': 'Ravi', 'age': 90, 'city': 'New Delhi'}"

结论

在本文中,我们研究了在单元测试中解析 JSON 的 5 种方法。

在编写单元测试、集成测试、端到端测试或 API 测试时,知道如何解析 JSON 尤为重要,因为几乎所有的数据交换都是通过 JSON 格式进行的。

你学习了各种技术,包括使用 fixture 和参数、通过外部文件和命令行传递 JSON。

有了这些知识,你现在可以在 Python 单元测试中高效地解析 JSON 数据了。

相关推荐
一半烟火以谋生1 小时前
pytest conftest.py 使用教程
pytest
谢尔登2 小时前
【Nest】单元测试
单元测试·log4j
我的xiaodoujiao11 小时前
使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 19--测试框架Pytest基础 3--前后置操作应用
python·学习·测试工具·pytest
鱼鱼说测试11 小时前
pytest+yaml+allure接口自动化测试框架
pytest
编啊编程啊程18 小时前
【011】宠物共享平台
spring boot·log4j·maven·dubbo·宠物
njsgcs3 天前
json转excel python pd
python·json·excel·pd
代码搬运媛3 天前
【架构相关】tsconfig.json 与 tsconfig.node.json、tsconfig.app.json 的关系和作用
node.js·json
ThreeAu.3 天前
pytest 实战:用例管理、插件技巧、断言详解
python·单元测试·pytest·测试开发工程师
我的xiaodoujiao3 天前
使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 18--测试框架Pytest基础 2--插件和参数化
python·学习·测试工具·pytest
小小测试开发4 天前
pytest 库用法示例:Python 测试框架的高效实践
开发语言·python·pytest