如何使用pytest忽略测试中的警告?

我正在尝试测试使用DatetimeFields的函数.我想测试的功能如下:

def get_pledge_frequency(last_week_pledges):
    """Returns two lists:
    pledge_frequency: containing the number of pledges per day of the last week
    weekdays: containing a letter that represents the day
    It assumes that last_week_pledges are pledges made within the last week.
    """
    pledge_frequency = []
    weekdays = []

    if last_week_pledges:
        last_7_days = [timezone.now() - timedelta(days=i) for i in range(7)]
        last_7_days.reverse()
        day_names = 'MTWTFSS'

        for day in last_7_days:
            pledge_frequency.append(
                last_week_pledges.filter(timestamp__date=day).count())
            weekdays.append(day_names[day.weekday()])

    return pledge_frequency, weekdays

我使用pytest进行测试,所以我实现的测试如下:

pledge_frequency_ids = ['no_pledges', 'one_pledge_today',
                        'one_pledge_not_today', 'two_pledges_same_day',
                        'two_pledges_not_same_day', 'multiple_pledges_a',
                        'multiple_pledges_b']

pledge_data = [
    ('2018-03-30', [], ([], [])),
    ('2018-03-30', ['2018-03-30'], ([0] * 6 + [1], 'SSMTWTF')),
    ('2018-03-30', ['2018-03-27'], ([0, 0, 0, 1, 0, 0, 0], 'SSMTWTF')),
    ('2018-03-31', ['2018-03-29', '2018-03-29'], ([0, 0, 0, 0, 2, 0, 0], 'SMTWTFS')),
    ('2018-03-28', ['2018-03-26', '2018-03-28'], ([0, 0, 0, 0, 1, 0, 1], 'TFSSMTW')),
    ('2018-04-01', ['2018-03-26', '2018-03-26', '2018-03-27', '2018-03-28'], ([2, 1, 1, 0, 0, 0, 0], 'MTWTFSS',)),
    ('2018-03-29', ['2018-03-25', '2018-03-26', '2018-03-27', '2018-03-28'], ([0, 0, 1, 1, 1, 1, 0], 'FSSMTWT'))]

@pytest.mark.parametrize('today, pledge_information, pledge_frequency',
                         pledge_data, ids=pledge_frequency_ids)
@pytest.mark.django_db
@mock.patch('django.utils.timezone.now')
@mock.patch('pledges.models.Pledge')
def test_get_pledge_frequency(_, mock_now, social_user, today,
                              pledge_information, pledge_frequency):
    """Tests to verify correctness of get_pledge_frequency() function.
    Covering the following cases:
    * No pledges
    * One pledge today
    * One pledge not today
    * Two pledges the same day
    * Two pledges not the same day
    * Multiple pledges particular case 0
    * Multiple pledges particular case 1"""
    mock_now.return_value = timezone.datetime.strptime(today, '%Y-%m-%d')
    for pledge_info in pledge_information:
        pledge = Pledge()
        pledge.user = social_user
        pledge.save()
        pledge.timestamp = timezone.datetime.strptime(pledge_info, '%Y-%m-%d')
        pledge.save()

    last_week_pledges = Pledge.objects.all()
    expected_frequency, expected_weekdays = pledge_frequency
    expected_weekdays = list(expected_weekdays)
    actual_frequency, actual_weekdays = get_pledge_frequency(last_week_pledges)

    assert expected_frequency == actual_frequency
    assert expected_weekdays == actual_weekdays

测试通过,但问题是我收到以下警告:

RuntimeWarning: DateTimeField Pledge.timestamp received a naive datetime (2018-03-29 00:00:00) while time zone support is active.

实际上,我得到了几个RuntimeWarning,它在时区支持处于活动状态时通知使用天真的日期时间.

如何禁用此测试的警告?我发现使用@ pytest.mark.filterwarnings可能很有用,我已将标签添加为:@ pytest.mark.filterwarnings(‘ignore:RuntimeWarning’).但是,这没有用,在运行测试后我仍然有这些警告.

装饰器的位置顺序是否重要?我尝试了几种组合,但它还没有用.

在文档中我发现我可以将addopts = -p no:warnings添加到我的pytest.ini文件中,但是如果我得到另一个生成此警告的测试,我不想遵循这种方法.

解决方法:

根据pytest documentation,@ pytest.mark.filterwarnings实际上是正确的方法,问题是我传递的参数不正确.这个问题解决了:

@pytest.mark.filterwarnings('ignore::RuntimeWarning') # notice the ::

所以测试的工作原理如下:

pledge_frequency_ids = ['no_pledges', 'one_pledge_today',
                        'one_pledge_not_today', 'two_pledges_same_day',
                        'two_pledges_not_same_day', 'multiple_pledges_a',
                        'multiple_pledges_b']

pledge_data = [
    ('2018-03-30', [], ([], [])),
    ('2018-03-30', ['2018-03-30'], ([0] * 6 + [1], 'SSMTWTF')),
    ('2018-03-30', ['2018-03-27'], ([0, 0, 0, 1, 0, 0, 0], 'SSMTWTF')),
    ('2018-03-31', ['2018-03-29', '2018-03-29'], ([0, 0, 0, 0, 2, 0, 0], 'SMTWTFS')),
    ('2018-03-28', ['2018-03-26', '2018-03-28'], ([0, 0, 0, 0, 1, 0, 1], 'TFSSMTW')),
    ('2018-04-01', ['2018-03-26', '2018-03-26', '2018-03-27', '2018-03-28'], ([2, 1, 1, 0, 0, 0, 0], 'MTWTFSS',)),
    ('2018-03-29', ['2018-03-25', '2018-03-26', '2018-03-27', '2018-03-28'], ([0, 0, 1, 1, 1, 1, 0], 'FSSMTWT'))]

@pytest.mark.parametrize('today, pledge_information, pledge_frequency',
                         pledge_data, ids=pledge_frequency_ids)
@pytest.mark.filterwarnings('ignore::RuntimeWarning')
@pytest.mark.django_db
@mock.patch('django.utils.timezone.now')
@mock.patch('pledges.models.Pledge')
def test_get_pledge_frequency(_, mock_now, social_user, today,
                              pledge_information, pledge_frequency):
    """Tests to verify correctness of get_pledge_frequency() function.
    Covering the following cases:
    * No pledges
    * One pledge today
    * One pledge not today
    * Two pledges the same day
    * Two pledges not the same day
    * Multiple pledges particular case 0
    * Multiple pledges particular case 1"""
    mock_now.return_value = timezone.datetime.strptime(today, '%Y-%m-%d')
    for pledge_info in pledge_information:
        pledge = Pledge()
        pledge.user = social_user
        pledge.save()
        pledge.timestamp = timezone.datetime.strptime(pledge_info, '%Y-%m-%d')
        pledge.save()

    last_week_pledges = Pledge.objects.all()
    expected_frequency, expected_weekdays = pledge_frequency
    expected_weekdays = list(expected_weekdays)
    actual_frequency, actual_weekdays = get_pledge_frequency(last_week_pledges)

    assert expected_frequency == actual_frequency
    assert expected_weekdays == actual_weekdays
上一篇:PHP usort()期望参数2是有效的回调,而不是在类中


下一篇:PHP / IIS copy()/ move_uploaded_file()无法打开流:权限被拒绝警告