Marimo项目中使用pytest进行单元测试指南

Marimo项目中使用pytest进行单元测试指南

marimo A next-generation Python notebook: explore data, build tools, deploy apps! marimo 项目地址: https://gitcode.com/gh_mirrors/ma/marimo

前言

在数据科学和Python开发中,单元测试是保证代码质量的重要手段。Marimo作为一个交互式笔记本环境,提供了与pytest测试框架的无缝集成,让开发者能够在笔记本环境中直接编写和运行测试用例。本文将详细介绍如何在Marimo项目中使用pytest进行单元测试。

Marimo中的测试机制

Marimo笔记本内置了测试发现和执行功能,当项目中安装了pytest依赖时,Marimo会自动识别并执行符合特定命名规则的测试代码:

  1. 测试函数:名称以test_开头的函数
  2. 测试类:名称以Test开头的类

Marimo会跳过包含非测试代码(如辅助函数、常量、变量、导入等)的单元格,建议将这类代码放在单独的单元格中。

示例代码

@app.cell
def __():
    import pytest
    def inc(x):
        return x + 1
    return inc, pytest

@app.cell
def __(inc, pytest):
    class TestBlock:
        @staticmethod
        def test_fails():
            assert inc(3) == 5, "This test fails"

        @staticmethod
        def test_sanity():
            assert inc(3) == 4, "This test passes"

    @pytest.mark.parametrize(("x", "y"), [(3, 4), (4, 5)])
    def test_parameterized(x, y):
        assert inc(x) == y
    return

配置选项

如果需要禁用自动测试功能,可以在配置文件中设置runtime.reactive_test选项为false

命令行测试

Marimo笔记本本质上是Python程序,因此可以直接使用pytest在命令行中运行测试:

pytest test_notebook.py

该命令会执行笔记本中所有符合测试命名规则的单元格,与在笔记本环境中运行测试的行为一致。

命名建议

为测试单元格命名有两种方式:

  1. 在笔记本文件中为单元格函数命名
  2. 使用笔记本编辑器中的单元格操作菜单

测试发现

pytest会自动发现以下类型的笔记本:

  1. 文件名以test_开头的笔记本
  2. 包含自测代码的笔记本(直接运行pytest my_notebook.py

完整示例

以下是一个完整的测试笔记本示例:

# test_notebook.py
import marimo

__generated_with = "0.10.6"
app = marimo.App()


@app.cell
def _():
    def inc(x):
        return x + 1
    return (inc,)


@app.cell
def test_fails(inc):
    assert inc(3) == 5, "This test fails"


@app.cell
def test_sanity(inc):
    assert inc(3) == 4, "This test passes"

@app.cell
def collection_of_tests(inc, pytest):
    @pytest.mark.parametrize(("x", "y"), [(3, 4), (4, 5)])
    def test_answer(x, y):
        assert inc(x) == y, "These tests should pass."

@app.cell
def imports():
    import pytest
    return pytest

运行pytest后的输出示例:

============================= test session starts ==============================
platform linux -- Python 3.12.9, pytest-8.3.5, pluggy-1.5.0
rootdir: /notebooks
configfile: pyproject.toml
collected 4 items

test_notebook.py::test_fails FAILED                                       [ 25%]
test_notebook.py::test_sanity PASSED                                      [ 50%]
test_notebook.py::MarimoTestBlock_0::test_parameterized[3-4] PASSED       [ 75%]
test_notebook.py::MarimoTestBlock_0::test_parameterized[4-5] PASSED       [100%]

=================================== FAILURES ===================================
__________________________________ test_fails __________________________________

    # content of test_notebook.py
    import marimo

    __generated_with = "0.10.6"
    app = marimo.App()


    @app.cell
    def _():
        def inc(x):
            return x + 1
        return (inc,)


    @app.cell
    def test_fails(inc):
>       assert inc(3) == 5, "This test fails"
E       AssertionError: This test fails
E       assert 4 == 5
E        +  where 4 = <function inc>(3)

test_notebook.py:17: AssertionError
=========================== short test summary info ============================
FAILED test_notebook.py::test_fails - AssertionError: This test fails
========================= 1 failed, 3 passed in 0.82s ==========================

最佳实践

  1. 分离测试代码:将测试代码与实现代码分离到不同的单元格中
  2. 使用参数化测试:利用@pytest.mark.parametrize减少重复代码
  3. 命名规范:遵循pytest的命名约定,使测试更容易被发现
  4. 集成到CI/CD:将Marimo笔记本测试纳入持续集成流程

总结

Marimo与pytest的深度集成为数据科学项目提供了强大的测试能力。通过在笔记本中直接编写测试用例,开发者可以更高效地进行测试驱动开发(TDD),确保代码质量的同时保持开发效率。无论是交互式开发还是自动化测试,Marimo都提供了完善的解决方案。

marimo A next-generation Python notebook: explore data, build tools, deploy apps! marimo 项目地址: https://gitcode.com/gh_mirrors/ma/marimo

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

邵娇湘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值