Testing

I have used Django for a while now and the entire time, I was oblivious of one thing – until I decided to poke around and look into it. And this is writing tests.

Sometimes you hear phrases like "But it works on my machine". It's said a lot. And it happens a lot. Code looks perfect, runs perfectly in development, but in production, it's literal mayhem. Yeah, welcome to deployment hell.

The fix? Write tests.

Not the most exciting part of building software. Nobody opens their laptop excited to write test cases. But the first time a test catches a bug you would have never noticed until a user reported it at 2am — you become a believer.


What is a test case?

A test case is simply code that checks your code. You define what you expect to happen, run the test, and Django tells you if reality matches your expectation. There are three steps:


  1. Arrange: Simulate the environment for the testing. In this case, setup users and give them coins
  2. Act: Perform the action (transfer coins from one user to the other)
  3. Assert: Check if the result matches your expectations (are the coin balances correct?)


from django.test import TestCase
from django.contrib.auth import get_user_model
User = get_user_model()


# Create your tests here.
class CoinSystemTest(TestCase):
    def setUp(self):
        self.sender = User.objects.create(
            username="sender",
            password="password@123",
            coin_balance=100
        )
        self.receiver = User.objects.create(
            username="receiver",
            password="password@123",
            coin_balance=0
        )

    def test_coin_transfer(self):
        amount = 20
        self.sender.coin_balance -= amount
        self.sender.save()

        self.receiver.coin_balance += amount
        self.receiver.save()

        self.assertEqual(self.sender.coin_balance, 80)
        self.assertEqual(self.receiver.coin_balance, 20)

    def test_insufficent_balance(self):
        amount = 500

        if self.sender.coin_balance >= amount:
            self.sender.coin_balance -= amount
            self.sender.save()

            self.receiver.coin_balance += amount
            self.receiver.save()


        self.assertEqual(self.sender.coin_balance, 100)
        self.assertEqual(self.receiver.coin_balance, 0)

Running the test

To run the test, you use:

bash
# 'user' here the app name
python manage.py test user

Green means everything passed. Red means something is broken — and better you find out now than your users finding out later.


The three things tests protect you from

1. Regressions — You fix a bug, then accidentally break something else two weeks later while adding a new feature. Tests catch this before it reaches production.

2. Assumptions — You assume a view returns 200 for authenticated users. You assume a form rejects invalid emails. Tests turn assumptions into verified facts.

3. Refactoring fear — Ever been scared to clean up messy code because you don't know what will break? Tests give you a safety net. Refactor freely, run tests, sleep well.


Start small

You don't need 100% test coverage overnight. Start with the parts of your app that would hurt the most if they broke — authentication, payments, core business logic.

One test is better than zero tests. Ten tests is better than one.

The habit matters more than the volume.


The honest truth

I ignored testing for longer than I should have. I was moving fast, building features, and tests felt like they were slowing me down.

They weren't. I just hadn't been burned badly enough yet.

Write the tests. Future you will be grateful.



Do you write tests? Let me know in the comments how they have helped you.