37. Testing in Django
Code testing is a way that we can be sure that our code works, as we believe it doesn’t crash and meets the specifications for the application we’re trying to build.
Code tests are mostly functions that we’ll write shortly that run other parts of our application code automatically.
Writing tests is typically done in one of two ways. In test driven development, we would write our tests before we write the application code. And in this scheme, we know that the application code is correct as it passes the test. Alternatively, we can write tests after we’ve written some application code. There are different benefits to either method.
We can use Python’s unit testing frameworks to achieve some of our testing aims. And Django provides some easy hooks to allow us to handle such testing.
Let’s go back to our working environment:
$ cd bioweb $ python -m venv env $ env\Scripts\activate
We can now install FactoryBoy, a helper package which will help us automate our tests.
(env) $ pip install factory_boy
Once it’s installed we can go back and run our server:
(env) $ cd bioweb (env) $ python manage.py runserver
Then we need somewhere in our project to host our model factories, so in our application directory, we create a new file called model_factories.py.
37.02 Fixtures with FactoryBoy
Our web application, like most others, critically relies on a database. This means that when we come to test it, our testing is going to be made up of two components.
On one side, we’ll have a way of populating our test database with some temporary, fixed testing data. On the other side, we’re going to have one or more files that contain our application tests.
We’re going to be using the Python package Factory Boy to provide a means of creating what are called test fixtures. A fixture is a consistent, repeatable piece of data or code that we can use repeatedly throughout our tests when we run them.
In this instance, our fixtures are going to be data that we add into a test database. The Package FactoryBoy is a version of the popular Ruby package called Factory Bought.
First we need to go to model_factories.py and import the packages we need in order to write test fixtures for our database.
import factory from django.test import TestCase from django.conf import settings from django.core.files import File from .models import *
As our fixtures represent the models in our database, we have to import all of our models at the end there.
Our API and HTML views implement both the list of genes and a way of viewing gene details. We need to write fixtures that cover each of the models that our gene list and our gene details covers.
The first of those is for the EC table because the EC table and sequencing tables are foreign key connected to our gene table.
class ECFactory(factory.django.DjangoModelFactory): ec_name = "transferase" class Meta: model = EC
Our model factory inherits from the generic factory package, and there’s a specific DjangoModelFactory for using with Django.
Then we have to name each of the fields in the model, and then give it some dummy data that will be used on testing. Last of all, we need to attach which model it refers to. Now we can do much the same thing for the sequencing factory.
class SequencingFactory(factory.django.DjangoModelFactory): sequencing_factory = "Sanger" factory_location = "UK" class Meta: model = Sequencing
We can now write a factory for our gene model:
class GeneFactory(factory.django.DjangoModelFactory): gene_id = "GeneX" entity = "Plasmid" start = 12 stop = 100 sense = "+" start_codon = "M" sequencing = factory.SubFactory(SequencingFactory) ec = factory.SubFactory(ECFactory) access = 0 class Meta: model = Gene
These are just the fields in the gene model, with some fixed default information that we can use in our tests. Then in order to include the foreign keys, just attach the factories that we just wrote to these fields.
At runtime, when the GeneFactory is used, it will populate each of these fields, and then it will add each of our predefined factories, and it will add the relevant fields for those as well.
These are our text fixtures written, and we can move on to actually start writing our tests in the next post.
Wednesday 1 December 2021, 51 views
Next post: 38. Writing API tests
Previous post: 36. Class-based views in the Django REST framework
Advanced Web Development index
- 38. Writing API tests
- 37. Testing in Django
- 36. Class-based views in the Django REST framework
- 35. Building a RESTful web service in Django
- 34. Introduction to CRUD, REST and APIs
- 33. Refactoring with generic views in Django
- 32. Django validators
- 31. Django forms (2) – using the ModelForm class
- 30. Django forms (1)
- 28. Adding CSS to the template
- 27. Django templating
- 26. Deleting and updating records
- 25. Joins, filters and chaining commands
- 24. Using the ORM in views.py
- 23. Adding to the database by writing a script
- 22. Adding to the database with Django Admin
- 21. Migrations
- 20. ORM – work through example
- 19. An introduction to the Object-Relational Mapper
- 18. Altering the database
- 17. SQL functions and summaries
- 16. SQL Query performance
- 15. Queries and table joins in SQL
- 14. Inserts and queries in SQL
- 13. Good practice in relational database design
- 12. Limitations to database modelling
- 11. Building a database using SQL
- 10. Introduction to PostgreSQL
- 9. How to start writing a new application in Django
- 8. Building a lightweight project
- 7. Django URLs
- 6. Django templates
- 5. Django models
- 4. Django views
- 3. Creating a new hello app
- 2. Creating a new virtual environment
- 1. Setting up Django