为了账号安全,请及时绑定邮箱和手机立即绑定

如何避免单元测试 Django 视图中的组合爆炸

如何避免单元测试 Django 视图中的组合爆炸

MMMHUHU 2021-07-01 18:39:20
我有一个相当复杂的 Django(Rest Framework)视图,它更新数据库中的一个对象。为了更新对象,需要满足一些条件(这些不是真正的条件,但它们是相似的):用户必须登录用户名需要以 admin更新数据需要根据一些规则有效is_moon_phase_ok需要返回一个单独的昂贵函数True我正在尝试为此视图编写一组可靠的单元测试,我提出的场景如下:when not logged in, return 401when not logged in, return {"fail": "login"}when not logged in, don't touch databasewhen not logged in, don't check moon phasewhen username is not admin_*, return 401when username is not admin_*, return {"fail": "username"}when username is not admin_*, don't touch databasewhen username is not admin_*, don't check moon phasewhen invalid data, return 400when invalid data, return {"fail": "data"}when invalid data, don't touch databasewhen invalid data, don't check moon phasewhen logged in, return 200when logged in, return updated datawhen logged in, check moon phasewhen logged in, update database如您所知,这些单元测试中的每一个都需要大量代码来设置然后执行。就我而言,每个单元测试有 7 到 20 行代码。想象一下,如果需求发生变化,并且它们确实发生了变化,那么忽略测试用例、确保它们仍然适用、根据新需求更新它们等会是多么痛苦。有没有更好的方法来完成同样的事情,使用相同的测试覆盖率,但用更少的劳动力?
查看完整描述

1 回答

?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

对我来说,这听起来很像参数化测试,pytest 对此有支持,基本上你可以编写一个测试并提供输入参数,以及预期的。因此,您只需编写一个测试,但足够通用以支持不同的参数,从而减少了需要维护的代码。在幕后 pytest 使用您定义的参数一一运行相同的测试。编写通用测试可能会引入一些逻辑(如您在我的示例中所见),但我认为您可以接受


作为一个通用的例子:


@pytest.mark.parametrize('is_admin,expected_status_code,expected_error', [

    (True, 200, {}),

    (False, 401, {"fail": "login"})

])

def test_sample(is_admin, expected_status_code, expected_data):

    # do your setup

    if is_admin:

        user =  create_super_user()

    else:

        user =  normal_user()


    # do your request

    response = client.get('something')


    # make assertion on response

    assert response.status_code == expected_status_code

    assert response.data == expected_data

您还可以有多个参数层,例如:


@pytest.mark.parametrize('is_admin', [

    True,

    False

])

@pytest.mark.parametrize('some_condition,expected_status_code,expected_error', [

    (True, 200, {}),

    (False, 401, {"fail": "login"})

])

这将为 is_admin (True/False) 和其他参数的每个组合执行测试,好吗?


查看完整回答
反对 回复 2021-07-06
  • 1 回答
  • 0 关注
  • 106 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号