4

I am trying to test the number of DB queries executed by an API in my Django application. So, I have a test case similar to the following:

class DatabaseQueriesTestCase(TestCase):
    scan_uri = "something"

    def test_API_1(self):
        payload = {
                    'id': 12,
                    'name': "ABCD"
                  }
        self.assertNumQueries(13, self.client.post, self.scan_uri, data=payload)

On running the test multiple times, some pass while others fail. Some fail, saying one more query was run. Why is this happening? Is this a problem with assertNumQueries ??

Note: Using Redis cache in my application..

User_Targaryen
  • 4,125
  • 4
  • 30
  • 51
  • Are you using caching, e.g. memcache? – Daniel Hepper Oct 20 '16 at 06:52
  • @DanielHepper: I am using some kind of caching but how does that point out the problem? Sometimes 13 queries are run and sometimes 14 queries are run.. The database gets destroyed and created again before running a Test. – User_Targaryen Oct 20 '16 at 06:57
  • Because something might be stored in the cache in the first test run and read from the cache in the second run. The cache is not cleared in between test runs. See https://docs.djangoproject.com/en/1.10/topics/testing/overview/#other-test-conditions – Daniel Hepper Oct 20 '16 at 06:58
  • The problem is still happening when I run only `test_API_1` instead of all the tests in `DatabaseQueriesTestCase` – User_Targaryen Oct 20 '16 at 07:01
  • Try `CACHES={}` in your settings file and see if that solves the problem. – Daniel Hepper Oct 20 '16 at 07:16

2 Answers2

2

I cleared my cache in setUp():

def setUp(self):
    # cleared cache
    # in my case: self.redis_conn.flushdb()

This solved the problem. You can find a helpful discussion about such a problem associated with assertNumQueries here

Many thanks to @Daniel Hepper for helping me out!!!

User_Targaryen
  • 4,125
  • 4
  • 30
  • 51
2

For relational database issues you need to clear the query caches first:

class DatabaseQueriesTestCase(TestCase):
    scan_uri = "something"

    def clear_query_caches(self):
        """
        Resets all caches that may prevent query execution.
        Needed to ensure deterministic behavior of ``assertNumQueries`` (or
        after external changes to some Django database records).
        """
        from django.contrib.contenttypes.models import ContentType
        from django.contrib.sites.models import Site
        ContentType.objects.clear_cache()
        Site.objects.clear_cache()

    def setUp():
        self.clear_query_caches()

    def test_API_1(self):
        payload = {
                    'id': 12,
                    'name': "ABCD"
                  }
        self.assertNumQueries(13, self.client.post, self.scan_uri, data=payload)

https://code.djangoproject.com/ticket/23746

Julio Marins
  • 10,039
  • 8
  • 48
  • 54