<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">To follow up on this issue --<div><br></div><div>I switched to using the wsgi server included in the cherrypy framework instead of the waitress wsgi server for my application. &nbsp;With this server I see coverage of the code from all my views when I run my test suite -- all of which are not marked as covered when I use the same test suite with the waitress wsgi server.</div><div><br></div><div>I'm guessing there is a difference in the way these two servers implement threading that causes this to occur …? &nbsp;I haven't delved into either server implementation but from my logs I see these thread names from cherrypy:</div><div><br></div><div>[CP Server Thread-6]</div><div><br></div><div>versus thread names of this variety from waitress:</div><div><br></div><div>[Dummy-3]</div><div><br></div><div>Its not entirely clear to me -- but I wonder if waitress perhaps spawns threads in response to requests rather than using a pre-initialized worker thread pool. &nbsp;Would that explain what I'm seeing if it was true?</div><div><br></div><div>I thought perhaps I was mistaken about what coverage should do in the case of a multi-threaded application -- so I conducted an experiment with the cherrypy server -- 2 requests were generated which were handled by two different worker threads, and then a third worker thread was responsible for generating the coverage report (via a call to the html_report method of the coverage api object). &nbsp;This produced the hoped for coverage report showing statement coverage along all the paths taken by each thread -- along the expected path for the view method calls.</div><div><br></div><div>So I'm left with a little bit of confidence in the observation that coverage appears to be working when I use the cherrypy wsgi server but not when I use the waitress server.</div><div><br></div><div>Many thanks for your help. &nbsp;Let me know if there's anything I can do to help clarify this or if you think it sounds like I'm doing something 'inherently wrong' which will be likely to bite me down the road …</div><div><br></div><div>Ben</div><div><br><div><div>On Aug 24, 2012, at 9:21 AM, Ben Cohen &lt;<a href="mailto:cohen.ben@gmail.com">cohen.ben@gmail.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><meta http-equiv="Content-Type" content="text/html charset=windows-1252"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Thanks for all the responses so far!<div><br></div><div>For completeness heres the project link for venusian decorators:</div><div><br></div><div><a href="http://pypi.python.org/pypi/venusian">http://pypi.python.org/pypi/venusian</a></div><div><br></div><div>Venusian style decorators add attributes to function/methods/classes including a callback which is invoked by a later 'scan' stage -- the pyramid framework uses this system to mark function/methods as web request handlers in a nice/flexible fashion. &nbsp;But Tres's links have convinced me that there's nothing inherently 'magic' about this process which would lead to coverage.py missing function/method calls.<br><div><br></div><div>I tried running coverage conventionally like so:</div><div><br></div><div>coverage run /path/to/my/pythonenv/bin/pserve development.ini</div><div><br></div><div>pserve is a script that's part of the pyramid web framework. &nbsp;The high level view of what it does is:</div><div><br></div><div>1. create the wsgi object representing a web application</div><div>2. setup a wsgi server&nbsp;</div><div>3. pass the application object to the server for serving. &nbsp;</div><div><br></div><div>After starting the server thusly, then invoking my test suite, I kill the serve process and run:</div><div><br></div><div>coverage html</div><div><br></div><div>to generate the html report. &nbsp;The report is essentially the same as the one generated by the api calls and shows that none of my application's view methods are being called...</div><div><br></div><div>I had mentioned earlier that I was using the single-threaded waitress http server -- however that's not true -- waitress is a multi-threaded server -- I'm using it in its default configuration. &nbsp;There's a little bit of magic with threads happening largely behind the scenes within the framework/http server -- my functions/methods will all be called in a thread from a thread worker pool -- would it be expected for coverage to fail to trace methods called in a thread other than the MainThread?</div><div><br></div><div><div><div>On Aug 24, 2012, at 7:48 AM, Tres Seaver &lt;<a href="mailto:tseaver@palladion.com">tseaver@palladion.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">-----BEGIN PGP SIGNED MESSAGE-----<br>Hash: SHA1<br><br>On 08/24/2012 10:35 AM, Tres Seaver wrote:<br><blockquote type="cite">On 08/23/2012 08:34 PM, Ben Cohen wrote:<br><br><blockquote type="cite">The most obvious shared feature of the functions/methods that<br>report no coverage is the use of a venusian callback method<br>decorator -- this decorator marks functions/methods with declarative<br>attributes, subsequently modules are scanned for methods with those<br>attributes and then ingested by the pyramid web framework's<br>web-publishing machinery.<br></blockquote><br><blockquote type="cite">Is there some magic happening within the pyramid framework that <br>causes coverage to fail to register when these methods are called?<br>Is anybody using coverage and pyramid together without issue …? &nbsp;I<br>didn't expect so fundamental an issue with the two as the pyramid <br>documentation has a chapter describing the use of coverage in unit <br>tests …<br></blockquote><br>Pyramid itself runs tests with the coverage package without issues<br>(run via 'setup.py nosetests --with-xunit --with-xcoverage' -- see the<br>'cover' environment in its tox.ini). &nbsp;We use it routinely for apps<br>built on Pyramid as well. &nbsp;The venusian decorator does not do anything<br>to interfere with coverage: &nbsp;the attributes it adds to the decorated <br>function are used to populate Pyramid's registry during the later<br>"scan" phase.<br></blockquote><br>Pyramid's Jenkins:<br><br> <a href="http://jenkins.pylonsproject.org/job/pyramid/">http://jenkins.pylonsproject.org/job/pyramid/</a><br><br>and the instance for SubstanceD, an app written on top of Pyramide:<br><br> <a href="http://jenkins.pylonsproject.org/job/substanced/">http://jenkins.pylonsproject.org/job/substanced/</a><br><br><br>Tres.<br>- -- <br>===================================================================<br>Tres Seaver &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+1 540-429-0999 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="mailto:tseaver@palladion.com">tseaver@palladion.com</a><br>Palladion Software &nbsp;&nbsp;"Excellence by Design" &nbsp;&nbsp;&nbsp;<a href="http://palladion.com/">http://palladion.com</a><br>-----BEGIN PGP SIGNATURE-----<br>Version: GnuPG v1.4.11 (GNU/Linux)<br>Comment: Using GnuPG with Mozilla - <a href="http://enigmail.mozdev.org/">http://enigmail.mozdev.org/</a><br><br>iEYEARECAAYFAlA3lB8ACgkQ+gerLs4ltQ4tmQCgx9jQjZPXJJlme1ZrNqm46rMb<br>KEIAn2SE/Cz43KS/f+61XVb6HcqtiHzK<br>=vlKO<br>-----END PGP SIGNATURE-----<br><br><br>_______________________________________________<br>testing-in-python mailing list<br><a href="mailto:testing-in-python@lists.idyll.org">testing-in-python@lists.idyll.org</a><br><a href="http://lists.idyll.org/listinfo/testing-in-python">http://lists.idyll.org/listinfo/testing-in-python</a><br></blockquote></div><br></div></div></div></blockquote></div><br></div></body></html>