Skip to content

Test data

When testing we will need data to test against. As a general rule, test data should be curated and considered.

Guidelines

  • Only generate as much test data as you need. This should be kept to a minimum, but still enough to adequately test your code. For example, you may wish to test an addition function. To do so, you could generate 50 objects and assert the sum of their values added together is correct. But two objects would do in this case - any more than that is overkill.

  • When including fixtures, test data should be clean and easy to read. IDs/PKs should be sequential unless there is reason for them not to be. Reviewers are tasked with reviewing large amounts of code - and when scanning test data sequential PKs indicate that the IDs are not relevant to the test (as should be the case) so they can be skipped over. Randomly-assigned PKs catch the eye, delay reviews and can lead to reviewers missing actual issues due to the added noise.

  • The same is true of strings. Names of objects should be simple and relevant to the object you're creating. It's fine to assert variable == 'keyword1' for example; it doesn't need to be fancier than that.

  • Be wary if converting data from a live database to test data. Consider how much of the data you actually need. Per the above, you will need to tidy up the data to normalise the PKs.

  • Don't include fields with Django defaults that are not relevant to your test - as above they are just added noise. Django will apply the default when the objects are generated.

  • Datetimes should only be as explicit as you need them to be. If datetimes are not relevant to your test but still required by a model, use the datetime 2001-01-01T00:00:00Z. As above, this helps the reviewer implicitly understand that the date isn't a meaningful part of the test.

  • When you need a common object for your tests (eg, a Referer or Pattern object), consider importing an existing test fixture (or adding to it) rather than generating a new model as part of your test.

  • If for some reason you need a lot of test objects rather than precise ones, consider generating them in a for loop in the setUp method of your test class. This will not normally be the case and likely indicates you are generating too much test data.

Naive datetimes

Django will convert naive datetimes to UTC when they are saved to the database. However, where possible you should use timezone-aware datetimes in your tests to avoid any confusion and silence any warnings.

Mocking

Mocking is a way to replace an object with an imitation of that object. This is useful when you want to test a object that relies on another object that is not relevant to the test. The Python standard library includes a unittest.mock module that provides a Mock class that can be used to mock functions and objects. You can find more information mocking in the Python documentation. Mocking is an extremely powerful tool, and we encourage you to read the documentation to learn more about it.