はじめに
自分用の個人開発のメモ/備忘録として記録していきます。
環境
django5.0
↓ dockerでの開発環境作成はこちら
↓ 認証ユーザーモデルはこちらをそのまま利用
やりたいこと
Serializerのテストを一通り書いてみる
前回
Modelのテスト
Viewのテスト
テストについて下調べ
おもに下記のようなテストをやる模様。
No | カテゴリ | 内容 |
---|---|---|
1 | シリアライザインスタンスの作成 | テスト対象のシリアライザインスタンスを作成 |
2 | バリデーションテスト | シリアライザが適切なバリデーションルールを適用していることを確認 |
3 | シリアライズプロセスのテスト | オブジェクトが正しいJSONデータにシリアライズされるかをテスト |
4 | デシリアライズプロセスのテスト | JSONデータが正しくモデルインスタンスにデシリアライズされるかをテスト |
5 | フィールドレベルのテスト | 定義したフィールドが適切に処理されているかを確認 |
準備
とりあえずSerializerを準備
・ユーザー>プロジェクト>リスト>チケット>コメントとリレーションしているモデルを利用
・チケットはコメントをネストしたTicketDetailSerializerを別途準備
・プロジェクトは、リスト>チケットまでをネストしたProjectDetailSerializerを準備
from rest_framework import serializers
from .models import Project, List, Ticket, Comment
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = '__all__'
class TicketSerializer(serializers.ModelSerializer):
class Meta:
model = Ticket
fields = '__all__'
class ListSerializer(serializers.ModelSerializer):
class Meta:
model = List
fields = '__all__'
class ProjectSerializer(serializers.ModelSerializer):
user = serializers.HiddenField(default=serializers.CurrentUserDefault())
class Meta:
model = Project
fields = '__all__'
class TicketDetailSerializer(serializers.ModelSerializer):
comments = CommentSerializer(many=True)
class Meta:
model = Ticket
fields = '__all__'
class ListDetailSerializer(serializers.ModelSerializer):
tickets = TicketSerializer(many=True)
class Meta:
model = List
fields = '__all__'
class ProjectDetailSerializer(serializers.ModelSerializer):
user = serializers.HiddenField(default=serializers.CurrentUserDefault())
lists = ListDetailSerializer(many=True)
class Meta:
model = Project
fields = '__all__'
test_serializers.pyを書いていく
setUp
テストのセットアップ
メソッドを使用してテストケースの初期データを設定
各テスト実行前に自動的に呼び出され、テストに必要なデータを生成
ProjectSerializerがCurrentUserDefault()を使っているので、APIRequestFactoryにてリクエストを作成し、userを割り当て
シリアライザに context パラメータを渡すことで、シリアライザ内で request を使用出来るようにする
class ProjectSerializerTestCase(TestCase):
def setUp(self):
User = get_user_model()
self.user = User.objects.create_user(email='testuser@test.com', password='12345')
self.project_data = data={'name': 'Example Project', 'description': 'Example Description'}
self.factory = APIRequestFactory()
self.request = self.factory.get('/') # メソッドは何でもよい、リクエストを作る必要がある
self.request.user = self.user # テストユーザーをリクエストに割り当てる
test_serializer_with_empty_data
空のデータに対するバリデーション
このテストメソッドは、空のデータでシリアライザを初期化し、そのバリデーションが失敗することを検証
def test_serializer_with_empty_data(self):
serializer = ProjectSerializer(data={}, context={'request': self.request})
self.assertFalse(serializer.is_valid())
self.assertIn('name', serializer.errors)
self.assertNotIn('user', serializer.errors)
test_serializer_with_valid_data
有効なデータに対するバリデーション
シリアライザに渡されたデータが有効であり、is_valid() メソッドが True を返すことを検証
def test_serializer_with_valid_data(self):
serializer = ProjectSerializer(data=self.project_data, context={'request': self.request})
self.assertTrue(serializer.is_valid())
test_serializer_outputs_expected_data
シリアライズプロセスの検証
モデルインスタンスが正確にJSON形式にシリアライズされることを確認
def test_serializer_outputs_expected_data(self):
model_instance = Project.objects.create(name='Example Project', user=self.user)
serializer = ProjectSerializer(model_instance, context={'request': self.request})
self.assertEqual(serializer.data['name'], 'Example Project')
self.assertNotIn('user', serializer.data)
test_deserialization_creates_proper_instance
デシリアライズとインスタンスの作成
提供されたデータからモデルインスタンスが正しく作成されることを確認
def test_deserialization_creates_proper_instance(self):
serializer = ProjectSerializer(data=self.project_data, context={'request': self.request})
self.assertTrue(serializer.is_valid())
instance = serializer.save()
self.assertEqual(instance.name, 'Example Project')
self.assertEqual(instance.user, self.user)
*CommentSerializer/TicketSerializer/ListSerializerも同様に作成する
TicketDetailSerializer(JSON形式へのシリアライズのみ)
class TicketDetailSerializerTestCase(TestCase):
def setUp(self):
User = get_user_model()
self.user = User.objects.create_user(email='testuser@test.com', password='12345')
self.project = Project.objects.create(name='Example Project', user=self.user)
self.list = List.objects.create(title='Example List', project=self.project)
self.ticket = Ticket.objects.create(title='Example Ticket', list=self.list)
self.comment = Comment.objects.create(text='Example Comment', ticket=self.ticket)
def test_serializer_outputs_expected_data(self):
serializer = TicketDetailSerializer(self.ticket)
self.assertEqual(serializer.data['title'], 'Example Ticket')
self.assertEqual(serializer.data['list'], self.list.id)
self.assertEqual(serializer.data['comments'][0]['text'], 'Example Comment')
self.assertEqual(serializer.data['comments'][0]['ticket'], self.ticket.id)
ListDetailSerializer(JSON形式へのシリアライズのみ)
class ListDetailSerializerTestCase(TestCase):
def setUp(self):
User = get_user_model()
self.user = User.objects.create_user(email='testuser@test.com', password='12345')
self.project = Project.objects.create(name='Example Project', user=self.user)
self.list = List.objects.create(title='Example List', project=self.project)
self.ticket = Ticket.objects.create(title='Example Ticket', list=self.list)
def test_serializer_outputs_expected_data(self):
serializer = ListDetailSerializer(self.list)
self.assertEqual(serializer.data['title'], 'Example List')
self.assertEqual(serializer.data['project'], self.project.id)
self.assertEqual(serializer.data['tickets'][0]['title'], 'Example Ticket')
self.assertEqual(serializer.data['tickets'][0]['list'], self.list.id)
ProjectDetailSerializer(JSON形式へのシリアライズのみ)
class ProjectDetailSerializerTestCase(TestCase):
def setUp(self):
User = get_user_model()
self.user = User.objects.create_user(email='testuser@test.com', password='12345')
self.project = Project.objects.create(name='Example Project', user=self.user)
self.list = List.objects.create(title='Example List', project=self.project)
self.ticket = Ticket.objects.create(title='Example Ticket', list=self.list)
def test_serializer_outputs_expected_data(self):
serializer = ProjectDetailSerializer(self.project)
self.assertEqual(serializer.data['name'], 'Example Project')
self.assertNotIn('user', serializer.data)
self.assertEqual(serializer.data['lists'][0]['title'], 'Example List')
self.assertEqual(serializer.data['lists'][0]['project'], self.project.id)
self.assertEqual(serializer.data['lists'][0]['tickets'][0]['title'], 'Example Ticket')
self.assertEqual(serializer.data['lists'][0]['tickets'][0]['list'], self.list.id)
test実行
テスト実行
python manage.py test
全てのテストが成功すればこのような表示となる
Found 19 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
...................
----------------------------------------------------------------------
Ran 19 tests in 4.555s
OK
Destroying test database for alias 'default'...
おわりに
・serializerが複雑になれば、もっとテストも細かく作成する必要がありそう
参考