OLD | NEW |
(Empty) | |
| 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 |
| 4 .. _subprocess: |
| 5 |
| 6 ======================= |
| 7 Measuring sub-processes |
| 8 ======================= |
| 9 |
| 10 .. :history: 20100224T201800, new for 3.3. |
| 11 .. :history: 20100725T211700, updated for 3.4. |
| 12 |
| 13 |
| 14 Complex test suites may spawn sub-processes to run tests, either to run them in |
| 15 parallel, or because sub-process behavior is an important part of the system |
| 16 under test. Measuring coverage in those sub-processes can be tricky because you |
| 17 have to modify the code spawning the process to invoke coverage.py. |
| 18 |
| 19 There's an easier way to do it: coverage.py includes a function, |
| 20 :func:`coverage.process_startup` designed to be invoked when Python starts. It |
| 21 examines the ``COVERAGE_PROCESS_START`` environment variable, and if it is set, |
| 22 begins coverage measurement. The environment variable's value will be used as |
| 23 the name of the :ref:`configuration file <config>` to use. |
| 24 |
| 25 When using this technique, be sure to set the parallel option to true so that |
| 26 multiple coverage.py runs will each write their data to a distinct file. |
| 27 |
| 28 |
| 29 Configuring Python for sub-process coverage |
| 30 ------------------------------------------- |
| 31 |
| 32 Measuring coverage in sub-processes is a little tricky. When you spawn a |
| 33 sub-process, you are invoking Python to run your program. Usually, to get |
| 34 coverage measurement, you have to use coverage.py to run your program. Your |
| 35 sub-process won't be using coverage.py, so we have to convince Python to use |
| 36 coverage.py even when not explicitly invoked. |
| 37 |
| 38 To do that, we'll configure Python to run a little coverage.py code when it |
| 39 starts. That code will look for an environment variable that tells it to start |
| 40 coverage measurement at the start of the process. |
| 41 |
| 42 To arrange all this, you have to do two things: set a value for the |
| 43 ``COVERAGE_PROCESS_START`` environment variable, and then configure Python to |
| 44 invoke :func:`coverage.process_startup` when Python processes start. |
| 45 |
| 46 How you set ``COVERAGE_PROCESS_START`` depends on the details of how you create |
| 47 sub-processes. As long as the environment variable is visible in your |
| 48 sub-process, it will work. |
| 49 |
| 50 You can configure your Python installation to invoke the ``process_startup`` |
| 51 function in two ways: |
| 52 |
| 53 #. Create or append to sitecustomize.py to add these lines:: |
| 54 |
| 55 import coverage |
| 56 coverage.process_startup() |
| 57 |
| 58 #. Create a .pth file in your Python installation containing:: |
| 59 |
| 60 import coverage; coverage.process_startup() |
| 61 |
| 62 The sitecustomize.py technique is cleaner, but may involve modifying an |
| 63 existing sitecustomize.py, since there can be only one. If there is no |
| 64 sitecustomize.py already, you can create it in any directory on the Python |
| 65 path. |
| 66 |
| 67 The .pth technique seems like a hack, but works, and is documented behavior. |
| 68 On the plus side, you can create the file with any name you like so you don't |
| 69 have to coordinate with other .pth files. On the minus side, you have to |
| 70 create the file in a system-defined directory, so you may need privileges to |
| 71 write it. |
| 72 |
| 73 Note that if you use one of these techniques, you must undo them if you |
| 74 uninstall coverage.py, since you will be trying to import it during Python |
| 75 start-up. Be sure to remove the change when you uninstall coverage.py, or use |
| 76 a more defensive approach to importing it. |
| 77 |
| 78 |
| 79 Signal handlers and atexit |
| 80 -------------------------- |
| 81 |
| 82 .. hmm, this isn't specifically about subprocesses, is there a better place |
| 83 where we could talk about this? |
| 84 |
| 85 To successfully write a coverage data file, the Python sub-process under |
| 86 analysis must shut down cleanly and have a chance for coverage.py to run the |
| 87 ``atexit`` handler it registers. |
| 88 |
| 89 For example if you send SIGTERM to end the sub-process, but your sub-process |
| 90 has never registered any SIGTERM handler, then a coverage file won't be |
| 91 written. See the `atexit`_ docs for details of when the handler isn't run. |
| 92 |
| 93 .. _atexit: https://docs.python.org/2/library/atexit.html |
OLD | NEW |