pytest-redis
pytest-redis is a pytest plugin that provides Redis fixtures and fixture factories, enabling developers to test code that relies on a running Redis database. It simplifies the setup and teardown of Redis instances for testing, offering fixtures for Redis processes and clients. The current version is 4.0.0 and it maintains an active release cadence, primarily updating to support newer Python and pytest versions.
Common errors
-
pytest_redis.exceptions.RedisMisconfigured: Could not find redis-server executable.
cause The `redis-server` executable is not found in the system's PATH or was not explicitly provided to pytest.fixInstall Redis server, add its directory to your system's PATH environment variable, or run pytest with the `--redis-exec /path/to/redis-server` option. -
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType' (often seen with redis-py client methods)
cause This typically occurs when `redis-py` (the underlying Redis client library) returns `None` for operations that previously returned an `int` or a byte string, especially after upgrading `redis-py` to version 4.x or higher, or due to incorrect `decode_responses` handling.fixCheck the `redis-py` documentation for the specific command causing the error. Ensure you are handling `bytes` vs. `str` correctly, potentially by passing `decode_responses=True` when creating a `redis.Redis` client (or when using `factories.redisdb` if it supports it), or explicitly decoding responses. Pin `redis-py` to a specific version if necessary, e.g., `redis<4.4.0`.
Warnings
- gotcha The `redis-server` executable must be available in your system's PATH, or its path must be explicitly provided via the `--redis-exec` command-line option for pytest. Failure to do so will result in a `RedisMisconfigured` error during test collection.
- gotcha When running tests in parallel, `pytest-redis` uses different Redis databases (DB 0-15) to isolate tests. However, using `FLUSHALL` in your tests will clear *all* databases, breaking test isolation and causing unexpected failures in parallel runs.
- breaking Users should be aware of breaking changes in `redis-py` versions (e.g., `redis-py` 4.0.0+). These can affect how you interact with the `redisdb` client yielded by `pytest-redis` fixtures. Notable changes include argument order for commands like `SETEX` and `LREM`, return types for `TTL`/`PTTL`, and the default handling of `decode_responses`.
Install
-
pip install pytest-redis
Imports
- redisdb
def test_something(redisdb):
- redis_proc
def test_something_with_proc(redis_proc):
- redis_noproc
def test_something_with_noproc(redis_noproc):
- factories
import pytest_redis.factories
from pytest_redis import factories
Quickstart
import pytest
from redis import Redis
from pytest_redis import factories
import os
# Basic test using the default function-scoped redisdb fixture
def test_can_connect(redisdb: Redis):
# Ensure environment variables for Redis connection (if needed by redis-py)
# are not hardcoded in actual tests, though pytest-redis manages the server.
# For direct Redis client instantiation, you might do:
# client = Redis(host=os.environ.get('REDIS_HOST', 'localhost'),
# port=int(os.environ.get('REDIS_PORT', '6379')))
redisdb.set("ping", "pong")
assert redisdb.get("ping") == b"pong"
print(f"Redis DB size: {redisdb.dbsize()}")
# Creating custom fixtures using factories
# Example: A session-scoped Redis process with a specific port or configuration
custom_redis_proc = factories.redis_proc(port=6380)
# A client fixture that uses the custom process
# Note: The string 'custom_redis_proc' matches the variable name of the proc fixture
custom_redis_client = factories.redisdb('custom_redis_proc')
# Test using the custom client fixture
def test_custom_redis_instance(custom_redis_client: Redis):
custom_redis_client.set("mykey", "myvalue")
assert custom_redis_client.get("mykey") == b"myvalue"
assert custom_redis_client.info()['tcp_port'] == 6380