likes
comments
collection
share

从单进程到分布式:探索pytest-xdist在测试中的威力

作者站长头像
站长
· 阅读数 3

前言

笔者在工作中接到一个测试任务,需要检测敏感词是否被正常过滤,但是敏感词数据样本有仅1万条。如果单进程跑,很费时间,那该如何解决呢?带着疑问,我们寻找解决方案。

pytest-xdist插件

pytest-xdist是一个非常有用的pytest插件,它可以帮助我们在多个进程或多台机器上并行运行测试用例,以提高测试效率。

可以看到此插件可以开多个进程执行case,可以大大加快执行速率。

安装

可以使用pip来安装pytest-xdist:

pip install pytest-xdist

如何使用

要在多个进程或多台机器上并行运行测试用例,只需要在运行pytest时添加-n选项,指定要使用的进程数或机器数即可。例如,如果要在4个进程上并行运行测试用例,则可以这样运行pytest:

pytest -n 4

如果是写在脚本中,也可以这样写:

pytest.main([ "-n", "4"])

pytest-xdist插件将自动将测试用例分配给4个进程,并在所有进程完成测试后输出测试报告。

如果你想在多台机器上运行测试用例,可以使用类似的方式指定要使用的机器数和主机名。例如,如果要在3个主机上运行测试用例,则可以这样运行pytest:

pytest -n 3 --dist=loadfile

这里使用了--dist=loadfile选项,表示要在不同的机器上运行测试用例。

案例

解决我们开头提到的问题

test_comment_controller.py

def read_test_data(file):
    test_data = []
    with open(file, 'r') as f:
        reader = csv.DictReader(f)
        for row in reader:
            test_data.append((row['param']))
    return [data for data in test_data if data]


class TestCommentController(TestCase):


    @pytest.mark.parametrize('param', read_test_data('demo.csv'))
    def test_comment_add(self, headers, param):
        payload = {
            "content": param,
            "modelId": "111111",
            "type": 0
        }
        self.post('/pangxiaolu/comment/add', json=payload, headers=headers)
        self.assertStatusCode(200)

这条case进行了参数化,读取外部文件,文件中有上万条,加下来看看该如何用pytest-xdist运行

要在4个进程上并行运行这条case,可以在命令行中运行以下命令:

pytest -n 4 test_comment_controller.py::TestCommentController::test_comment_add

pytest-xdist插件将自动将这些测试用例分配给4个进程,并在所有进程完成测试后输出测试报告。

核心逻辑

这一部分当做拓展知识,不了解也没关系。

大概包括几个流程:

  1. 配置:用户在pytest配置文件中通过命令行参数或者配置项指定并行测试的方式,例如多进程或者多台机器。pytest-xdist会根据这些配置初始化测试环境,并启动相应的进程或者节点等待任务。
  2. 拆分:pytest-xdist负责将测试集拆分成多个子集,每个子集分配给一个进程或者一个节点进行执行。pytest-xdist支持多种拆分策略,例如按照测试文件、测试模块、测试类等进行拆分。
  3. 执行:各个进程或者节点接收到测试集之后,会独立地执行测试,并将测试结果发送回主控节点。pytest-xdist使用自定义的进程间通信协议实现进程间通信和数据交换,保证测试结果的正确性和可靠性。
  4. 合并:主控节点在收到所有子进程或者节点的测试结果之后,会将这些结果汇总起来,生成测试报告并输出到终端或者文件中。pytest-xdist支持多种测试报告格式,例如JUnit XML、HTML等。
  5. 清理:pytest-xdist负责清理测试环境和进程资源,释放内存和文件句柄等。pytest-xdist还支持自定义的测试环境清理逻辑,例如删除临时文件、关闭网络连接等。

总之,pytest-xdist通过配置、拆分、执行、合并和清理等多个环节,实现了基于多进程或者多台机器的分布式测试。这样可以大大缩短测试时间,提高测试效率和稳定性。同时,pytest-xdist还继承了pytest的易用性和灵活性,支持多种插件和扩展,具有广泛的适用性和可定制性。

最后

笔者的这条case比较简单,不涉及依赖、共享数据等问题,但在测试其他case时,你可能会遇到一些问题,例如测试用例之间存在依赖关系,或者某些用例需要使用共享资源。为了解决这些问题,pytest-xdist插件提供了一些工具和机制,例如XdistSchedulerFixture、XdistWorkerFixture和XProcessManager等。这些工具和机制使得在多个进程或多台机器上运行测试用例变得更加容易和可靠。当然这些机制,我们用到后在用案例讲解,本篇内容还是知道pytest-xdist插件,知道如何使用就可以了。