使用Factory_Boy来编写测试代码吧!
概要:
当你用Python编写测试代码时,如果使用factory_boy,你可以轻松地创建和管理测试数据。我将详细解释如何使用factory_boy。
前提 tí)
-
- WebフレークワークはDjangoを使用
-
- テストフレームワークはPytestを使用
- Model、Serializer、Viewのテストを作成しまs
文件结构
application
├── __init__.py
├── admin.py
├── apps.py
├── migrations
├── models.py
├── serializers.py
├── tests
| ├── factories
| | ├── __init__.py
| | ├── customer.py
| | └── user.py
| ├── models
| | ├── __init__.py
| | ├── customer.py
| | └── user.py
| ├── serializers
| | ├── __init__.py
| | └── user.py
| └── views
| ├── __init__.py
| └── user.py
├── views.py
└── urls.py
最初的设定 (zuì chū de
安装factory_boy
让我们安装factory_boy。
pip install factory_boy
创建模型
本次是
-
- システムユーザ
-
- お客様
- お客様の住所
我们将创建一个model。
由于这次我们正在创建一个独特的系统用户,如果您对详细信息感兴趣,请参考下面的文章。
import uuid
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.validators import UnicodeUsernameValidator
from django.core.validators import RegexValidator
from django.db import models
# カスタムユーザクラスを定義
class User(AbstractUser):
username_validator = UnicodeUsernameValidator()
class Role(models.IntegerChoices):
"""システムユーザのロール
Args:
MANAGEMENT(0): 管理者
GENERAL(1): 一般
PART_TIME(2): アルバイト
"""
MANAGEMENT = 0, "管理者"
GENERAL = 1, "一般"
PART_TIME = 2, "アルバイト"
# 不要なフィールドはNoneにすることができる
first_name = None
last_name = None
date_joined = None
groups = None
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
employee_number = models.CharField(
unique=True,
validators=[RegexValidator(r"^[0-9]{8}$")],
max_length=8,
# 管理者のログイン画面で社員番号と表示される
verbose_name="社員番号",
)
"""社員番号"""
username = models.CharField(
max_length=150,
unique=True,
validators=[username_validator],
)
"""ユーザ名"""
email = models.EmailField(max_length=254, unique=True)
"""メールアドレス"""
role = models.PositiveIntegerField(
choices=Role.choices, default=Role.PART_TIME
)
"""ロール"""
created_at = models.DateTimeField(auto_now_add=True)
"""作成日"""
updated_at = models.DateTimeField(auto_now=True)
"""更新日"""
# デフォルトはusernameだが今回は社員番号を指定
USERNAME_FIELD = "employee_number"
# uniqueのemailとusernameを指定
REQUIRED_FIELDS = ["email", "username"]
class Meta:
ordering = ["employee_number"]
db_table = "User"
def __str__(self):
return self.username
class Customer(models.Model):
"""お客様"""
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
kana = models.CharField(max_length=255)
"""カナ氏名"""
name = models.CharField(max_length=255)
"""氏名"""
birthday = models.DateField()
"""誕生日"""
phone_no = models.CharField(
max_length=11,
validators=[RegexValidator(r"^[0-9]{11}$", "11桁の数字を入力してください。")],
blank=True,
)
"""電話番号"""
address = models.ForeignKey(
"Address",
on_delete=models.CASCADE,
related_name="address",
)
"""住所"""
class Meta:
db_table = "Customer"
class Address(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
prefecture = models.CharField(max_length=255)
"""都道府県"""
municipalities = models.CharField(max_length=255)
"""市区町村"""
house_no = models.CharField(max_length=255)
"""丁・番地"""
other = models.CharField(max_length=255, blank=True)
"""その他(マンション名など)"""
post_no = models.CharField(
max_length=7,
validators=[RegexValidator(r"^[0-9]{7}$", "7桁の数字を入力してください。")],
null=True,
)
"""郵便番号"""
class Meta:
db_table = "Address"
factory_boy的创建方式
在factories文件夹下
-
- user.py
- customer.py
创建并填写所需的设置。
用户.py
使用Django时,我们继承DjangoModelFactory类来定义用于测试数据的类,以便在Django中使用factory_boy。
关于生成密码,我们使用PostGenerationMethodCall来执行Django的set_password函数,以将测试数据的密码设置为”test”并进行加密后保存。
from datetime import datetime, timedelta
from factory import Faker, PostGenerationMethodCall, Sequence
from factory.django import DjangoModelFactory
from application.models import User
class UserFactory(DjangoModelFactory):
class Meta:
model = User
# ユニーク制約があるのでオートインクリメント
username = Sequence(lambda n: "テスト利用者{}".format(n))
employee_number = Sequence(lambda n: "{0:08}".format(n + 100))
password = PostGenerationMethodCall("set_password", "test")
email = Faker("email")
role = Faker(
"random_int",
min=0,
max=2,
)
created_at = Faker(
"date_between_dates",
date_start=(datetime.now() - timedelta(days=20)).date(),
date_end=datetime.now(),
)
updated_at = Faker(
"date_between_dates",
date_start=(datetime.now() - timedelta(days=20)).date(),
date_end=datetime.now(),
)
Faker类
使用Faker可以生成随机测试数据。
本次将使用FactoryBoy的Faker类。
另外,关于下文提到的地址,通过指定locale=”ja_JP”可以生成日本独特的测试数据(例如都道府县等)。
以下是Faker类的源代码。
class Faker(declarations.BaseDeclaration):
"""Wrapper for 'faker' values.
Args:
provider (str): the name of the Faker field
locale (str): the locale to use for the faker
All other kwargs will be passed to the underlying provider
(e.g ``factory.Faker('ean', length=10)``
calls ``faker.Faker.ean(length=10)``)
Usage:
>>> foo = factory.Faker('name')
"""
def __init__(self, provider, **kwargs):
locale = kwargs.pop('locale', None)
self.provider = provider
super().__init__(
locale=locale,
**kwargs)
请参考以下的官方文档以了解详细信息。
顾客.py
通过使用SubFactory,您可以在FK中指定其他Factory的对象。
from datetime import datetime, timedelta
import factory
from factory import Faker, Sequence, SubFactory
from application.models import Address, Customer
class AddressFactory(factory.django.DjangoModelFactory):
class Meta:
model = Address
prefecture = Faker("administrative_unit", locale="ja_JP")
municipalities = Faker("city", locale="ja_JP")
house_no = str(Faker("ban", locale="ja_JP")) + str(
Faker("gou", locale="ja_JP")
)
other = str(Faker("building_name", locale="ja_JP")) + str(
Faker("building_number", locale="ja_JP")
)
post_no = Faker("random_number", digits=7)
class CustomerFactory(factory.django.DjangoModelFactory):
class Meta:
model = Customer
kana = Sequence(lambda n: "テストコキャク{}".format(n))
name = Sequence(lambda n: "テスト顧客{}".format(n))
birthday = Faker(
"date_between_dates",
date_start=(datetime.now().date() - timedelta(days=365 * 50)),
date_end=(datetime.now().date() - timedelta(days=365 * 20)),
)
phone_no = Sequence(lambda n: f"080" + "{0:08}".format(n + 100))
address = SubFactory(AddressFactory)
模型的測試 de
测试用户.py
我将创建用户测试。
user = UserFactory()
只需描述一下,就可以轻松地创建系统用户的测试数据。
另外,
def get_user(id):
return User.objects.get(pk=id)
获取由测试数据创建的数据,并对每个字段使用assert进行测试是否匹配。
如果不匹配,使用pytest.raises来确定会出现什么错误。
employee_number = "1" * 9
with pytest.raises(DataError):
UserFactory(employee_number=employee_number)
以下是测试代码的样式
为了访问数据库,请别忘记加上@pytest.mark.django_db的装饰器
import pytest
from django.db.utils import DataError, IntegrityError
from application.models import User
from application.tests.factories.user import UserFactory
def get_user(id):
return User.objects.get(pk=id)
@pytest.mark.django_db
def test_employee_number_length_can_be_8():
"""employee_numberの長さの最大値が8文字"""
employee_number = "1" * 8
user = UserFactory(employee_number=employee_number)
assert get_user(user.id).employee_number == employee_number
@pytest.mark.django_db
def test_employee_number_length_cannot_be_9_or_longer():
"""employee_numberの長さが9文字以上にならない"""
employee_number = "1" * 9
with pytest.raises(DataError):
UserFactory(employee_number=employee_number)
@pytest.mark.django_db
def test_employee_number_length_cannot_be_null():
"""employee_numberはnullにならない"""
with pytest.raises(IntegrityError):
UserFactory(employee_number=None)
@pytest.mark.django_db
def test_employee_number_length_must_be_unique():
"""employee_numberはuniqueでなければならない"""
employee_number = "1" * 8
UserFactory(employee_number=employee_number)
with pytest.raises(IntegrityError):
UserFactory(employee_number=employee_number)
@pytest.mark.django_db
def test_username_length_can_be_150():
"""usernameの長さの最大値が150文字"""
username = "a" * 150
user = UserFactory(username=username)
assert get_user(user.id).username == username
@pytest.mark.django_db
def test_username_length_cannot_be_151_or_longer():
"""usernameの長さの最大値が151文字以上にならない"""
username = "a" * 151
with pytest.raises(DataError):
UserFactory(username=username)
@pytest.mark.django_db
def test_username_cannot_be_null():
"""usernameはnullにできない"""
with pytest.raises(IntegrityError):
UserFactory(username=None)
@pytest.mark.django_db
def test_username_must_be_unique():
"""usernameはuniqueでなければならない"""
username = "a" * 150
UserFactory(username=username)
with pytest.raises(IntegrityError):
UserFactory(username=username)
@pytest.mark.django_db
def test_email_length_can_be_254():
"""emailの長さの最大値が254文字"""
email = "a" * 245 + "@test.com"
user = UserFactory(email=email)
assert get_user(user.id).email == email
@pytest.mark.django_db
def test_email_length_cannot_be_255_or_longer():
"""emailの長さの最大値が255文字以上にならない"""
email = "a" * 246 + "@test.com"
with pytest.raises(DataError):
UserFactory(email=email)
@pytest.mark.django_db
def test_email_cannot_be_null():
"""emailはnullにできない"""
with pytest.raises(IntegrityError):
UserFactory(email=None)
@pytest.mark.django_db
def test_email_must_be_unique():
"""emailはuniqueでなければならない"""
email = "a" * 245 + "@test.com"
UserFactory(email=email)
with pytest.raises(IntegrityError):
UserFactory(email=email)
@pytest.mark.django_db
def test_role_can_be_management():
"""管理者のロール"""
role = User.Role.MANAGEMENT
user = UserFactory(role=role)
assert get_user(user.id).role == role
@pytest.mark.django_db
def test_role_can_be_general():
"""一般のロール"""
role = User.Role.GENERAL
user = UserFactory(role=role)
assert get_user(user.id).role == role
@pytest.mark.django_db
def test_role_can_be_part_time():
"""アルバイトのロール"""
role = User.Role.PART_TIME
user = UserFactory(role=role)
assert get_user(user.id).role == role
这个测试数据里面有什么内容?
让我们实际查看一下测试数据中的内容吧。
@pytest.mark.django_db
def test_employee_number_length_can_be_8():
"""employee_numberの長さの最大値が8文字"""
employee_number = "1" * 8
user = UserFactory(employee_number=employee_number)
print(user.__dict__)
assert get_user(user.id).employee_number == employee_number
我们可以确认用户列表是以随机方式生成的。
'password':'pbkdf2_sha256$600000$AsfCb2R6rRgu3Kmpbf7aff$elbjshRXzE4DYAuvc/bOWwptY+fn7y4iVbnlVywAXJQ='
'last_login':None
'is_superuser':False
'is_staff':False
'is_active':True
'id':UUID('9a0a7b4b-c7ec-4579-8e71-e6efc8daf567')
'employee_number':'11111111'
'username':'テスト利用者0'
'email':'gford@example.com'
'role':2
'created_at':datetime.datetime(2023, 5, 22, 0, 52, 55, 980457, tzinfo=datetime.timezone.utc)
'updated_at':datetime.datetime(2023, 5, 22, 0, 52, 56, 167401, tzinfo=datetime.timezone.utc)
测试客户.py
顾客的测试也是一样的。
from datetime import datetime, timedelta
import pytest
from django.core.exceptions import ValidationError
from django.db.utils import DataError, IntegrityError
from application.models import Address, Customer
from application.tests.factories.customer import AddressFactory, CustomerFactory
def get_customer(id):
return Customer.objects.get(pk=id)
def get_address(id):
return Address.objects.get(pk=id)
@pytest.mark.django_db
def test_kana_length_can_be_255():
"""カナ氏名の長さの最大値が255文字"""
kana = "a" * 255
customer = CustomerFactory(kana=kana)
assert get_customer(customer.id).kana == kana
@pytest.mark.django_db
def test_name_length_can_be_255():
"""カナ氏名の長さの最大値が255文字"""
name = "a" * 255
customer = CustomerFactory(name=name)
assert get_customer(customer.id).name == name
@pytest.mark.django_db
def test_birthday_can_be_date():
"""誕生日が日付のフォーマット"""
birthday = datetime.now().date() - timedelta(days=365 * 20)
customer = CustomerFactory(birthday=birthday)
assert get_customer(customer.id).birthday == birthday
@pytest.mark.django_db
def test_birthday_is_not_date():
"""誕生日が日付以外のフォーマット"""
birthday = "1995-09-1-8"
with pytest.raises(ValidationError):
CustomerFactory(birthday=birthday)
@pytest.mark.django_db
def test_birthday_cannot_be_null():
"""誕生日nullにできない"""
with pytest.raises(IntegrityError):
CustomerFactory(birthday=None)
@pytest.mark.django_db
def test_phone_length_can_be_11():
"""phone_numberの長さの最大値が11文字"""
phone_no = "080" + "1" * 8
customer = CustomerFactory(phone_no=phone_no)
assert get_customer(customer.id).phone_no == phone_no
@pytest.mark.django_db
def test_phone_length_cannot_be_12_or_longer():
"""phone_numberの長さが12文字以上にならない"""
phone_no = "080" + "1" * 9
with pytest.raises(DataError):
CustomerFactory(phone_no=phone_no)
@pytest.mark.django_db
def test_phone_length_cannot_be_null():
"""phone_numberはnullにならない"""
with pytest.raises(IntegrityError):
CustomerFactory(phone_no=None)
@pytest.mark.django_db
def test_prefecture_length_can_be_255():
"""都道府県の長さの最大値が255文字"""
prefecture = "a" * 255
address = AddressFactory(prefecture=prefecture)
assert get_address(address.id).prefecture == prefecture
@pytest.mark.django_db
def test_municipalities_length_can_be_255():
"""市区町村の長さの最大値が255文字"""
municipalities = "a" * 255
address = AddressFactory(municipalities=municipalities)
assert get_address(address.id).municipalities == municipalities
@pytest.mark.django_db
def test_house_no_length_can_be_255():
"""丁・番地の長さの最大値が255文字"""
house_no = "a" * 255
address = AddressFactory(house_no=house_no)
assert get_address(address.id).house_no == house_no
@pytest.mark.django_db
def test_other_length_can_be_255():
"""その他の長さの最大値が255文字"""
other = "a" * 255
address = AddressFactory(other=other)
assert get_address(address.id).other == other
@pytest.mark.django_db
def test_post_no_length_can_be_7():
"""郵便番号の長さの最大値が7文字"""
post_no = "1" * 7
address = AddressFactory(post_no=post_no)
assert get_address(address.id).post_no == post_no
@pytest.mark.django_db
def test_post_no_length_can_be_8_or_longer():
"""郵便番号の長さが8文字以上にならない"""
post_no = "1" * 8
with pytest.raises(DataError):
AddressFactory(post_no=post_no)
测试配置
本次我们可以在conftest中使用FactoryBoy
-
- Serilaizer
- View
为了使用在这次测试中,我将创建。
import pytest
from django.core.management import call_command
from rest_framework.test import APIClient
from application.models.user import User
from application.tests.factories.user import UserFactory
@pytest.fixture(scope="session")
def django_db_setup(django_db_setup, django_db_blocker):
with django_db_blocker.unblock():
call_command("loaddata", "fixture.json")
@pytest.fixture
def client(scope="session"):
return APIClient()
@pytest.fixture
def management_user(user_password):
return UserFactory(
password=user_password,
role=User.Role.MANAGEMENT,
)
@pytest.fixture
def general_user(user_password):
return UserFactory(
password=user_password,
role=User.Role.GENERAL,
)
@pytest.fixture
def part_time_user(user_password):
return UserFactory(
password=user_password,
role=User.Role.PART_TIME,
)
@pytest.fixture
def user_password():
return "test"
序列化器的测试
把UserSerializer的测试作为例子来创建
在进行Serializer的测试时
-
- validate、to_representationなどSerializerのメソッドの動作確認
- Modelだけではテストできない文字数制限
由于本次未使用validate方法,我们将添加正常情况和员工编号小于7个字符时的异常情况测试。
from rest_framework import serializers
from application.models import User
class UserSerializer(serializers.ModelSerializer):
"""ユーザ用シリアライザ"""
class Meta:
model = User
fields = ["id", "employee_number", "username", "email", "role"]
read_only_fields = ["id", "created_at", "updated_at"]
def to_representation(self, instance):
rep = super(UserSerializer, self).to_representation(instance)
rep["role"] = instance.get_role_display()
return rep
from collections import OrderedDict
import pytest
from application.models import User
from application.serializers.user import UserSerializer
@pytest.mark.django_db
def test_user_serializer_to_representation(management_user):
"""to_representationで設定した形式で取得できる事を確認する"""
serializer = UserSerializer(instance=management_user)
expected = OrderedDict(
[
("id", str(management_user.id)),
("employee_number", management_user.employee_number),
("username", management_user.username),
("email", management_user.email),
("role", management_user.get_role_display()),
]
)
assert serializer.to_representation(serializer.instance) == expected
@pytest.fixture
def user_data():
"""システムユーザのインプットデータ"""
return {
"employee_number": "1" * 8,
"username": "テストユーザ01",
"email": "test@example.com",
"role": User.Role.GENERAL,
}
@pytest.mark.django_db
def test_validate_user_data(user_data):
"""userのデータがバリデーションエラーにならない"""
serializer = UserSerializer(data=user_data)
assert serializer.is_valid()
@pytest.mark.django_db
def test_employee_number_length_cannot_be_7_or_shorter(user_data):
"""userのemployee_numberが7文字以下のためバリデーションエラーになる"""
user_data["employee_number"] = "1" * 7
serializer = UserSerializer(data=user_data)
assert not serializer.is_valid()
查看测试
由于此次测试案例数量较多,我们将仅专注于用户的CRUD测试,并编写相应的测试代码。
from django.http import JsonResponse
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from application.models.user import User
from application.serializers import (
UserSerializer,
)
class UserViewSet(ModelViewSet):
queryset = User.objects.all()
serilaizer_class = UserSerializer
def get_permissions(self):
if self.action in {
"create",
"update",
"destroy",
"partial_update",
}:
permission_classes = [IsManagementUser]
else:
permission_classes = [IsAuthenticated]
return [permission() for permission in permission_classes]
def destroy(self, request, *args, **kwargs):
"""システムユーザを削除するAPI
Args:
request : リクエスト
Returns:
Union[
Response,
JsonResponse
]
"""
instance = self.get_object()
if request.user == instance:
return JsonResponse(
data={"msg": "自身を削除する事は出来ません"},
status=status.HTTP_400_BAD_REQUEST,
)
instance.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
import pytest
from rest_framework import status
from application.models.user import User
from application.tests.factories.user import UserFactory
@pytest.fixture
def get_user_url():
return "/api/users/"
def get_user_details_url(id):
return f"/api/users/{id}/"
@pytest.fixture
def user_data():
return {
"employee_number": "11111111",
"username": "テストユーザ01",
"email": "test_user_01@test.com",
"role": User.Role.MANAGEMENT,
}
@pytest.mark.django_db
def test_management_user_can_list_users(
client, management_user, user_password, get_user_url
):
"""管理者ユーザでユーザの一覧を表示できるテスト"""
client.login(
employee_number=management_user.employee_number, password=user_password
)
response = client.get(get_user_url, format="json")
assert response.status_code == status.HTTP_200_OK
@pytest.mark.django_db
def test_general_user_can_list_users(
client, general_user, user_password, get_user_url
):
"""一般ユーザでユーザの一覧を表示できるテスト"""
client.login(
employee_number=general_user.employee_number, password=user_password
)
response = client.get(get_user_url, format="json")
assert response.status_code == status.HTTP_200_OK
@pytest.mark.django_db
def test_sales_user_can_list_users(
client, part_time_user, user_password, get_user_url
):
"""アルバイトユーザでユーザの一覧を表示できるテスト"""
client.login(
employee_number=part_time_user.employee_number, password=user_password
)
response = client.get(get_user_url, format="json")
assert response.status_code == status.HTTP_200_OK
@pytest.mark.django_db
def test_user_cannot_list_users_without_login(client, get_user_url):
"""ログインなしでユーザの一覧を表示できないテスト"""
response = client.get(get_user_url, format="json")
assert response.status_code == status.HTTP_403_FORBIDDEN
@pytest.mark.django_db
def test_management_user_can_list_user_details(
client, management_user, user_password
):
"""管理者ユーザでユーザの詳細を表示できるテスト"""
user = UserFactory()
client.login(
employee_number=management_user.employee_number, password=user_password
)
response = client.get(get_user_details_url(user.id), format="json")
assert response.status_code == status.HTTP_200_OK
@pytest.mark.django_db
def test_general_user_can_list_user_details(
client, general_user, user_password
):
"""一般ユーザでユーザの詳細を表示できるテスト"""
user = UserFactory()
client.login(
employee_number=general_user.employee_number, password=user_password
)
response = client.get(get_user_details_url(user.id), format="json")
assert response.status_code == status.HTTP_200_OK
@pytest.mark.django_db
def test_part_time_user_can_list_user_details(
client, part_time_user, user_password
):
"""アルバイトユーザでユーザの詳細を表示できるテスト"""
user = UserFactory()
client.login(
employee_number=part_time_user.employee_number, password=user_password
)
response = client.get(get_user_details_url(user.id), format="json")
assert response.status_code == status.HTTP_200_OK
@pytest.mark.django_db
def test_management_user_can_create_user(
client, management_user, user_password, get_user_url, user_data
):
"""管理者ユーザでユーザを作成できるテスト"""
client.login(
employee_number=management_user.employee_number, password=user_password
)
response = client.post(get_user_url, user_data, format="json")
assert response.status_code == status.HTTP_201_CREATED
@pytest.mark.django_db
def test_general_user_cannot_create_user(
client, general_user, user_password, get_user_url, user_data
):
"""一般ユーザでユーザを作成できないテスト"""
client.login(
employee_number=general_user.employee_number, password=user_password
)
response = client.post(get_user_url, user_data, format="json")
assert response.status_code == status.HTTP_403_FORBIDDEN
@pytest.mark.django_db
def test_general_user_cannot_create_user(
client, part_time_user, user_password, get_user_url, user_data
):
"""アルバイトユーザでユーザを作成できないテスト"""
client.login(
employee_number=part_time_user.employee_number, password=user_password
)
response = client.post(get_user_url, user_data, format="json")
assert response.status_code == status.HTTP_403_FORBIDDEN
@pytest.mark.django_db
def test_management_user_can_update_user(
client, management_user, user_password, user_data
):
"""管理者ユーザでユーザを更新できるテスト"""
user = UserFactory()
client.login(
employee_number=management_user.employee_number, password=user_password
)
response = client.put(
get_user_details_url(user.id), user_data, format="json"
)
assert response.status_code == status.HTTP_200_OK
@pytest.mark.django_db
def test_general_user_cannot_update_user(
client, general_user, user_password, user_data
):
"""一般ユーザでユーザを更新できないテスト"""
user = UserFactory()
client.login(
employee_number=general_user.employee_number, password=user_password
)
response = client.put(
get_user_details_url(user.id), user_data, format="json"
)
assert response.status_code == status.HTTP_403_FORBIDDEN
@pytest.mark.django_db
def test_general_user_cannot_update_user(
client, part_time_user, user_password, user_data
):
"""アルバイトユーザでユーザを更新できないテスト"""
user = UserFactory()
client.login(
employee_number=part_time_user.employee_number, password=user_password
)
response = client.put(
get_user_details_url(user.id), user_data, format="json"
)
assert response.status_code == status.HTTP_403_FORBIDDEN
@pytest.mark.django_db
def test_management_user_can_partial_update_user(
client, management_user, user_password, user_data
):
"""管理者ユーザでユーザを一部更新できるテスト"""
user = UserFactory()
client.login(
employee_number=management_user.employee_number, password=user_password
)
response = client.patch(
get_user_details_url(user.id), user_data, format="json"
)
assert response.status_code == status.HTTP_200_OK
@pytest.mark.django_db
def test_general_user_cannot_partial_update_user(
client, general_user, user_password, user_data
):
"""一般ユーザでユーザを一部更新できないテスト"""
user = UserFactory()
client.login(
employee_number=general_user.employee_number, password=user_password
)
response = client.patch(
get_user_details_url(user.id), user_data, format="json"
)
assert response.status_code == status.HTTP_403_FORBIDDEN
@pytest.mark.django_db
def test_general_user_cannot_partial_update_user(
client, part_time_user, user_password, user_data
):
"""アルバイトユーザでユーザを一部更新できないテスト"""
user = UserFactory()
client.login(
employee_number=part_time_user.employee_number, password=user_password
)
response = client.patch(
get_user_details_url(user.id), user_data, format="json"
)
assert response.status_code == status.HTTP_403_FORBIDDEN
@pytest.mark.django_db
def test_management_user_can_delete_user(
client, management_user, user_password, user_data
):
"""管理者ユーザでユーザを削除できるテスト"""
user = UserFactory()
client.login(
employee_number=management_user.employee_number, password=user_password
)
response = client.delete(
get_user_details_url(user.id), user_data, format="json"
)
assert response.status_code == status.HTTP_204_NO_CONTENT
@pytest.mark.django_db
def test_general_user_cannot_delete_user(
client, general_user, user_password, user_data
):
"""一般ユーザでユーザを削除できないテスト"""
user = UserFactory()
client.login(
employee_number=general_user.employee_number, password=user_password
)
response = client.delete(
get_user_details_url(user.id), user_data, format="json"
)
assert response.status_code == status.HTTP_403_FORBIDDEN
@pytest.mark.django_db
def test_general_user_cannot_delete_user(
client, part_time_user, user_password, user_data
):
"""アルバイトユーザでユーザを削除できないテスト"""
user = UserFactory()
client.login(
employee_number=part_time_user.employee_number, password=user_password
)
response = client.delete(
get_user_details_url(user.id), user_data, format="json"
)
assert response.status_code == status.HTTP_403_FORBIDDEN
@pytest.mark.django_db
def test_user_cannot_delete_yourself(
client, management_user, user_password, user_data
):
"""自身を削除できないテスト"""
client.login(
employee_number=management_user.employee_number, password=user_password
)
response = client.delete(
get_user_details_url(management_user.id), user_data, format="json"
)
assert response.status_code == status.HTTP_400_BAD_REQUEST
assert response.json() == {"msg": "自身を削除する事は出来ません"}
总结
使用factory_boy后,测试代码的可读性提高了,写起来更有乐趣了。虽然测试代码在确保程序质量方面非常重要,但却需要相当的精力。所以我希望能像现在这样利用factory_boy来提高效率。
以下内容为中文本地语言释义,请提供一个选项:
引用