如何测试不同格式的日期和日期时间?
How can I test dates and datetimes in different formats?
我有一个正在单元测试的网络应用程序。我正在尝试测试 drf 序列化程序,但序列化程序更改了日期时间的格式,因此格式不同的相同日期未通过测试,因为它们不相同。
我试过格式化序列化程序 timeDateField,但它们使用的所有 strftime 格式都是零填充的,而我的测试用户上次登录属性给出的日期没有零填充。我认为解决方案 可以 以所选答案描述 here 的方式解决,但这似乎有点粗略,理想情况下,我作为必须维护此代码的人,想要一个更干净或更 pythonic 的解决方案。
这是测试:
class UserTest(TestCase):
def setup(self):
last_login = datetime.datetime(2000, 1, 1, hour=0, minute=0, second=0, microsecond=0, tzinfo=None)
date_joined = datetime.datetime(2019, 2, 2, hour=2, minute=2, second=2, microsecond=2, tzinfo=None)
birthdate = timezone.now().date()
renewal = timezone.now().date()
return User.objects.create(username='test_user', first_name='test_first', last_name='test_last',
email='test_mail', last_login=last_login, date_joined=date_joined,
birthdate=birthdate, gender='U', renewal=renewal)
def test_user_serializer(self):
self.u = self.setup()
serializer = UserSerializer(self.u, many=False)
data = serializer.data
.....
# tests for serialized attributes
self.assertEquals((data['last_login']), self.u.last_login) # FAILING THE TEST
这是 UserSerializer:
class UserSerializer(serializers.ModelSerializer):
last_login = serializers.DateTimeField
date_joined = serializers.DateTimeField
birthdate = serializers.DateField
renewal = serializers.DateField
class Meta:
model = User
fields = ('__all__')
这是我遇到的错误:
self.assertEquals(data['last_login'], self.u.last_login)
AssertionError: '2000-01-01T00:00:00Z' != datetime.datetime(2000, 1, 1, 0, 0)
在模型中,last_login 属性是一个 dateTimeField。
我应该尝试更改正在测试的元素之一的格式,还是可以编写一个测试来比较日期而不考虑格式?
请指教。谢谢你。
您出错的原因是您试图对两个不同的 datatypes/objects 进行比较。在下面一行:-
'2000-01-01T00:00:00Z' != datetime.datetime(2000, 1, 1, 0, 0)
在左轴我们有一个字符串(ISO 8601 时间戳格式),在右轴我们有一个日期时间对象。所以上面的操作总会报错,因为数据类型不一样。
所以你有两个选择,要么你可以使用类似 strftime()
的函数将 RHS(日期时间对象)转换为字符串。或者您可以从 LHS(时间戳字符串)创建一个日期时间对象。
我将解释第一种方法,因为它是两种方法中更简单的一种。
因此,为了将日期时间对象转换为字符串,我们必须通过 strftime()
.
传递它
strftime() takes as argument a datetime object**/tuple, and converts it into a string according to format specification.
因此,如果我们使用 ISO 8601 格式规范通过 strftime()
传递 datetime.datetime(2000, 1, 1, 0, 0)
,那么我们将获得所需的格式。
例子:-
import datetime
datet_obj = datetime.datetime(2000, 1, 1, 0, 0)
datet_str = datet_obj.strftime("%Y-%m-%dT%H:%M:%SZ")
print(datet_str)
输出:-
'2000-01-01T00:00:00Z'
通过这种方式,您可以将日期时间对象转换为所需格式的字符串。
现在,如果我们为所有内容创建一个衬里,然后进行比较,即
'2000-01-01T00:00:00Z' != datetime.datetime(2000, 1, 1, 0, 0).strftime("%Y-%m-%dT%H:%M:%SZ")
上面的代码 运行 成功并输出 False,因为 LHS 和 RHS 都相等。
** 日期时间对象通常是 strptime()
.
的输出
最简单的方法是:
assert response.json()["created_at"] == serializers.DateTimeField().to_representation(instance.created_at)
对 Vasu Deo.S 的答案进行了一些修改,其中在格式中包含了微秒。
import datetime
datet_obj = datetime.datetime(2000, 1, 1, 0, 0)
datet_str = datet_obj.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
print(datet_str)
输出
2000-01-01T00:00:00.000000Z
我有一个正在单元测试的网络应用程序。我正在尝试测试 drf 序列化程序,但序列化程序更改了日期时间的格式,因此格式不同的相同日期未通过测试,因为它们不相同。
我试过格式化序列化程序 timeDateField,但它们使用的所有 strftime 格式都是零填充的,而我的测试用户上次登录属性给出的日期没有零填充。我认为解决方案 可以 以所选答案描述 here 的方式解决,但这似乎有点粗略,理想情况下,我作为必须维护此代码的人,想要一个更干净或更 pythonic 的解决方案。
这是测试:
class UserTest(TestCase):
def setup(self):
last_login = datetime.datetime(2000, 1, 1, hour=0, minute=0, second=0, microsecond=0, tzinfo=None)
date_joined = datetime.datetime(2019, 2, 2, hour=2, minute=2, second=2, microsecond=2, tzinfo=None)
birthdate = timezone.now().date()
renewal = timezone.now().date()
return User.objects.create(username='test_user', first_name='test_first', last_name='test_last',
email='test_mail', last_login=last_login, date_joined=date_joined,
birthdate=birthdate, gender='U', renewal=renewal)
def test_user_serializer(self):
self.u = self.setup()
serializer = UserSerializer(self.u, many=False)
data = serializer.data
.....
# tests for serialized attributes
self.assertEquals((data['last_login']), self.u.last_login) # FAILING THE TEST
这是 UserSerializer:
class UserSerializer(serializers.ModelSerializer):
last_login = serializers.DateTimeField
date_joined = serializers.DateTimeField
birthdate = serializers.DateField
renewal = serializers.DateField
class Meta:
model = User
fields = ('__all__')
这是我遇到的错误:
self.assertEquals(data['last_login'], self.u.last_login)
AssertionError: '2000-01-01T00:00:00Z' != datetime.datetime(2000, 1, 1, 0, 0)
在模型中,last_login 属性是一个 dateTimeField。
我应该尝试更改正在测试的元素之一的格式,还是可以编写一个测试来比较日期而不考虑格式?
请指教。谢谢你。
您出错的原因是您试图对两个不同的 datatypes/objects 进行比较。在下面一行:-
'2000-01-01T00:00:00Z' != datetime.datetime(2000, 1, 1, 0, 0)
在左轴我们有一个字符串(ISO 8601 时间戳格式),在右轴我们有一个日期时间对象。所以上面的操作总会报错,因为数据类型不一样。
所以你有两个选择,要么你可以使用类似 strftime()
的函数将 RHS(日期时间对象)转换为字符串。或者您可以从 LHS(时间戳字符串)创建一个日期时间对象。
我将解释第一种方法,因为它是两种方法中更简单的一种。
因此,为了将日期时间对象转换为字符串,我们必须通过 strftime()
.
strftime() takes as argument a datetime object**/tuple, and converts it into a string according to format specification.
因此,如果我们使用 ISO 8601 格式规范通过 strftime()
传递 datetime.datetime(2000, 1, 1, 0, 0)
,那么我们将获得所需的格式。
例子:-
import datetime
datet_obj = datetime.datetime(2000, 1, 1, 0, 0)
datet_str = datet_obj.strftime("%Y-%m-%dT%H:%M:%SZ")
print(datet_str)
输出:-
'2000-01-01T00:00:00Z'
通过这种方式,您可以将日期时间对象转换为所需格式的字符串。
现在,如果我们为所有内容创建一个衬里,然后进行比较,即
'2000-01-01T00:00:00Z' != datetime.datetime(2000, 1, 1, 0, 0).strftime("%Y-%m-%dT%H:%M:%SZ")
上面的代码 运行 成功并输出 False,因为 LHS 和 RHS 都相等。
** 日期时间对象通常是 strptime()
.
最简单的方法是:
assert response.json()["created_at"] == serializers.DateTimeField().to_representation(instance.created_at)
对 Vasu Deo.S 的答案进行了一些修改,其中在格式中包含了微秒。
import datetime
datet_obj = datetime.datetime(2000, 1, 1, 0, 0)
datet_str = datet_obj.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
print(datet_str)
输出
2000-01-01T00:00:00.000000Z