【问题标题】:Generating fixture data with Python's fixture module使用 Python 的夹具模块生成夹具数据
【发布时间】:2012-11-08 23:27:58
【问题描述】:

我是第一次使用fixture 模块,试图获得一组更好的fixture 数据,这样我就可以使我们的功能测试更加完整。

我发现夹具模块有点笨拙,我希望有更好的方法来做我正在做的事情。这是 Python 2.7 中的 Flask/SQLAlchemy 应用程序,我们使用鼻子作为测试运行程序。

所以我有一组员工。员工有角色。有一些页面具有相当复杂的权限,我想确保对这些页面进行测试。

我创建了一个具有每种角色类型的 DataSet(我们的应用中大约有 15 个角色):

class EmployeeData(DataSet):

  class Meta:
    storable = Employee

  class engineer:
    username = "engineer"
    role = ROLE_ENGINEER

  class manager:
    username = "manager"
    role = ROLE_MANAGER

  class admin:
    username = "admin"
    role = ROLE_ADMIN

我想做的是编写一个功能测试来检查只有合适的人可以访问页面。 (实际的权限要复杂得多,我只是想给你一个玩具示例。)

类似这样的:

def test_only_admin_can_see_this_page():

  for employee in Employee.query.all():
    login(employee)

    with self.app.test_request_context('/'):
    response = self.test_client.get(ADMIN_PAGE)
    if employee.role == ROLE_ADMIN
      eq_(200, response.status_code)
    else:
      eq_(401, response.status_code)

    logout(employee)

有没有一种方法可以生成夹具数据,这样我的开发人员就不必记住每次添加角色时都在夹具上添加一行?我们有所有角色的规范列表作为应用程序其他地方的配置,所以我有。

我不喜欢这个或夹具模块中的任何一个,所以我很高兴听到建议!

【问题讨论】:

  • 你有没有为此想出一个好方法?
  • 我发布了一个(很晚的)答案,我想知道,你觉得它有帮助吗?

标签: python sqlalchemy flask nose


【解决方案1】:

一个选项是使用factory_boy 来创建您的测试数据。

  • 假设您保留并相应地更新一个角色列表(稍后将使用),如下所示:

    roles = [ROLE_ENGINEER, ROLE_ADMIN, ROLE_MANAGER, ...]
    
  • 让我们为Employee 表创建一个工厂:

    import factory
    from somewhere.in.the.app import roles
    
    class EmployeeFactory(factory.alchemy.SQLAlchemyModelFactory):
        class Meta:
            model = Employee
            sqlalchemy_session = session
    
        username = factory.Sequence(lambda n: u'User %d' % n)
        # Other attributes
        ...
        # Now the role choice
        role = factory.fuzzy.FuzzyChoice(roles)
    

    FuzzyChoice 方法接受一个选择列表并从该列表中随机选择。
    现在这将能够按需创建任意数量的Employee 对象。

  • 使用工厂:

    from factory.location import EmployeeFactory
    
    def test_only_admin_can_see_this_page():
        EmployeeFactory.create_batch(size=100)
    
        for employee in session.query(Employee).all():
            login(employee)
    
            with self.app.test_request_context('/'):
            response = self.test_client.get(ADMIN_PAGE)
            if employee.role == ROLE_ADMIN
                eq_(200, response.status_code)
            else:
                eq_(401, response.status_code)
    
            logout(employee)
    

    细分:

    • EmployeeFactory.create_batch(size=100) 在测试会话中创建 100 个 Employee 对象。
    • 我们可以从工厂session访问这些对象。

有关在 SQLAlchemy 中使用 factory_boy 的更多信息:https://factoryboy.readthedocs.io/en/latest/orms.html?highlight=sqlalchemy#sqlalchemy
尤其要小心会话管理:https://factoryboy.readthedocs.io/en/latest/orms.html?highlight=sqlalchemy#managing-sessions

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-27
    相关资源
    最近更新 更多