• Pytest系列(31) - config.cache 使用


    基础介绍

    官方地址:https://docs.pytest.org/en/8.0.x/reference/reference.html#config-cache

    • pytest 中,cache 是一个非常有用的功能,它允许测试会话之间持久化状态
    • 这意味着可以在一次测试运行中存储一些值,并在后续的测试运行中访问这些值

    如何使用 cache

    cache 对象通过 pytestFixtureRequest 对象提供,通常在一个 fixture 中获取并返回它

    @fixture
    def cache(request: FixtureRequest) -> Cache:
        """Return a cache object that can persist state between testing sessions.
    
        cache.get(key, default)
        cache.set(key, value)
    
        Keys must be ``/`` separated strings, where the first part is usually the
        name of your plugin or application to avoid clashes with other cache users.
    
        Values can be any object handled by the json stdlib module.
        """
        assert request.config.cache is not None
        return request.config.cache
    

    • pytest 的缓存机制是通过一个名为 .pytest_cache 的目录实现的,该目录位于项目的根目录下
    • config.cache 对象提供了一个简单的键值存储接口,允许测试代码读取和写入缓存数据
    • 一个 key 一个文件

    存储和检索数据

    cache 对象提供了两个主要方法:getset

    • get(key, default=None) 方法用于检索之前存储的值。如果指定的 key 不存在,则返回 default 值。
    • set(key, value) 方法用于存储值。key 应该是一个字符串,而 value 可以是任何可以被 json 标准库模块处理的对象。
    # 设置缓存值
    config.cache.set("key", "value")
    
    # 获取缓存值
    value = config.cache.get("key", None)  # 如果键不存在,返回 None

    键建议使用 / 分隔的字符串,其中第一部分通常是你的插件或应用程序的名称,以避免与其他使用 cache 的代码冲突

    示例

    假设有一个测试,需要从外部API获取数据,但这个操作很耗时,可以在第一次运行测试时从API获取数据,并将其存储在 cache 中。在后续的测试运行中,可以直接从 cache 中检索数据,避免重复的API调用

    def test_external_api(cache):
        # 尝试从缓存中获取数据
        data = cache.get('external_api/data', default=None)
        if data is None:
            # 如果缓存中没有数据,则从API获取并存储到缓存中
            data = fetch_data_from_external_api()  # 假设这是一个函数来获取数据
            cache.set('external_api/data', data)
        
        # 使用数据进行测试
        assert data is not None

    源码解析

    pytest 的缓存机制是在 _pytest/cacheprovider.py 文件中实现的

    def get(self, key: str, default):
        """Return the cached value for the given key.
    
        If no value was yet cached or the value cannot be read, the specified
        default is returned.
    
        :param key:
            Must be a ``/`` separated value. Usually the first
            name is the name of your plugin or your application.
        :param default:
            The value to return in case of a cache-miss or invalid cache value.
        """
        path = self._getvaluepath(key)
        try:
            with path.open("r") as f:
                return json.load(f)
        except (ValueError, OSError):
            return default
    
    def set(self, key: str, value: object) -> None:
        """Save value for the given key.
    
        :param key:
            Must be a ``/`` separated value. Usually the first
            name is the name of your plugin or your application.
        :param value:
            Must be of any combination of basic python types,
            including nested types like lists of dictionaries.
        """
        path = self._getvaluepath(key)
        try:
            if path.parent.is_dir():
                cache_dir_exists_already = True
            else:
                cache_dir_exists_already = self._cachedir.exists()
                path.parent.mkdir(exist_ok=True, parents=True)
        except OSError:
            self.warn("could not create cache path {path}", path=path, _ispytest=True)
            return
        if not cache_dir_exists_already:
            self._ensure_supporting_files()
        data = json.dumps(value, indent=2)
        try:
            f = path.open("w")
        except OSError:
            self.warn("cache could not write path {path}", path=path, _ispytest=True)
        else:
            with f:
                f.write(data)
    • 代码还是比较简单的,key 就是一个文件路径,不存在则创建,然后写入数据
    • 这些方法最终会将数据序列化为 JSON 格式

    __EOF__

  • 本文作者: 小菠萝测试笔记
  • 本文链接: https://www.cnblogs.com/poloyy/p/18094328
  • 关于博主: 阿里高级测开工程师 - 让我装回杯
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    春季高考更名为职教高考,从中职到大学本科研究生升学通道打通
    142 环形链表II
    Linux命令(83)之cut
    为什么引用CSS的link标签放在头部,引用JS的script标签放在body结束标签之前?
    MySQL 8.0 如何修改密码安全策略!!!
    C# HTML
    思腾云计算
    uni-app常用场景速查记录
    【纯虚函数,final/override关键字】
    Linux搭建文件服务器
  • 原文地址:https://www.cnblogs.com/poloyy/p/18094328