ASTEROID: Automated, Solution for Testing Efficiently on Replicable, Operative, and Isolated Databases.
This pytest plugin is made for testing with MySQL docker images and is based on the great lovely-pytest-docker plugin by Lovely Systems.
pytest-asteroid extends the lovely-pytest-docker plugin by adding:
- an availability check to make sure the MySQL image is ready for connection before running the database test suite.
- a simple reset state functionality to handle state dependency issues between tests.
Make sure your system has Docker Engine installed and that the docker daemon is running before executing your tests.
Install pytest-asteroid using pip or poetry. We prefer to use poetry as it reduces the amount of files needed in the project and simplifies dependency management and virtual environments.
Install with poetry:
$ poetry add pytest-asteroid --dev
In order to use ASTEROID make sure to have the following environmental variables set for the test DB docker image:
- MYSQL_DATABASE
- MYSQL_ROOT_PASSWORD
# content from conftest.py
###############################################################################
# * Connection to test database
# This fixture uses the ASTEROID fixture get_docker_db_port which, on first
# session-scoped call, will envoke the docker_service startup.
###############################################################################
# Overwrite this fixture if a custom connection type is required
###############################################################################
# NOTE: Here we are using class fixture as we need the connection to close again
# after each test class run if we want to reset state.
# If attemting to reset state, while a connection is open,
# we will have a deadlock.
@pytest.fixture(scope="class")
def get_connection(get_docker_db_port):
conn = pymysql.connect(
database=os.environ["MYSQL_DATABASE"],
port=get_docker_db_port("mysql_db", timeout=30.0),
user="root",
password=os.environ["MYSQL_ROOT_PASSWORD"],
cursorclass=pymysql.cursors.DictCursor,
)
# Start a transaction and rollback to reset state after each test class execution
yield conn
conn.close()
# content from test_state.py
class TestSaveState:
# Test cases to check reset state works
def test_connection_insert(self, get_connection, reset_or_save_db_state):
reset_or_save_db_state("mysql_db", "superheroes")
conn = get_connection
# setup: insert new data
with conn.cursor() as cur:
cur.execute(
"""
INSERT INTO superheroes (name, cape, height_cm, weigth_kg)
VALUES('Dr. Strange', true, 188, 82)
"""
)
conn.commit()
cur.execute("SELECT * FROM superheroes WHERE name = 'Dr. Strange'")
rows = cur.fetchall()
assert len(rows) == 1
Use the examples in the project repository folder tests/ for inspiration on how to use pytest-asteroid and to see examples of test file structure.