I'm sure you agree that you have to check to see that your codes do what you expect them to do.
Manually testing your code may come as default...
- You go through the user interface and imitate the processes users are expected to follow.
- You use some "print" statements to check inputs and outputs.
- Where a process depends on some database items, you create dummy objects.
- After all these, you ship your application...phew!
...you think you finally finished the project!
Well most of the time, you thought wrong! It is either a bug snuck through or a new feature needs to be added! - You work on whatever it is and ship the application again.
- Suddenly, you are called on that the interface you tested and tested and wrote many print statements for failed to work!
You see where I'm headed with this;
-You do your manual testing all over again and the cycle continues, non-stop!
AUTOMATE TESTING
Apart from being a good developer by writing tests, you save yourself tons of workload albeit in the future.
- You write the test
- You run the test
- You ship the application.
Modifications? - You modify
- You run the test
- You ship the application.
New feature? - You add feature
- You run the test
- You ship the application.
You write the test for your module once and you get to run it as often as you like.
ENOUGH WITH THE TESTING ADVOCACY!
Django documentation explains writing tests
Creating dummy data in your test functions could feel scary and overwhelming especially when you need to populate your database. One way to test quickly is using https://model-bakery.readthedocs.io/en/latest/index.html. It creates the fixtures you need to test your application while you concentrate on writing your tests.
HOW TO USE MODEL BAKERY
Let us assume we have a books app
In our models.py:
from django.db import models class Author(models.Model): name = models.CharField(max_length=250) joined = models.DateField(auto_now_add=True) def __str__(self): return self.name def book_list(self): return self.book_set.all() def active_book_list(self): return self.book_set.filter(published=True) class Book(models.Model): author = models.ForeignKey(Author, on_delete=models.CASCADE) title = models.CharField(max_length=250) synopsis = models.TextField() published = models.BooleanField() pages = models.IntegerField() def __str__(self): return f"{self.title} by {self.author.name}"
To use bakery, run: pip install model_bakery
In your tests.py file,
from django.test import TestCase from model_bakery import baker from books.models import Author, Book class AuthorTest(TestCase): def setUp(self): #create a dummy author self.author = baker.make(Author) #create published books by the author self.published_books = baker.make(Book, author=self.author, _quantity=5) #the first argument is the model of the object you want to create #the second argument, which is optional, is the field(s) you want to #provide value for. It is necessary here because I want to test the #books written by self.author. If I do not set it, bakery will #autogenerate random author(s) for the book(s) #the third argument, which is also optional, is the quantity of objects to #be created self.unpublished_books = baker.make(Book, author=self.author, _quantity=5) #to test that our active_book_list function works properly def test_active_book_list(self): author = self.author published_books = self.author.active_book_list() number_of_published_books = len(published_books) self.assertEqual(number_of_pulished_books, 5) #self.author has 10 books in total but we expect this function to give #return 5 books
Now run: python manage.py test to test your project
Or run: python manage.py test books to test only your books app
Your terminal output should look something like this:
So, every time you fix a bug or add new features run: python manage.py test to test your project or run: python manage.py test books to test only your books app to test that your active_book_list module works as it should.
@Credits: CodeMentor - Alaka Olaide & Full Stack Feed