Search code examples
pythonpython-2.7cachingflaskflask-cache

make unittest to test the caching status of several routes


I am trying to write a unittest for a couple of routes. The data manipulation is fairly intensive and making the server CPU bound, and the retrieval of new data is fairly infrequent. As such, I used flask cache to @cache.memoize the more intensive routes.

Given this, there are two things I want to make test cases for.

  1. A route IS caching. Without this, it will take too long to manipulate the data.
  2. When I explicitly clear the cache, the data will reload from the static data. Without this, my data will become stale. I will clear the cache on every retrieval of new data.

the following is a code for my unit tests with some comments.

import unittest
from app import create_app
from app.charts.cache import cache

class ChartTests(unittest.TestCase):
  def setUp(self):
    self.app = create_app('TESTING')
    self.context = self.app.app_context()
    self.client = self.app.test_client()
    self.context.push()

  def tearDown(self):
    self.context.pop()

  def test_routes_cached(self):
    """ test that the routes are caching and uncaching correctly """
    r1 = self.client.get('/chart/upgrade/')
    r2 = self.client.get('/chart/upgrade/')
    r3 = self.client.get('/chart/upgrade/?start_date=201404')
    self.assertTrue( #R1 is not cached )
    self.assertTrue( #R2 is cached )
    self.assertFalse(r3.data == r2.data)
    update_data(app) # changes the csv. Also uses flask-cache's `clear_cache()` to purge
    r_new = self.client.get('/chart/upgrade')
    self.assertTrue( #R_NEW is not cached )
    self.assertTrue(r_new.data != r1.data)

My routes are fairly simple, and tend to follow the following pattern:

@charts.before_request():
def update_data():
  charts.data = CSVReader('my_csv')

@charts.route('/upgrade')
@cache.memoize()
def upgrade():
  # ... do little fiddles with some data
  return jsonify(my_new_data)

How can I make accurate assertions about the cached status of my routes within a unittest?


Solution

  • The simplest way is simply to use the get method of flask.ext.cache.Cache:

    def test_routes_cached(self):
        self.assertTrue(cache.get("/chart/upgrade/") is None)
        r1 = self.client.get("/chart/upgrade/")
        self.assertTrue(cache.get("/chart/upgrade/") is not None)
    
        # ... snip ...
    
        update_data(app)
    
        self.assertTrue(cache.get("/chart/upgrade/") is None)
        r_new = self.client.get("/chart/upgrade/")
        self.assertTrue(cache.get("/chart/upgrade/") is not None)
    
        # ... etc. ...