Home > Back-end >  Django Unit Test - filtered query results
Django Unit Test - filtered query results

Time:09-16

I am relatively new to Django and very new to writing unit tests. I'd like to ask for assistance but I'm a bit stuck with where to even begin. The app I'm working with allows a teacher to assign multiple assignments to a student. On the student dashboard, an assignment should only be available if the start date <= today's date. The student should only see the first assignment in the list.

I need to compose a unit test to cover this scenario:

  • manually assign multiple assignments to a student
  • use the same query that is used for the student dashboard to ensure that the only assignments returned are the ones with a start date <= today's date
  • ensure that the student only sees the first assignment (with the earliest start date) in the list.

Below I have posted the relevant code that is pulling what displays on the student dashboard. Please let me know if additional code is needed to help me get started with this. Thanks very much for any help you can offer!

Edit: I would like to only use the built in django.test features for now, if possible

from my home/views.py file

@login_required
def index(request):
    user_type = request.user.type.text
    if user_type == 'Student':
        """ Only return the first test so the student sees one test at a time"""

        assignment = Assignment.objects.filter(
            student=request.user,
            start_date__lte=datetime.date.today(),
            completed=False).first()

        if (assignment):
            context = {
                'test_pk': assignment.test.pk,
            }
        else:
            context = {}
        return render(request, 'home/student.html', context)
    

CodePudding user response:

Basics of testing stuff like this goes roughly like:

  • Create the desired data manually
  • Create the action/conditions that are happening in the view(maybe send a request to the view)
  • Check the result with the previously manually created data.

So, start with creating some Assignment objects for students. Run your view(send a request to your view logged in as the previously created user) Check if the desired outcome exist in the returned html.

CodePudding user response:

I would suggest you to use pytest and factoryboy for that, there's a lot of great tutorials online to use it with Django.

For you example it would be something like this You need first to init the session, we can create fixture for that

import pytest
import factory

@pytest.fixture
def client():
    from django.test.client import Client
    return Client(HTTP_USER_AGENT='pytest')

then we should init the session, another fixture:

@pytest.fixture
def session(client):
    # your custom session her
    user = #use factory for the user
    client.user = user
    # your defaults for
    # client.GET 
    # client.POST 
    # client.META

    return client

class AssignmentFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = Assignment
        django_get_or_create = ('any attribute you like',)

    # default the attributes you want to create here
    # For example
    name = "assignment one"

Then the test can be something like this

@pytest.mark.django_db
def test_retrieve_assignment_success(session):
    path = reverse("view_name")
    assignment = AssignmentFactory()
    res = session.get(path=path, data={}, follow=False)
    json_res = res.json()
    
    assert json_res.get('context') is not None 
    assert assigment.pk == json_res.get('context').get('test_pk')

@pytest.mark.django_db
def test_retrieve_assignment_fail(session):
    path = reverse("view_name")
    res = session.get(path=path, data={}, follow=False)
    json_res = res.json()

    assert json_res.get('context') is not None    
    assert json_res.get('context') == {}
  • Related