0

I have a Django model. Among other things it has a ForeignKey to User:

class MyModel(models.Model):
    foo = models.BooleanField()
    bar = models.ForeignKey(User)

I have a method in my tests that generates me an appropriately shaped User - generate_test_user()

I want to write some tests with Hypothesis to assert assorted properties about instances of my model.

My first implementation looked like this:

class MyTestCase(TestCase):

    @hypothesis.given(models(MyModel, bar=just(generate_test_user())))
    def test_my_model(self, mymodel):
        pass

However this fails because generate_test_user gets called at import time and thus tries to create a model before Django migrations etc. have run.

What's a good way to craft a strategy such that the right things get evaluated at the right times / delay evaluation of the just call / similar?

Kristian Glass
  • 37,325
  • 7
  • 45
  • 73

2 Answers2

1

Sounds like you need to draw the strategy interactively rather than specifying it in @given():

@given(data())
def test_my_model(self, data):
    mymodel = data.draw(models(MyModel, bar=just(generate_test_user())))
    # Run assertions on mymodel
solarissmoke
  • 30,039
  • 14
  • 71
  • 73
1

TL;DR I wanted builds not just

From hypothesis.strategies:

def just(value):
    """Return a strategy which only generates value.

    Note: value is not copied. Be wary of using mutable values.

    """

whereas (edited for brevity):

def builds(target, *args, **kwargs):
    """Generates values by drawing from ``args`` and ``kwargs`` and passing
    them to ``target`` in the appropriate argument position.

    e.g. ``builds(target, integers(), flag=booleans())`` would draw an
    integer ``i`` and a boolean ``b`` and call ``target(i, flag=b)``.

Thus my original

@hypothesis.given(models(MyModel, bar=just(generate_test_user())))
def test_my_model(self, mymodel):
    pass

became

@hypothesis.given(models(MyModel, bar=builds(generate_test_user)))
def test_my_model(self, mymodel):
    pass

and all was as I wanted, with generate_test_user called at exactly the right time, at each test run

Kristian Glass
  • 37,325
  • 7
  • 45
  • 73