W | eb

Django: 테스트를 하는 테스트를 하는 테스트를 테스트

덞웖이 2024. 10. 11. 21:00

준비

더보기

- Ubuntu Server 22.04 
- VSCode Insider 
- Remote SSH Extension 
- Postman Extension
- Python 3.10 venv
- Django 5.1.1
- SQLite 3.37.2

pip install coverage

Unit Test

더보기

polls_api/tests.py

from django.test import TestCase
from polls_api.serializers import QuestionSerializer, VoteSerializer
from django.contrib.auth.models import User
from polls.models import *

class VoteSerializerTestCase(TestCase):
    def test_vote_serializer(self):
        user = User.objects.create(username='testuser')
        question = Question.objects.create(
            question_text='test text',
            owner=user,
        )
        choice = Choice.objects.create(
            question=question,
            choice_text='choice1'
        )
        data={
            'question': question.id,
            'choice': choice.id,
            'voter': user.id
        }
        serializer = VoteSerializer(data=data)
        self.assertTrue(serializer.is_valid())
        vote = serializer.save()
        self.assertEqual(vote.question, question)
        self.assertEqual(vote.choice, choice)
        self.assertEqual(vote.voter, user)
        
    # same user, diff vote on the same question
    def test_vote_serializer_dupe_test(self):
        user = User.objects.create(username='testuser')
        question = Question.objects.create(
            question_text='test text',
            owner=user,
        )
        choice1 = Choice.objects.create(
            question=question,
            choice_text='choice1'
        )
        choice2 = Choice.objects.create(
            question=question,
            choice_text='choice2'
        )
        Vote.objects.create(question=question, choice=choice1, voter=user)
        data={
            'question': question.id,
            'choice': choice2.id,
            'voter': user.id
        }
        serializer = VoteSerializer(data=data)
        self.assertFalse(serializer.is_valid())

class QuestionSerializerTestCase(TestCase):
    # method name must start with test_
    # def test_a(self):
    #     # python은 항상 Strict equal?
    #     self.assertEqual(1, 2)
    # def test_b(self):
    #     pass # 강제 통과

    def test_with_valid_data(self):
        serializer = QuestionSerializer(data={'question_text': 'abc'})
        self.assertEqual(serializer.is_valid(), True)

        new_question = serializer.save()
        self.assertIsNotNone(new_question.id)

    def test_with_invalid_data(self):
        serializer = QuestionSerializer(data={'question_text': ''})    
        self.assertEqual(serializer.is_valid(), False)

Execute Tests

python manage.py test

Integration Test(아마도)

더보기

polls_api/tests.py

# ...
from rest_framework.test import APITestCase
from django.urls import reverse
from rest_framework import status
from django.utils import timezone
# ...

# ...
class QuestionListTest(APITestCase):
    def setUp(self):
        self.question_data = {'question_text': 'some question'}
        self.url= reverse('question-list') # don't use lazy within a method? elaborate?

    def test_create_question(self):
        user = User.objects.create(username='test', password='test')
        self.client.force_authenticate(user=user) # 강제 로그인
        response = self.client.post(self.url, self.question_data)
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(Question.objects.count(), 1)
        question = Question.objects.first()
        self.assertEqual(question.question_text, self.question_data['question_text'])
        # was created less than a second ago?
        self.assertLess((timezone.now() - question.pub_date).total_seconds(), 1) # first is smaller than the last
        
# ...

Execute Test

# 테스트 개별로 실행하기
python manage.py test polls_api.tests.QuestionListTest

# 테스트 coverage 테스트 coverage 테스트 coverage 테스트
coverage run manage.py test
# 실행 끝난 후
coverage report

# 전부 커버 하도록 테스트 보완해보기

 

CRUD is short for Crush, Ruin, Undermine and Destroy