dimanche 27 septembre 2020

How to keep test instance IDs apart in Django?

There's a bug in the following code:

def test_should_filter_foobar_by_foo_id(self) -> None:
    first_foo = Foo(name="a")
    second_foo = Foo(name="b")

    first_foobar = FooBar(foo=first_foo)
    second_foobar = FooBar(foo=second_foo)

    results = FooBarFilter(data={"foo": first_foobar.id}

    self.assertListEqual([first_foobar], results.qs.order_by("id"))

The test passes for the wrong reason, because when starting from a newly initialized DB the Foo.id and FooBar.id sequences both start at 1. first_foobar.id should be first_foo.id. This is very similar to real-world tests I've written where the sequences running in lockstep has caused misleading test implementations.

Is there a (cheap, simple) way to do something similar to Django's reset_sequences to jolt all the sequences out of lockstep? Whether randomly or by adding 1 million to the first sequence, 2 million to the next etc., or some other method. A few suboptimal options come to mind:

  1. Create dummy instances at the start of the test to move the sequences out of lockstep.
    • Prohibitively expensive.
    • Error prone because we'd have to keep track of how many instances of each model we create.
    • Adds irrelevant complexity to the tests.
  2. Change the current values of each sequence as part of test setup.
    • Error prone because we'd have to make sure to change all the relevant sequences as we add more models to the tests.
    • Adds irrelevant complexity to the tests.
  3. Swap around the order in which we create the instances in the test, so that first_foo has ID 2 and second_foo has ID 1.
    • Adds irrelevant complexity to the tests.
    • Once we have three or more models in the test at least two of them will be in lockstep, and we'd need to complement this with some other technique.
  4. Modify the IDs of each instance after saving, thereby bypassing the sequences entirely.
    • Again, adds irrelevant complexity to the tests.
    • Error prone, since now it would be easy to accidentally end up with ID collisions.
  5. Change the current values of each sequence as part of the template DB. I'm not sure how to do this, and I'm not sure how expensive it would be.

Aucun commentaire:

Enregistrer un commentaire