Have you ever used Postman for testing fixtures in Django projects? Explore the nitty-gritty of creating fixtures in Postman for software testing in Cypress! Below we walk you through the whole process.
The role of fixtures in automated testing
What are fixtures?
Fixture is a collection of data created by developers and imported into the database during the early stages of the project, such as, for example, the API development stage. Depending on what the application is designed for, fixtures may contain fake user accounts, messages between users, product lists, user roles, etc. Although developers often provide all non-test data, QA specialists also create the necessary fixtures themselves due to greater knowledge of test-crucial data.
Why should you use fixtures?
The use of test fixtures allows the development team to maintain test repeatability, thanks to the fact that the tests are run in an environment that always has the same configuration. What is important enough in this context, test repeatability allows you to verify whether the software in question works in line with your and the client’s expectations. That is directly related to your business goals in software testing.
Furthermore, test fixtures allow QA to accelerate the design and development of tests, as some tests use previously created data, instead of processing it while writing tests. Having all these advantages in mind, in many projects, in addition to performing manual tests, QA specialists also write automated ones and use fixtures.
Creating fixtures in Postman - a step-by-step guide
If you don't know how to create a fixture, make sure to read through our step-by-step instructions on how to create fixtures using Postman for testing in Cypress.
- First, you will need to clone your project’s repository (if you haven't done it yet).
- Create a qa.yml file with environment variables used during the API testing on local environments. Alternatively, you can also ask a BE dev to create this file. The file should be created in the folder where the backend is located:
../project/backend
- As the aim is to use fixtures that will be used only for API tests, you need to create a separate bootstrap file. Add the bootstrap-with-fixtures.py file here:
src/config/management/commands
In the qa.yml file the bootstrap command should have the following value:
bootstrap-with-fixtures.py
bootstrap:
<<: *base
command: manage bootstrap-with-fixtures
Note: Because you want to run tests on CI, make sure the variable in the variable file (api_test_ci.yml) for CI tests is the same.
- Next, open two windows of the terminal and go to your project directory. For me it would look like this:
../project/backend
- Then, enable the Docker and run the application via docker-compose in the 1st terminal window. The below command runs the Docker:
docker-compose -f qa.yml up
OR
docker-compose -f qa.yml up && docker-compose -f qa.yml rm -f
The above command runs the Docker, and upon the Docker closing, the data will be cleaned.
Note: By default, the Django template contains a docker-compose.yml, so the -f switch is not needed. But when we want to use another file, like in our case, we need to specify an alternative compose file, therefore, we need to use the -f switch.
- In the 2nd window run the command Execute to open a bash terminal:
docker-compose exec django bash
- Now you can use Postman to send a POST request with the data you need.
- In the bash terminal (the 2nd window) run the command below to dump data:
python src/manage.py dumpdata -a -o example.json
You should remember that “-a” switch dumps all models - that is the entire database. Usually, only some of them are required.
Want to know more about testing API in Cypress? Check this article and learn about testing REST API!
Sometimes models are connected with other models. In that case, a good idea is to look for the ID of the model you are interested in. If you are more of an inquisitive type, you are bound to appreciate taking a peek into the “models.py” of the application (module) for which they're creating fixtures, and analyze the relations between specific models (the foreign keys, one-to-one or many-to-many relations that is).
If you know what model you need, you can change an -a to a modelName and, of course, give a JSON file a name. If these fixtures are used only to test, it would be a good idea to add “_tests” after the name, e.g., user_test.json).
python src/manage.py dumpdata user -o user_tests.json
- To improve readability, reformat the JSON file.
Using the Visual Studio Code: open the right-click menu and choose the “Format Document” option.
- Move the file to the following location:
../backend/src/model_name/fixtures/nazwa_tests.json
Note: this file naming is a convention that can be changed in the future.
- Having moved the file, you need to add fixtures to the file bootstrap-with-fixtures.py.
bootstrap:
<<: *base
command: manage bootstrap-with-fixtures
The bootstrap-with-fixtures.py file should be located here:
../src/config/management/commands/bootstrap-with-fixtures.py
and it can look in the following way:
from django.core.management import call_command
from django.core.management.base import BaseCommand
class Command(BaseCommand):
_FIXTURES = [
"src/user/fixtures/user_tests.json",
]
def handle(self, *args, **options):
call_command("bootstrap")
for order, fixture in enumerate(self._FIXTURES, start=1):
self.stdout.write(f"[{order}] {fixture}", ending=" - ")
call_command("loaddata", fixture)
- Next in the bash terminal (the 2nd window that is) run the Command to check if you properly added the fixtures to be able to install them later:
./docker/entrypoint.sh fmt && ./docker/entrypoint.sh lint
Justification for this step:
The ./docker/entrypoint.sh file contains some predefined scripts used in the CI pipeline for validating the quality of the code in docker image. We may call it ourselves to verify any issues, thus preventing the CI from possibly failing on us.
It is useful to know that ”fmt” is short for “format” and it performs autofix on the code style, while “lint” runs linters.
- We need to run this command (./docker/entrypoint.sh fmt && ./docker/entrypoint.sh lint) to verify if the changes within the Python code comply with code style rules. Some of the common issues which we wish to avoid that cause failure on the lint stage include: commas, line breaking and so on.
- You should know that you will be informed about any errors or warnings as well as changes (or the lack of them) in the following cases:
- if you need to fix any part of the added code,
- if any files were changed,
- if everything is in order (the case exemplified below).
The fmt part provides information about the files, specifying the number of unchanged ones as well as providing the number of altered and skipped files. Moreover, if any files were changed, it indicates what the change was.
-- black --
All done! ✨ 🍰 ✨
687 files left unchanged.
-- isort --
Skipped 50 files
The lint part also holds the information about the number of unchanged, changed and skipped files, similarly showing (when applicable) what the change was.
-- black --
All done! ✨ 🍰 ✨
687 files would be left unchanged.
-- isort --
Skipped 50 files
-- flake8 --
-- mypy --
Note: If the entrypoint.sh script fixes an issue but, at the same time, there are some issues that can’t be fixed by it, you will need to make changes in the indicated file.
- Now restart the Docker with an empty database to ensure that you have all the data for your new fixtures:
Ctrl+C
(sending a signal once calls a graceful shutdown)
Then:
docker-compose -f qa.yml up
OR
docker-compose -f qa.yml up && docker-compose -f qa.yml rm -f
Note: You should know that if the docker-compose wasn’t shut down gracefully, i.e., by sending a signal twice or more times, it will kill the containers immediately. Also, sometimes using Ctrl + C does not affect all containers. To be able to affect them all, you need to run the following commands:
docker-compose -f qa.yml stop
The above command is used to stop orphans, while the one located below can be applied to remove the states of containers (remove -force):
docker-compose -f qa.yml rm -f
Note: By default the Django template contains the docker-compose.yml, so the -f switch is not needed here. But if this file has a different name than the docker-compose, we always need to use the -f switch.
- To be able to use and/or refer to the newly created objects in tests, it’s good to have a defined file with representations of these entities. When new fixtures are added, new representations should also be added accordingly.
- In the folder in question:
api_tests/cypress/fixtures
add to the file
fixtures.js
(if you don’t have the file, you should create it) only the data that you are using:
export const user = {id: "6a8892f4-38f3-44ge-ba4e-3ec4a847r9k8", name: "Olga", surname: "Kaminska"};
The name of the representation should briefly describe what it contains. If, for example, we have two types of users created - an admin and a regular user - we can name them in that specific way for readability purposes.
For considerably sized applications this file will grow in size. You should use the naming and separations wisely - you may as well convert the file into a few smaller and more contextual files. Readability counts!
- In the file with the test you need to import the necessary variables:
import { user } from '../../fixtures/fixtures'
and use them in your test:
it('Validate if status code is 200 when trying to fetch user data', () => {
cy
.request({
method: 'GET',
url: `${baseUrl}/v1/user/${user.id}/`,
headers: {
"Authorization": "JWT " + token,
},
failOnStatusCode: true
})
.should((response) => {
expect(response.status).to.eq(200)
expect(response.body).to.have.property("id")
expect(response.body["id"]).to.be.equal(user.id)
expect(response.body).to.have.property("name")
expect(response.body["name"]).to.be.equal(user.name)
expect(response.body).to.have.property("surname")
expect(response.body["surname"]).to.be.equal(user.surname);
});
});
Postman makes fixtures work in Cypress
While oftentimes Backend Developers provide us with ready-made fixtures, it sometimes happens that Quality Assurance specialists need a greater number of test fixtures and, thus, have to create them themselves. In such a case, Postman is worth recommending, as it allows us to create fixtures comprehensively, with all the necessary data and, more importantly, saves time in the process of test creation.
All in all, fixtures made in Postman get the job done as long as you remember about a few important steps - among which the following ones should be emphasized:
- saving all the dependencies between data, especially when the user address is being saved in a different fixture than the rest of the user’s personal data,
- adding the file to the bootstrap file,
- making sure to clean the docker data before reopening the docker again and running the test.
Good luck in creating your first fixtures in Postman!
Know all about fixtures in Postman? Dive into the insightful reading about decision tables and their use in software testing.
Looking forward to developing your QA career path in a friendly environment? Visit our Career page and find your dream job now!
Navigate the changing IT landscape
Some highlighted content that we want to draw attention to to link to our other resources. It usually contains a link .