django-test-profiling

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Django Test Profiling

Django 测试性能分析

Use this skill before changing a Django test suite for speed. Measurement decides which optimization is worth doing; otherwise it is easy to spend time on harmless settings while the real cost sits in startup, database setup, fixture construction, or a small set of slow tests.
在为了提速而修改 Django 测试套件之前,使用此 skill。测量结果决定哪些优化值得执行;否则很容易把时间花在无关紧要的设置上,而真正的成本却隐藏在启动、数据库设置、fixture 构建或一小批缓慢测试中。

Measurement Workflow

测量工作流

  1. Capture a full wall-clock baseline.
    • Prefer shell timing because it includes Python startup, Django import time, test discovery, database setup, and teardown.
    • Record the exact command, environment, and repeat count.
  2. Separate framework phases when possible.
    • For Django's runner, use
      --timing
      to see database setup and teardown.
    • For pytest, compare shell timing with
      pytest --durations
      .
  3. Find the slowest tests.
    • For pytest-django, start with
      pytest --durations 20
      .
    • For Django's runner, use an existing slow-test plugin or a small custom runner only when the project does not already have one.
  4. Profile only after you know where the time goes.
    • Use
      py-spy
      first for a low-overhead whole-run view.
    • Use
      cProfile
      when you need exhaustive Python call data.
  5. Convert the result into a ranked action list.
    • Identify whether the expensive part is startup, database creation, repeated setup, test data, query count, I/O, cache/file/storage access, or a specific test body.
    • Hand off to
      django-test-performance
      ,
      django-test-data
      , or
      django-test-parallelization
      when the next step fits those skills.
  1. 捕获完整的挂钟时间基线。
    • 最好使用 shell timing,因为它包括 Python 启动、Django 导入时间、测试发现、数据库设置和清理。
    • 记录准确的命令、环境和重复执行次数。
  2. 尽可能区分各个框架阶段。
    • 对于 Django 的 runner,使用
      --timing
      查看数据库设置和清理耗时。
    • 对于 pytest,将 shell timing 与
      pytest --durations
      进行比较。
  3. 找出最慢的测试。
    • 对于 pytest-django,先使用
      pytest --durations 20
      。
    • 对于 Django 的 runner,仅当项目中尚未使用现有慢测试插件或小型自定义 runner 时,才考虑添加。
  4. 只有在明确耗时位置后再进行性能分析。
    • 首先使用
      py-spy
      获取低开销的整体运行视图。
    • 需要详尽的 Python 调用数据时,使用
      cProfile
      。
  5. 将结果转换为按优先级排序的行动列表。
    • 确定耗时较高的部分是启动、数据库创建、重复设置、测试数据、查询次数、I/O、缓存/文件/存储访问,还是某个具体的测试主体。
    • 如果下一步符合
      django-test-performance
      、
      django-test-data
      或
      django-test-parallelization
      这些 skill 的适用范围,则转交给相应的 skill 处理。

Commands

命令

bash
time python manage.py test
python manage.py test --timing
pytest --durations 20
For profiling command variants and interpretation guidance, read profiler-commands.md.
bash
time python manage.py test
python manage.py test --timing
pytest --durations 20
有关性能分析命令的变体和结果解读指南,请阅读 profiler-commands.md。

Decision Rules

决策规则

  • Treat shell timing as the authoritative user-visible duration.
  • Use Django
    --timing
    when database setup or teardown may dominate.
  • Optimize the slowest measured tests first, not the tests that look suspicious.
  • Put noisy duration reports in CI logs when they distract from normal local runs.
  • Use
    py-spy --subprocesses
    when the test runner uses child processes.
  • Sort cProfile by cumulative time first; inspect self-time only after you understand the caller chain.
  • 将 shell timing 视为用户可感知耗时的权威依据。
  • 当数据库设置或清理可能占据主要耗时时,使用 Django 的
    --timing
    。
  • 优先优化实测最慢的测试,而不是仅凭主观判断看起来有问题的测试。
  • 当耗时报告干扰本地正常运行时,将其放入 CI 日志。
  • 当测试运行器使用子进程时,使用
    py-spy --subprocesses
    。
  • 首先按累计时间对 cProfile 结果排序;理解调用链后再检查 self-time。

Common Mistakes

常见错误

  • Trusting a framework's final "ran in X seconds" line as the complete runtime.
  • Comparing Django runner timing and pytest timing as if they measure identical phases.
  • Profiling everything before finding slow tests.
  • Reading unsorted cProfile output and chasing import internals.
  • Expecting sampling profiles to catch every short hot path.
  • Optimizing a helper without checking how often it is reached by tests.
  • 将框架最终输出的“耗时 X 秒”视为完整运行时间。
  • 直接比较 Django runner 计时与 pytest 计时,却不区分两者测量的阶段。
  • 在找出慢测试之前对所有内容进行性能分析。
  • 阅读未经排序的 cProfile 输出,并盲目追踪导入过程的内部实现。
  • 期望采样分析能够捕获每一条短暂的热点路径。
  • 未检查测试调用辅助函数的频率,就直接对其进行优化。

Verification

验证

Before reporting findings, include:
  • The exact baseline command and measured wall-clock time.
  • The slowest tests or slowest phases.
  • The profiler used, if any, and why it was appropriate.
  • The top 3 practical next actions, ordered by expected impact.
报告分析结果前,应包括:
  • 准确的基线命令和实测挂钟时间。
  • 最慢的测试或阶段。
  • 使用的性能分析器(如果有),以及选择它的原因。
  • 按预期影响排序的前 3 项后续实际行动。