未加星标

Introducing django-perf-rec, our Django performance testing tool

字体大小 | |
[开发(python) 所属分类 开发(python) | 发布者 店小二03 | 时间 2016 | 作者 红领巾 ] 0人收藏点击收藏

Introducing django-perf-rec, our Django performance testing tool

N.B. This is a cross-post from the YPlan tech blog .

During PyCon UK I had the opportunity to work on open-sourcing our in-house Django performance testing tool, which has now been released as django-perf-rec . We created it over two years ago, and have been using and improving it since. It has been helping us to pre-emptively fix performance problems in our code, and now it can help you!

In the old days we used to often see performance regressions when we introduced a new feature to existing code, and we’d have to retroactively understand and fix them. For example, we might add a feature that accesses a new foreign key on a model, and because select_related / prefetch_related hadn’t been added to the appropriate QuerySet , we’d see an N+1 query problem appear. Often the problems would only manifest in real slowness in production, as our test and development environments don’t contain much data.

We tried to lock these down with Django’s assertNumQueries ( docs ) in tests like:

def test_books(self): with self.assertNumQueries(4): self.client.get('/books/')

This worked on a basic level, but if the test failed on you, you’d be left with little information on what caused the failure, and be forced to manually trace the code path, thinking along the way about where the change came from.

Failures happened often enough for us that we started adding comments by assertNumQueries to track roughly what the expected queries were, to make retracing easier:

def test_books(self): with self.assertNumQueries(4): # - Get User # - Get Books # - Prefetch Authors # - Update Stats counters self.client.get('/books/')

Suffice to say this wasn’t fun. If a query was added or removed, you’d have to manually edit all the comments. Also they could still ‘rot’ and become inaccurate - if one query was removed whilst another was added elsewhere, the test would continue to pass but the comments would be out of sync, making debugging at the next failure harder.

We had the insight was that the comments actually contained data, and this data could be grabbed and written down by a tool automatically…

From this idea, django-perf-rec was born. When active it intercepts all database queries (and also cache operations!), and writes them out to a YAML file that lives next to the test. Then when the test runs again, it compares the newly captured data to the record in the file, and fails if there are any differences. Thus the above test can now be written as:

import django_perf_rec # ... def test_books(self): with django_perf_rec.record(): self.client.get('/books/')

It also deals with variable data changing in your SQL and cache keys by fingerprinting it. For example the YAML for the above test might look like the following - note the SQL parameters have been replaced with # , and the column lists with ... :

MyTests.test_books: - cache|get: session.# - db: 'SELECT ... FROM myapp_users WHERE (myapp_users.id = #)' - db: 'SELECT ... FROM myapp_books ORDER BY # LIMIT #' - db: 'SELECT ... FROM myapp_authors WHERE (myapp_authors.id IN #)' - db: 'UPDATE myapp_stats SET # WHERE #'

When a failure happens, you get the exact comparison between the old and new lists, making it easy to understand why a change has happened. (We’re using pytest which gives us nice output - PR’s accepted for improving the output on other test runners!). If the changes are acceptable you can just delete the YAML file and rerun the test to check them in as part of the diff. If not, you have a lot more information to use in finding the problematic code.

It works with parallel test running (we use pytest-xdist ), so the YAML files don’t get corrupted whilst multiple processes write to them. Plus it also comes with a TestCase mixin so you don’t have to import it in every file you want to use it in!

Check it out today at https://github.com/YPlan/django-perf-rec and if you need an improvement please open an issue, or better yet, a pull request!

Tags:django

本文开发(python)相关术语:python基础教程 python多线程 web开发工程师 软件开发工程师 软件开发流程

主题: DjangoSQL
分页:12
转载请注明
本文标题:Introducing django-perf-rec, our Django performance testing tool
本站链接:http://www.codesec.net/view/480880.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 开发(python) | 评论(0) | 阅读(33)