Learn to reduce repetitive code in bank account tests using pytest fixtures for efficient test setup and management.
In this article, you’ll learn how to reduce repetitive code in your bank account tests using pytest fixtures. When testing your bank account functionality, you might notice that each test requires initializing a bank account instance multiple times. For example:
This repetitive code can become tedious when you have many tests (for example, 50 tests in a single class). Pytest fixtures help minimize this redundancy.
A fixture is simply a function that runs before your tests and sets up the necessary environment, such as creating an instance of a bank account.
We’ll start by creating two fixtures. One fixture initializes a bank account with a zero balance and the other initializes it with a preset balance (e.g., 50). Although you can place fixtures anywhere, the best practice is to define them at the top of your test file. For example:
Copy
Ask AI
import pytestfrom app.calculations import add, subtract, multiply, divide, BankAccount@pytest.fixturedef zero_bank_account(): print("Creating an empty bank account") return BankAccount()@pytest.fixturedef bank_account(): # Returns a bank account with an initial value of 50. return BankAccount(50)
You can use these fixtures by adding them as parameters to your test functions. Below is an example of refactored tests using these fixtures:
Copy
Ask AI
def test_divide(): assert divide(20, 5) == 4def test_bank_set_initial_amount(bank_account): # Using the bank_account fixture that initializes with 50. assert bank_account.balance == 50def test_bank_default_amount(zero_bank_account): # Using the zero_bank_account fixture that initializes with 0. print("Testing my bank account") assert zero_bank_account.balance == 0def test_withdraw(bank_account): bank_account.withdraw(20) assert bank_account.balance == 30
When running the tests with the -s flag (which shows print statements), you’ll see that the fixture runs before your test function. For instance, the output for test_bank_default_amount will display:
Copy
Ask AI
Creating an empty bank accountTesting my bank accountPASSED
This confirms that the fixture is executed prior to the test itself.
Fixtures can also be combined with pytest’s parameterization feature to test multiple scenarios. For example, you can parameterize addition test cases as shown below:
When you run the tests, the output may look like this:
Copy
Ask AI
tests/test_calculations.py::test_withdraw PASSEDtests/test_calculations.py::test_deposit PASSEDtests/test_calculations.py::test_collect_interest PASSEDtests/test_calculations.py::test_bank_transaction[200-100-100] Creating an empty bank accounttests/test_calculations.py::test_bank_transaction[50-10-40] Creating an empty bank accounttests/test_calculations.py::test_bank_transaction[1200-200-1000] Creating an empty bank account============================== 14 passed in 0.09s ==============================
Each parameterized scenario uses the fixture to set up the test environment correctly.
Using pytest fixtures helps eliminate repetitive setup code across multiple tests. They not only simplify your test code for scenarios like deposit and withdrawal operations but also make it easier to manage more complex cases, such as setting up databases or external services.
By combining fixtures with parameterized test cases, you can efficiently cover a wide range of scenarios while keeping your test code concise, maintainable, and SEO-friendly.