【问题标题】:In doctest, is there a way to treat a yaml code-block as a variable?在 doctest 中,有没有办法将 yaml 代码块视为变量?
【发布时间】:2020-10-20 12:13:48
【问题描述】:

我正在使用 doctest 测试 .rst 文件中的代码 sn-ps。在许多情况下,最重要的测试是对 yaml 配置的简单有效性检查。

例如:

>>> my_yaml = """
... foo:
...   bar:
...    - baz1
...    - baz2
... """
>>> my_yaml_dict = yaml.load(my_yaml_string, Loader=yaml.FullLoader)
>>> assert "baz_2" in my_yaml_dict["foo"]["bar"]

为了使代码更具可读性和可复制粘贴,我想只显示 yaml 块,并将测试本身放在隐藏的代码块中。

这行得通:

>>> my_yaml = """
... foo:
...   bar:
...    - baz1
...    - baz2
... """

.. invisible-code-block: python

    >>> my_yaml_dict = yaml.load(my_yaml_string, Loader=yaml.FullLoader)
    >>> assert "baz_2" in my_yaml_dict["foo"]["bar"]

但是,yaml 块仍然封装在my_yaml="""...""" 中,这使得复制粘贴变得困难。

有没有办法将代码块本身视为变量?我在想像这样的事情:

.. code-block:: yaml # doctest: +varname=my_yaml_string

    foo:
      bar:
       - baz1
       - baz2

.. invisible-code-block: python

    >>> my_yaml_dict = yaml.load(my_yaml_string, Loader=yaml.FullLoader)
    >>> assert "baz_2" in my_yaml_dict["foo"]["bar"]

【问题讨论】:

    标签: python yaml pytest doctest


    【解决方案1】:

    根据文档,我认为更改/跳过文档字符串分隔符(>>> ... )是不可能的:

    任何预期的输出都必须紧跟在包含代码的最后 '>>> ' 或 '... ' 行之后,并且预期的输出(如果有)延伸到下一个 '>>> ' 或全空白行。 https://docs.python.org/3/library/doctest.html#how-are-docstring-examples-recognized

    另一种解决方案是将上述 Yaml 数据移动到外部变量,该变量未在 doctest 块中定义:

    my_yaml_string = """
    foo:
        bar:
          - baz1
          - baz2
    """
    

    然后可以直接从 doctest 块中使用上面的变量:

    >>> my_yaml_dict = yaml.load(my_yaml_string, Loader=yaml.FullLoader)
    >>> assert "baz_2" in my_yaml_dict["foo"]["bar"]
    

    另外my_yaml_string 变量可以在另一个模块中定义以不影响运行时性能:

    >>> import test_constants
    >>> my_yaml_dict = yaml.load(test_constants.my_yaml_string, Loader=yaml.FullLoader)
    >>> assert "baz_2" in my_yaml_dict["foo"]["bar"]
    

    此外,测试数据可以完全移动到单独的文件中。这具有为所选数据序列化语言(在本例中为 Yaml)启用静态分析器覆盖的额外好处:

    # test_data.yaml
    foo:
        bar:
          - baz1
          - baz2
    
    >>> my_yaml_dict = yaml.load(open("test_data.yaml"), Loader=yaml.FullLoader)
    >>> assert "baz_2" in my_yaml_dict["foo"]["bar"]
    

    请注意,"test_data.yaml" 可能需要转换为绝对路径,具体取决于文档测试的执行方式。

    【讨论】:

    • 将测试数据分离到其他文件中看起来很有希望。我会试一试。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2011-12-12
    • 1970-01-01
    • 1970-01-01
    • 2021-09-29
    • 2018-10-23
    • 1970-01-01
    • 2013-03-26
    • 2014-10-17
    相关资源
    最近更新 更多