Package: django-test-query-counter
A Django Toolkit for controlling Query count when testing. It controls the
number of queries done in the tests stays below a particular threshold between
Test Runs.Specially useful when paired with a CI like Jenkins or Travis to
control each commit doesn’t slow down the Database considerably.RequirementsPython 3DjangoDocumentationThe full documentation is athttps://django-test-query-counter.readthedocs.io.InstallationThere are ways to install it into your projectClone this repository into your project:gitclonehttps://github.com/sophilabs/django-test-query-counter.gitDownload the zip file and unpack it:wgethttps://github.com/sophilabs/django-test-query-counter/archive/master.zipunzipmaster.zipInstall with pip:pipinstalldjango-test-query-counterAdd it to yourINSTALLED_APPS:INSTALLED_APPS=(...'test_query_count',...)UsageRun your django tests as you do. After the run thereportsdirectory with two filesquery_count.jsonandquery_count_detail.json.To check your tests Query Counts run:$ python manage.py check_query_countThen you would see an output like the following one (if you at least ran the
tests twice):All Tests API Queries are below the allowed threshold.If the current test run had more queries than the last one, it will tell you:There are test cases with API calls that exceeded threshold:

    In test case app.organizations.tests.api.test_division_api.DivisionViewTest.test_bulk_create_division, POST /api/divisions. Expected at most 11 queries but got 15 queries
    In test case app.shipments.tests.api.test_leg_api.LegViewTest.test_create_bulk_leg, POST /api/legs. Expected at most 59 queries but got 62 queries
    In test case app.plans.tests.functional.test_plan_api.PlannedDatesTest.test_unassign_and_assign_driver_to_leg, POST /api/assignments/assign-driver. Expected at most 261 queries but got 402 queries
CommandError: There was at least one test with an API call excedding the allowed threshold.ConfigurationYou can customize how the Test Query Count works by definingTEST_QUERY_COUNTERin your settings file as a dictionary. The following code shows an exampleTEST_QUERY_COUNTER={# Global switch'ENABLE':True,# Paths where the count files are generated (relative to the current# process dir)'DETAIL_PATH':'reports/query_count_detail.json','SUMMARY_PATH':'reports/query_count.json',# Tolerated percentage of count increase on successive# test runs.A value of 0 prevents increasing queries altoghether.'INCREASE_THRESHOLD':10}Excluding TestsIndividual tests or classes can be excluded for the count using the@exclude_query_countdecorator. For example# To exclude all methods in the class@exclude_query_count()classAllTestExcluded(TestCase):deftest_foo(self):self.client.get('path-1')deftest_foo(self):self.client.get('path-2')# To exclude one test onlyclassOneMethodExcluded():deftest_foo(self):self.client.get('path-1')@exclude_query_count()deftest_foo(self):self.client.get('path-2')More specifically,exclude_query_countaccept parameters to conditionally
exclude a query count by path, method or count. Wherepaththe or regex of
the excluded path(s). Themethodspecifies the regex of the method(s) to
exclude, andcountis minimum number of queries tolerated. Requests with
less or same amount as “count” will be excluded.For example:classTest(TestCase):@exclude_query_count(path='url-2')deftest_exclude_path(self):self.client.get('/url-1')self.client.post('/url-2')@exclude_query_count(method='post')deftest_exclude_method(self):self.client.get('/url-1')self.client.post('/url-2')@exclude_query_count(count=2)deftest_exclude_count(self):#  succesive urls requests are additiveforiinrange(3):self.client.get('/url-1')Implementing into your CICurrently the query count works locally. However, it shines when it is
integrated withJenkins, or other CIs. You have to do
this manually:RequirementsJenkins with a Job that build you project.From now on let’s suppose your job is available athttp://127.0.0.1:8080/job/ZAP_EXAMPLE_JOB/.Activate Build Archive: Go to the jobconfiguration pageand add thearchive artifactsbuild
Post-build actions.Setreports/query_count.jsonin the files to archive pathCreate a new Django custom Command to run the validation against the
archived Jenkins file. For example:fromurllib.requestimporturlretrievefromdjango.core.managementimportBaseCommand,CommandErrorfromdjango.confimportsettingsfromtest_query_counter.appsimportRequestQueryCountConfigfromtest_query_counter.query_countimportQueryCountEvaluatorclassCommand(BaseCommand):JENKINS_QUERY_COUNT='https://yourci/job/'\'yourproject/lastSuccessfulBuild/'\'artifact/app/reports/query_count.json'defhandle(self,*args,**options):current_file_path=RequestQueryCountConfig.get_setting('SUMMARY_FILE')withopen(current_file_path)ascurrent_file,\open(urlretrieve(self.JENKINS_QUERY_COUNT)[0])aslast_file:violations=QueryCountEvaluator(10,current_file,last_file).run()ifviolations:raiseCommandError('There was at least one test with an API ''call excedding the allowed threshold.')Add a build step to run this command:After that, it will run fine, and the build would fail if any Query count is over the limit.TODOInclude support for stacktraces inquery_count_detail.json.Generate an HTML report of executed Queries.Make query count configurableInclude Jenkins support out of the box (usingdjango_jenkins)Running TestsDoes the code actually work?source<YOURVIRTUALENV>/bin/activate(myenv)$pipinstalltox(myenv)$toxLicensePySchool is MIT Licensed. Copyright (c) 2017 Sophilabs, Inc.CreditsThis tool is maintained and funded by Sophilabs, Inc. The names and logos for
sophilabs are trademarks of sophilabs, inc.Tools used in rendering this package:Cookiecuttercookiecutter-djangopackageHistory0.1.0 (2017-07-10)First release on PyPI.