使用Python的fixture模块生成测试数据

6
我第一次使用fixture模块,试图获取更好的fixture数据以便让我们的功能测试更加完整。但我发现fixture模块有些笨重,希望有更好的方法来完成我的需求。这是一个基于Python 2.7 的 Flask/SQLAlchemy 应用,并且我们使用 nose 作为测试运行器。
我有一组员工数据,每个员工都有自己的角色。应用中有几个页面拥有相对复杂的权限,我希望确保这些权限也被测试到。
我创建了一个 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)

有没有一种方法可以生成装置数据,使我的开发人员不必记住每次添加角色时都要添加一行到装置中?我们在应用程序的其他地方有所有角色的规范列表,因此我有这个。我对这些内容或fixture模块并没有执着,所以我很乐意听取建议!

2
你有没有想到一个好的解决方案? - Eli
我发布了一个(相当晚的)回答,我想知道,你觉得它有用吗? - John Moutafis
1个回答

3

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

  • Assuming that you keep and update accordingly a list of roles (that will be used later on) like this one:

    roles = [ROLE_ENGINEER, ROLE_ADMIN, ROLE_MANAGER, ...]
    
  • Let's create a factory for the Employee table:

    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)
    

    The FuzzyChoice method takes a list of choices and makes a random choice from this list.
    Now this will be able to create any amount of Employee objects on demand.

  • Using the factory:

    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)
    

    Breakdown:

    • EmployeeFactory.create_batch(size=100) Creates 100 Employee objects in the test session.
    • We can access those objects from the factory session.

有关使用factory_boy与SQLAlchemy的更多信息:https://factoryboy.readthedocs.io/en/latest/orms.html?highlight=sqlalchemy#sqlalchemy
特别要注意会话管理:https://factoryboy.readthedocs.io/en/latest/orms.html?highlight=sqlalchemy#managing-sessions


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接