Python Django -在测试过程中向Factory传递多个参数



我目前正在开发一个社交媒体应用程序。在这个应用程序中,当前用户可以通过电子邮件邀请他们的朋友加入该应用程序(具体来说,加入应用程序的"频道",如Discord)。对于这个项目,我正在工作的功能,用户会得到一个错误,如果他们试图邀请的人谁是已经在应用程序(意思是人谁已经在应用程序的数据库)。我正在进行单元测试,以确保在检测到用户已经存在时弹出错误消息。

我设法让我的第一个场景工作,但我有点难为第二个。

这是两个测试的核心文件。

factories.py

class ChannelFactory(factory.django.DjangoModelFactory)
class Meta:
model = Channel
id = int
name = str
class CurrentUserFactory(factory.django.DjangoModelFactory)
class Meta:
model = CurrentUser
user_email = user_email
channel = models.ForeignKey(Channel)

场景#1(当前工作)-一个新用户被邀请加入应用程序,但已经存在于应用程序的数据库

test_forms.py

from tests.factories import ChannelFactory, CurrentUserFactory
@pytest.mark.django_db
def test_that_current_user_cannot_be_reinvited(email, error_message):
"""user that is already in the specific channel cannot be reinvited"""
email = "user@test.com"
error_message = "user@test.com already exists in this channel"
# I am not specifying the channel name because the factory object is supposed to generate it automatically
current_user = CurrentUserFactory(user_email='user@test.com')
invite_form = forms.UserRequestForm({"email":email, channel=current_user.channel)
assert not invite_form is valid()
assert invite_form.errors["email"][0] = error_message

结果:测试通过!

然而,测试通过主要是因为只有一个用户被测试。

现在,我的任务是创建一个测试,看看如果同时邀请几个人会发生什么。该应用程序允许输入逗号分隔的字符串,所以理论上一次最多可以邀请10封电子邮件。

场景#2 -两个新用户被邀请到同一个频道,并且都存在于应用程序的数据库中。这就是我遇到问题的地方,因为我需要以某种方式确保CurrentUsers生成到相同的通道。

from tests.factories import CurrentUserFactory

@pytest.mark.django_db
def tests_that_multiple_current_users_cannot_be_reinvited(emails, error_message):
"""users that are already in the specific channel cannot be reinvited"""
emails = ["user@test.com", "user2@test.com"]
error_message = "The following users already exist in this channel: user@test.com, user2@test.com"
#here, I attempt to "force" a Channel instance
channel = Channel(id="5", name="Hometown Friends")
current_users = [
(CurrentUserFactory(user_email='user@test.com', channel=channel)),
(CurrentUserFactory(user_email='user2@test.com', channel=channel)),
]
invite_form = forms.UserRequestForm({"email":emails, "channel":current_users.channel})
assert not invite_form is valid()
assert invite_form.errors["email"][0] = error_message

当我尝试运行测试时:

E AttributeError: 'tuple' object has no attribute 'channel'

我想知道我是否可以通过尝试使用元组来轻松解决这个问题,或者是否有一个更简单的方法,我不知怎么没有看到。帮助将非常感激!

元组是将一些对象存储在一起的另一种方式,如列表或数组。

你试图从这里的元组中获取属性'channel':

invite_form = forms.UserRequestForm({"email":emails, "channel":current_users.channel})

由于您在元组中放置了两个对象,因此您需要向python提供您希望从中获取属性的对象的确切地址。

试试这个:

invite_form_1 = forms.UserRequestForm({"email":emails[0], "channel":current_users[0].channel})
invite_form_2 = forms.UserRequestForm({"email":emails[1], "channel":current_users[1].channel})

现在你告诉python查看元组current_users中的第一个对象并获取其属性'channel',然后在第二行中查看该元组中的第二个对象。

显然,在这种情况下,您还必须分别断言这两种形式。

如果你想测试x个表单,你也可以使用循环:

invite_forms = []
for i in x:
invite_forms.append(
forms.UserRequestForm({"email":emails[i], "channel":current_users[i].channel}))

(只要确保email和current_users有足够的对象!)

这里你添加了x个UserRequestForm对象到invite_forms元组/列表中。

同样,这将要求您还遍历断言。

最新更新