During the process of automatically closing the interface, we often encounter scenarios such as "Request 2 needs to use the data responded to Request 1". The common approach is to make use case dependencies or write the response results of Request 1 to a file. When used Read the file. Of course, this is not the focus of this article. This article mainly introduces cache
writing and reading cache data.
request.config.cache
Students who don’t understand it yet request fixture
can read the article written by me first.
Let’s look at the use case first:
def test_01(cache):
cache.set("token", "uiouoouoiou")
def test_02(cache):
r = cache.get("token", None)
test_01
In this way, the value will be cached when the code is executed token
, and the value test_02
can be read from the cache at any time of execution token
. How is that Cache
achieved? Let's take a look at the source code. Direct access to source code
Implementation principle
def test_01(cache):
cache.set("token", {"token": "1212121"})
We cache.set()
make a breakpoint on this line. debug
After execution, debug
the result is
cache = Cache()
_CACHE_PREFIX_DIRS = 'd'
_CACHE_PREFIX_VALUES = 'v'
_cachedir = /PycharmProjects/panda-test/org/.pytest_cache
_config = <_pytest.config.Config object at 0x109e80d60>
You can see that a cache instance is automatically created and some data is initialized. By default, the cache file should be in the .pytest_cache
directory
/_pytest/cacheprovider.py
@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
As you can see, cache
what is returned is Cache
an object. Let’s see Cache
how the object is implemented.
def set(self, key: str, value: object) -> None:
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)
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)
This source code is used to save key-value pairs into the cache. The code is relatively simple, please explain briefly.
- Get the path of the key-value pair to be saved: Get the path ( ) of the value ( ) in the cache
_getvaluepath()
based on the given key ( ) by calling the method. The path here is a string separated by different levels, usually the first name is the name of the plugin or application.key
value
path
/
- Check whether the path exists: Determine whether the path needs to be created by judging whether the parent directory of the path is a directory. If the parent directory already exists, it
cache_dir_exists_already
is set toTrue
; otherwise, it checks if the cache directory exists and if the cache directory already exists, it iscache_dir_exists_already
set toTrue
, otherwise it creates the cache directory. - Ensure that the supporting files exist: If the cache directory is newly created, call
_ensure_supporting_files()
the method to ensure that the supporting files exist. This method may be used to create other cache-related files or directories. - Serialize the data and write it to a file:
value
Serialize the value ( ) using JSON format to ensure it is a basic Python type or contains nested types (such as lists and dictionaries). Then, try to open the file corresponding to the path (encoded using UTF-8) and write the serialized data to the file.
def get(self, key: str, default):
path = self._getvaluepath(key)
try:
with path.open("r", encoding="UTF-8") as f:
return json.load(f)
except (ValueError, OSError):
return default
This source code is used to obtain the value of the specified key from the cache. Here is a brief explanation:
- Get the path to get the value: Get the path of the value in the cache ( )
_getvaluepath()
based on the given key ( ) by calling the method. The path here is a string separated by different levels, usually the first name is the name of the plug-in or application.key
path
/
- Attempts to read a file and return cached values: open the file with the path (encoded in UTF-8) and
json.load(f)
load the data in the file as a Python object using . The loaded value is then returned. ValueError
Handling exceptions: If the contents of the file cannot be parsed into valid JSON data or opening the file fails, exceptions ( and ) are caughtOSError
and the default value (default
) is returned.
I still learned a novel way of writing here, which I have never used before, which is with path.open("r", encoding="UTF-8") as f:
equivalent toopen(path, "r", encoding="UTF-8")
These are two commonly used methods. Of course, there are more methods provided. Here is a brief introduction:
-
__init__(self, cachedir: Path, config: Config, *, _ispytest: bool = False) -> None
:- Initialization method, used to set the properties of the class
_cachedir
and_config
.
- Initialization method, used to set the properties of the class
-
for_config(cls, config: Config, *, _ispytest: bool = False) -> "Cache"
:- Class method that creates and returns an instance based on given configuration information
Cache
. - If the configuration item
cacheclear
is set toTrue
and the cache directory exists, callclear_cache
the method to clear the cache. - Finally, a new
Cache
instance is returned.
- Class method that creates and returns an instance based on given configuration information
-
clear_cache(cls, cachedir: Path, _ispytest: bool = False) -> None
:- Class method, clear the subdirectories under the cache directory.
- Build a subdirectory path based on the parameter
cachedir
andrm_rf
delete the directory recursively using the function.
-
cache_dir_from_config(config: Config, *, _ispytest: bool = False) -> Path
:- Static method, obtains the path of the cache directory from the given configuration information.
- First get the string representation of the cache directory from the configuration, then use
resolve_from_str
the function to parse itPath
and return it as an object.
-
warn(self, fmt: str, *, _ispytest: bool = False, **args: object) -> None
:- A way to issue cache warnings.
- Use
warnings.warn
the function to issue a warning message and specify the warning typePytestCacheWarning
. - If the parameter is present
args
, it is used as a formatting parameter replacing the placeholder in the format string.
-
mkdir(self, name: str) -> Path
:- Create a directory path object and create the directory under the cache directory.
- Parameter
name
is the name of the directory to be created. - Checks whether the directory name contains a path separator
/
and throws an exception if so. - Use
_cachedir.joinpath
the method to build the full directory path, andmkdir
the method to create the directory. - Returns the created directory path object.
-
_getvaluepath(self, key: str) -> Path
:- Generates the path to the value file based on the given key.
- Build the value file path in the cache directory, using
_CACHE_PREFIX_VALUES
as subdirectory prefix.
-
_ensure_supporting_files(self) -> None
:- Create support files in the cache directory.
- Create
README.md
a file describing the purpose of the cache directory. - Create
.gitignore
the file, ignoring all files in the cache directory. - Create
CACHEDIR.TAG
a file that marks the cache directory.
at last
cache
The function is still very practical, such as the login function, which can be written to the cache after logging in token
, so that when making other interface requests, it can token
be obtained directly from the cache when needed token
.
Finally: The complete software testing video tutorial below has been compiled and uploaded. Friends who need it can get it by themselves [guaranteed 100% free]
Software Testing Interview Document
We must study to find a high-paying job. The following interview questions are from the latest interview materials from first-tier Internet companies such as Alibaba, Tencent, Byte, etc., and some Byte bosses have given authoritative answers. After finishing this set I believe everyone can find a satisfactory job based on the interview information.