Trouble with Test After Introducing django-axes

Published: (January 4, 2026 at 03:33 AM EST)
2 min read
Source: Dev.to

Source: Dev.to

Background

What is django-axes?

django-axes is a Django package that monitors login attempts and locks out users based on authentication settings. It helps prevent brute‑force attacks.

Official documentation

Why I used django-axes

I was working on a collaborative project to develop a small app with a login feature. To prevent brute‑force attacks, we wanted to limit the number of login attempts, so we decided to introduce django-axes.

Issue

After implementing django-axes, I ran all tests. Many tests that previously passed started failing. The failures were all related to login functionality because the tests did not include a request object.

When tests use client.login (as shown below), the user is authenticated without an HTTP request. However, django-axes determines whether a user is authenticated by inspecting the request, causing the failures.

Failing pattern (using client.login)

self.user = User.objects.create_user(
    username="login_user",
    email="login@example.com",
    password="LoginPass123",
)

self.client.login(email="login@example.com", password="LoginPass123")

Working pattern (using client.post)

self.user = User.objects.create_user(
    username="login_user",
    email="login@example.com",
    password="LoginPass123",
)

self.client.post(
    self.login_url,
    {"email": "login@example.com", "password": "LoginPass123"},
    REMOTE_ADDR="192.168.1.1",
)

Solutions

I found two practical ways to resolve the issue.

1. Disable django-axes in tests

Set AXES_ENABLE = False in your test settings to disable django-axes checks during testing.
When you need to test features related to django-axes, re‑enable it with AXES_ENABLE = True.

Disabling Axes components in tests

This approach lets you limit django-axes behavior only to the tests that actually need it.

2. Use force_login()

force_login() bypasses the authentication process that django-axes hooks into. For tests that are not directly related to login verification, it is reasonable to use force_login() instead of client.login().

force_login documentation

Working pattern (using force_login)

self.user = User.objects.create_user(
    username="login_user",
    email="login@example.com",
    password="LoginPass123",
)

self.client.force_login(self.user)

As mentioned earlier, using client.post() also works because it includes a request.

Conclusion

django-axes is a very useful package for enhancing application security. However, when introducing it, we need to be careful about how authentication is handled in tests. Depending on the app architecture and testing strategy, choose the most appropriate solution—either disabling django-axes in tests or using force_login()/client.post() for authentication.

I hope this helps anyone facing similar issues.

Back to Blog

Related posts

Read more »