pytest:如何干掉类似的模型管理器方法测试

pytest: How to DRY up similar model manager method tests

我有什么

经理和模特

与经理一起,我可以得到那些已完成、经过培训或规定的案例。

from datetime import date

class CaseManager(models.Manager):
    """Define a manager for Case model."""

    def fulfilled(self):
        """Get all cases that will fulfill soon."""
        return self.get_queryset().filter(fulfillment=date.today())

    def caducated(self):
        """Get all cases that will caducate soon."""
        return self.get_queryset().filter(caducity=date.today())

    def prescribed(self):
        """Get all cases that will prescribe soon."""
        return self.get_queryset().filter(prescription=date.today())

class Case(models.Model):
    """Representation of a legal case."""

    fulfillment = models.DateField(verbose_name=_("Fulfillment"), default=date.today)
    caducity = models.DateField(verbose_name=_("Caducity"), default=date.today)
    prescription = models.DateField(verbose_name=_("Prescription"), default=date.today)

    objects = CaseManager()

工厂

创建假案例进行测试。

class CaseFactory(DjangoModelFactory):
    """Define Case Factory"""

    fulfillment = Faker("date")
    caducity = Faker("date")
    prescription = Faker("date")

    class Meta:
        model = Case

我试过的

测试

class TestCasesManagers:
    def test_fulfilled(self):
        case = CaseFactory(fulfillment=date.today())
        assert case in Case.objects.fulfilled()

    def test_caducated(self):
        case = CaseFactory(caducity=date.today())
        assert case in Case.objects.caducated()

    def test_prescribed(self):
        case = CaseFactory(prescription=date.today())
        assert case in Case.objects.prescribed()

问题

使用这种方法,我必须对我的经理的所有类似但不可扩展的方法重复几乎相同的测试。

我想要的

  1. 创建 cases 并更改传递给工厂的关键字参数以创建假模型。
  2. assert中调用管理器的不同方法,不重复相同的代码。

您可以用对象列表概括这些:

class TestCasesManagers:
    kws = [
        ('fulfillment', 'fulfilled'),
        ('caducity', 'caducated'),
        ('prescription', 'prescribed')
    ]

    def make_test(ky, mg):
        def f(self):
            case = CaseFactory(**{<b>ky</b>: date.today()})
            assert case in getattr(Case.objects, <b>mg</b>)()
        return f
    for ky, mg in kws:
        locals()[f'test_{mg}'] = make_test(ky, mg)
    del make_test

因此,您可以轻松地向列表 kws 添加一个额外的 2 元组来测试此组合。这些仍然是 个人 测试,因此您可以决定 运行 只测试 一个 管理器功能,或者只重试失败的功能.