howitworks.rst 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. .. Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
  2. .. For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt
  3. .. _howitworks:
  4. =====================
  5. How Coverage.py works
  6. =====================
  7. .. :history: 20150812T071000, new page.
  8. For advanced use of coverage.py, or just because you are curious, it helps to
  9. understand what's happening behind the scenes. Coverage.py works in three
  10. phases:
  11. * **Execution**: Coverage.py runs your code, and monitors it to see what lines
  12. were executed.
  13. * **Analysis**: Coverage.py examines your code to determine what lines could
  14. have run.
  15. * **Reporting**: Coverage.py combines the results of execution and analysis to
  16. produce a coverage number and an indication of missing execution.
  17. The execution phase is handled by the ``coverage run`` command. The analysis
  18. and reporting phases are handled by the reporting commands like ``coverage
  19. report`` or ``coverage html``.
  20. Let's look at each phase in more detail.
  21. Execution
  22. ---------
  23. At the heart of the execution phase is a Python trace function. This is a
  24. function that the Python interpreter invokes for each line executed in a program.
  25. Coverage.py implements a trace function that records each file and line number
  26. as it is executed.
  27. Executing a function for every line in your program can make execution very
  28. slow. Coverage.py's trace function is implemented in C to reduce that
  29. slowdown. It also takes care to not trace code that you aren't interested in.
  30. When measuring branch coverage, the same trace function is used, but instead of
  31. recording line numbers, coverage.py records pairs of line numbers. Each
  32. invocation of the trace function remembers the line number, then the next
  33. invocation records the pair `(prev, this)` to indicate that execution
  34. transitioned from the previous line to this line. Internally, these are called
  35. arcs.
  36. For more details of trace functions, see the Python docs for `sys.settrace`_,
  37. or if you are really brave, `How C trace functions really work`_.
  38. At the end of execution, coverage.py writes the data it collected to a data
  39. file, usually named ``.coverage``. This is a JSON-based file containing all of
  40. the recorded file names and line numbers executed.
  41. .. _sys.settrace: https://docs.python.org/3/library/sys.html#sys.settrace
  42. .. _How C trace functions really work: http://nedbatchelder.com/text/trace-function.html
  43. Analysis
  44. --------
  45. After your program has been executed and the line numbers recorded, coverage.py
  46. needs to determine what lines could have been executed. Luckily, compiled
  47. Python files (.pyc files) have a table of line numbers in them. Coverage.py
  48. reads this table to get the set of executable lines, with a little more source
  49. analysis to leave out things like docstrings.
  50. The data file is read to get the set of lines that were executed. The
  51. difference between the executable lines, and the executed lines, are the lines
  52. that were not executed.
  53. The same principle applies for branch measurement, though the process for
  54. determining possible branches is more involved. Coverage.py uses the abstract
  55. syntax tree of the Python source file to determine the set of possible
  56. branches.
  57. Reporting
  58. ---------
  59. Once we have the set of executed lines and missing lines, reporting is just a
  60. matter of formatting that information in a useful way. Each reporting method
  61. (text, html, annotated source, xml) has a different output format, but the
  62. process is the same: write out the information in the particular format,
  63. possibly including the source code itself.
  64. Plugins
  65. -------
  66. Plugins interact with these phases.