[Zope3-checkins] SVN: zope.testing/trunk/src/zope/testing/ add
profiling support with test
Benji York
benji at zope.com
Wed Aug 24 13:32:25 EDT 2005
Log message for revision 38071:
add profiling support with test
(because of bug in 2.4.1 and earlier, only works when Python is run with -O)
Changed:
A zope.testing/trunk/src/zope/testing/profiling.txt
U zope.testing/trunk/src/zope/testing/testrunner.py
-=-
Added: zope.testing/trunk/src/zope/testing/profiling.txt
===================================================================
--- zope.testing/trunk/src/zope/testing/profiling.txt 2005-08-24 16:39:42 UTC (rev 38070)
+++ zope.testing/trunk/src/zope/testing/profiling.txt 2005-08-24 17:32:25 UTC (rev 38071)
@@ -0,0 +1,34 @@
+Profiling
+=========
+
+The testrunner includes the ability to profile the test execution with hotshot
+via the --profile option.
+
+ >>> import os.path, sys
+ >>> directory_with_tests = os.path.join(this_directory, 'testrunner-ex')
+ >>> sys.path.append(directory_with_tests)
+
+ >>> defaults = [
+ ... '--path', directory_with_tests,
+ ... '--tests-pattern', '^sampletestsf?$',
+ ... ]
+
+ >>> sys.argv = 'test --profile'.split()
+
+When the tests are run, we get profiling output.
+
+ >>> from zope.testing import testrunner
+ >>> testrunner.run(defaults)
+ Running unit tests:
+ ...
+ Running samplelayers.Layer1 tests:
+ ...
+ Running samplelayers.Layer11 tests:
+ ...
+ Total: ... tests, 0 failures, 0 errors
+ ...
+ Ordered by: cumulative time, call count
+ List reduced from ... to 50 due to restriction <50>
+ <BLANKLINE>
+ ncalls tottime percall cumtime percall filename:lineno(function)
+ ...
Property changes on: zope.testing/trunk/src/zope/testing/profiling.txt
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: zope.testing/trunk/src/zope/testing/testrunner.py
===================================================================
--- zope.testing/trunk/src/zope/testing/testrunner.py 2005-08-24 16:39:42 UTC (rev 38070)
+++ zope.testing/trunk/src/zope/testing/testrunner.py 2005-08-24 17:32:25 UTC (rev 38071)
@@ -20,17 +20,21 @@
# we want to use the latest, greatest doctest, which zope.testing
# provides. Then again, zope.testing is generally useful.
import gc
+import glob
import logging
import optparse
import os
import pdb
import re
import sys
+import tempfile
+import threading
import time
+import trace
import traceback
-import threading
import unittest
-import trace
+import hotshot
+import hotshot.stats
real_pdb_set_trace = pdb.set_trace
@@ -101,6 +105,12 @@
# to make tests of the test runner work properly. :)
pdb.set_trace = real_pdb_set_trace
+ if options.profile and sys.version_info[:3] <= (2,4,1) and __debug__:
+ print ('Because of a bug in Python < 2.4.1, profiling '
+ 'during tests requires the -O option be passed to '
+ 'Python (not the test runner).')
+ sys.exit()
+
if options.coverage:
tracer = MyTrace(ignoredirs=[sys.prefix, sys.exec_prefix],
ignoremods=["os", "posixpath", "stat"],
@@ -110,14 +120,41 @@
tracer = None
try:
+ if options.profile:
+ prof_prefix = 'tests_profile'
+ prof_suffix = '.prof'
+ prof_glob = prof_prefix + '*' + prof_suffix
+ dummy, file_path = tempfile.mkstemp(prof_suffix, prof_prefix, '.')
+ prof = hotshot.Profile(file_path)
+ prof.start()
+
try:
- failed = run_with_options(options)
- except EndRun:
- failed = True
+ try:
+ failed = run_with_options(options)
+ except EndRun:
+ failed = True
+ finally:
+ if tracer:
+ tracer.stop()
+ if options.profile:
+ prof.stop()
+ prof.close()
+
+ if options.profile:
+ stats = None
+ for file_name in glob.glob(prof_glob):
+ loaded = hotshot.stats.load(file_name)
+ if stats is None:
+ stats = loaded
+ else:
+ stats.add(loaded)
+ stats.sort_stats('cumulative', 'calls')
+ stats.print_stats(50)
finally:
- if tracer:
- tracer.stop()
-
+ if options.profile:
+ for file_name in glob.glob(prof_glob):
+ os.unlink(file_name)
+
if tracer:
coverdir = os.path.join(os.getcwd(), options.coverage)
r = tracer.results()
@@ -996,13 +1033,20 @@
""")
analysis.add_option(
- '--coverage', action="store", dest='coverage',
+ '--coverage', action="store", type='string', dest='coverage',
help="""\
Perform code-coverage analysis, saving trace data to the directory
with the given name. A code coverage summary is printed to standard
out.
""")
+analysis.add_option(
+ '--profile', action="store_true", dest='profile',
+ help="""\
+Run the tests under hotshot and display the top 50 stats, sorted by
+cumulative time and number of calls.
+""")
+
def do_pychecker(*args):
if not os.environ.get("PYCHECKER"):
os.environ["PYCHECKER"] = "-q"
@@ -1223,12 +1267,21 @@
def tearDown(test):
sys.path, sys.argv = test.globs['saved-sys-info']
- return doctest.DocFileSuite('testrunner.txt', 'testrunner-edge-cases.txt',
- setUp=setUp, tearDown=tearDown,
- optionflags=doctest.ELLIPSIS
- +doctest.NORMALIZE_WHITESPACE,
- checker=checker, )
+ suite = doctest.DocFileSuite(
+ 'testrunner.txt', 'testrunner-edge-cases.txt',
+ setUp=setUp, tearDown=tearDown,
+ optionflags=doctest.ELLIPSIS+doctest.NORMALIZE_WHITESPACE,
+ checker=checker)
+ if not __debug__:
+ suite = unittest.TestSuite([suite, doctest.DocFileSuite(
+ 'profiling.txt',
+ setUp=setUp, tearDown=tearDown,
+ optionflags=doctest.ELLIPSIS+doctest.NORMALIZE_WHITESPACE,
+ checker=checker)])
+
+ return suite
+
def main():
default = [
'--path', os.path.split(sys.argv[0])[0],
More information about the Zope3-Checkins
mailing list