pytest文檔80 - 內置 fixtures 之 cache 寫入中文顯示\u4e2d\u6587問題(用打補丁方式解決)


前言

pytest 內置 fixtures 之 cache 寫入中文的時候會在文件中寫入\u4e2d\u6587 這種unicode編碼格式。
如果想在文件中顯示正常的中文,需重新Cache類的set方法來解決

問題描述

pytest 用例 cache 的使用參考前面這篇https://www.cnblogs.com/yoyoketang/p/15747082.html
當cache設置中文的時候,寫入cache文件中文顯示

問題原因

出現這個問題的根本原因是python3 的json庫留下來的一個坑,先看以下簡單的實例

import json

a = '上海-悠悠'
print(json.dumps(a))

# ensure_ascii=False
print(json.dumps(a, ensure_ascii=False))

運行結果

"\u4e0a\u6d77-\u60a0\u60a0"
"上海-悠悠"

使用json調用dumps方法的時候默認ensure_ascii參數為True

def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True,
        allow_nan=True, cls=None, indent=None, separators=None,
        default=None, sort_keys=False, **kw):

所以會導致中文在轉json的時候,是以\u4e0a\u6d77這種編碼格式顯示的.

Cache類的set方法

pytest 內置 fixtures 之 cache 是 Cache 類的實例,看下 Cache 類的 set 方法實現

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, sort_keys=True)
        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)

這里面有一句json.dumps沒傳ensure_ascii參數

data = json.dumps(value, indent=2, sort_keys=True)

問題原因找到了,接下來打個補丁,重寫set方法即可

打補丁

以下這段補丁代碼加到運行用例之前,放到項目根目錄conftest.py文件的開始位置即可

from _pytest.cacheprovider import Cache
import json
"""
作者:上海-悠悠
python QQ交流群:730246532
聯系微信/QQ: 283340479
"""

def new_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, ensure_ascii=False, indent=2, sort_keys=True)
    try:
        f = path.open("w", encoding='utf-8')
    except OSError:
        self.warn("cache could not write path {path}", path=path, _ispytest=True)
    else:
        with f:
            f.write(data)

Cache.set = new_set

主要改動2個地方

# 添加一個參數 ensure_ascii=False
data = json.dumps(value, ensure_ascii=False, indent=2, sort_keys=True)
# 添加一個參數 encoding='utf-8'
f = path.open("w", encoding='utf-8')


網易雲完整視頻課程《pytest+yaml 框架使用與開發》https://study.163.com/course/courseMain.htm?courseId=1213419817&share=2&shareId=480000002230338
報名咨詢wx:283340479 (已報名的同學學習過程中有問題,都可以協助解決)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM