3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Django REST frameworkのGETとPOSTリクエストをpytestでテストしたい

Posted at

はじめに

テストなくしては安心して開発をすることはできません。

私はこれまでpythonの開発を行う時にpytestを使って単体テストや結合テストを行なってきました。

これからDjango REST frameworkを触ることになりそうなのでDjangoでのテスト実装方法について調べておきたいと思い、記事を作成しました。

環境

記事を作成した時に使用した端末はMacbook Pro 16のM1Proモデルです。

$ uname -om
Darwin arm64

本記事の内容はこちらのリポジトリで内容を確認することができますので、よければ参考にしてください。

必要なライブラリ

筆者はpipenvを使って環境を構築しています。
必要なライブラリは以下となっております。

requirements.txt
pytest
pytest-django
Django
django-filter
djangorestframework
markdown

テストディレクトリ構成について

テストのディレクトリ構造について2つ方法を見かけたの両方紹介します。

  1. 機能毎にディレクトリを分ける方法
  2. プロジェクト丸ごと一つのディレクトリでテストを管理する方法
README.md
# 1. 機能毎にディレクトリを分ける方法
sample/
├─ foo/
│  ├─ tests/
│  │  ├─ foo_tests.py
├─ bar/
│  ├─ tests/
│  │  ├─ bar_tests.py

# 2. プロジェクト丸ごと一つのディレクトリでテストを管理する方法
sample/
├─ foo/
├─ bar/
├─ tests/
│  ├─ foo_tests.py
│  ├─ bar_tests.py

小規模のプロジェクトであれば2の丸ごと管理でも良いかもしれませんが、せっかくRESTfulな設計にするのであれば機能毎にディレクトリを分けてテストを実装しておくと機能が増えた時も安心だと思います。

テスト実装の方法について

GETリクエスト

まず単純なGETリクエストを実装します。

my_api/sample/views.py
from rest_framework import APIView
from rest_framework.response import Response

class OnlyViews(APIView):
    def get(self, request, format=None):
        return Response(
            ["foo", "bar"]
        )
my_api/my_api/urls.py
from django.contrib import admin
from django.urls import path
from sample.views import OnlyViews

urlpatterns = [
    path('admin/', admin.site.urls),
    path("only_views/", OnlyViews.as_view(), name="show foo bar"),

次に先ほど作成したgetリクエストのテストを実装します。
以下の実装を行い、pytest run sampleを実行することでテストができるようになります。

my_api/sample/tests/test_views.py
import pytest
from rest_framework.test import APIRequestFactory

from sample.views import OnlyViews

class TestAPIViewTests:
    def test_get(self):
        factory = APIRequestFactory()
        view = OnlyViews.as_view()

        url = "http://127.0.0.1:8000/my_api/only_views"
        request = factory.get(url)

        response = view(request)
        assert response.data == ["foo", "bar"]

POSTリクエスト

次に単純なPOSTリクエストの実装を行います。
かなり無理やりな実装になっていますがサンプルのため、処理は適当に書いていますのでご容赦ください。。

my_api/sample/views.py

class OnlyViews(APIView):
    ...

    def post(self, request, format=None):
        
        return Response(int(request.data.get("number")) + 1)

GETとリクエストと同じように実装することができますが、postする内容の記載を忘れないようにしてください。

my_api/sample/tests/test_views.py
class TestAPIViewTests:
    ...

    def test_post(self):
        factory = APIRequestFactory()
        view = OnlyViews.as_view()

        url = "http://127.0.0.1:8000/my_api/only_views"
        request = factory.post(url, {'number': 10})

        response = view(request)
        assert response.data == 11

さいごに

今回はサラッとDRFでGETとPOSTリクエストのテスト実装方法についてまとめました。
基本的な機能だけでなく、もっとさらに進んだテストを行いたい場合はDjango REST frameworkのテスト公式ドキュメントをご参照ください。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?