231 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			231 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Python
		
	
	
	
| import py
 | |
| 
 | |
| class DefaultPlugin:
 | |
|     """ Plugin implementing defaults and general options. """ 
 | |
| 
 | |
|     def pytest_pyfunc_call(self, pyfuncitem, args, kwargs):
 | |
|         pyfuncitem.obj(*args, **kwargs)
 | |
|         return 
 | |
| 
 | |
|     def pytest_collect_file(self, path, parent):
 | |
|         ext = path.ext 
 | |
|         pb = path.purebasename
 | |
|         if pb.startswith("test_") or pb.endswith("_test") or \
 | |
|            path in parent.config.args:
 | |
|             if ext == ".py":
 | |
|                 return parent.Module(path, parent=parent) 
 | |
|       
 | |
|     def pytest_collect_directory(self, path, parent):
 | |
|         #excludelist = parent._config.getvalue_pathlist('dir_exclude', path)
 | |
|         #if excludelist and path in excludelist:
 | |
|         #    return 
 | |
|         if not parent.recfilter(path):
 | |
|             # check if cmdline specified this dir or a subdir directly
 | |
|             for arg in parent.config.args:
 | |
|                 if path == arg or arg.relto(path):
 | |
|                     break
 | |
|             else:
 | |
|                 return 
 | |
|         # not use parent.Directory here as we generally 
 | |
|         # want dir/conftest.py to be able to 
 | |
|         # define Directory(dir) already 
 | |
|         Directory = parent.config.getvalue('Directory', path) 
 | |
|         return Directory(path, parent=parent)
 | |
| 
 | |
|     def pytest_addoption(self, parser):
 | |
|         group = parser.addgroup("general", "test collection and failure interaction options")
 | |
|         group._addoption('-v', '--verbose', action="count", 
 | |
|                    dest="verbose", default=0, help="increase verbosity."),
 | |
|         group._addoption('-x', '--exitfirst',
 | |
|                    action="store_true", dest="exitfirst", default=False,
 | |
|                    help="exit instantly on first error or failed test."),
 | |
|         group._addoption('-k',
 | |
|             action="store", dest="keyword", default='',
 | |
|             help="only run test items matching the given "
 | |
|                  "space separated keywords.  precede a keyword with '-' to negate. "
 | |
|                  "Terminate the expression with ':' to treat a match as a signal "
 | |
|                  "to run all subsequent tests. ")
 | |
|         group._addoption('-l', '--showlocals',
 | |
|                    action="store_true", dest="showlocals", default=False,
 | |
|                    help="show locals in tracebacks (disabled by default).")
 | |
|         #group._addoption('--showskipsummary',
 | |
|         #           action="store_true", dest="showskipsummary", default=False,
 | |
|         #           help="always show summary of skipped tests") 
 | |
|         group._addoption('--pdb',
 | |
|                    action="store_true", dest="usepdb", default=False,
 | |
|                    help="start pdb (the Python debugger) on errors.")
 | |
|         group._addoption('--tb', metavar="style", 
 | |
|                    action="store", dest="tbstyle", default='long',
 | |
|                    type="choice", choices=['long', 'short', 'no'],
 | |
|                    help="traceback verboseness (long/short/no).")
 | |
|         group._addoption('-s', 
 | |
|                    action="store_true", dest="nocapture", default=False,
 | |
|                    help="disable catching of stdout/stderr during test run.")
 | |
|         group.addoption('--boxed',
 | |
|                    action="store_true", dest="boxed", default=False,
 | |
|                    help="box each test run in a separate process") 
 | |
|         group._addoption('-p', action="append", dest="plugin", default = [],
 | |
|                    help=("load the specified plugin after command line parsing. "
 | |
|                          "Example: '-p hello' will trigger 'import pytest_hello' "
 | |
|                          "and instantiate 'HelloPlugin' from the module."))
 | |
|         group._addoption('-f', '--looponfail',
 | |
|                    action="store_true", dest="looponfail", default=False,
 | |
|                    help="run tests, re-run failing test set until all pass.")
 | |
| 
 | |
|         group = parser.addgroup("test process debugging")
 | |
|         group.addoption('--collectonly',
 | |
|             action="store_true", dest="collectonly",
 | |
|             help="only collect tests, don't execute them."),
 | |
|         group.addoption('--traceconfig',
 | |
|                    action="store_true", dest="traceconfig", default=False,
 | |
|                    help="trace considerations of conftest.py files."),
 | |
|         group._addoption('--nomagic',
 | |
|                    action="store_true", dest="nomagic", default=False,
 | |
|                    help="don't reinterpret asserts, no traceback cutting. ")
 | |
|         group._addoption('--fulltrace',
 | |
|                    action="store_true", dest="fulltrace", default=False,
 | |
|                    help="don't cut any tracebacks (default is to cut).")
 | |
|         group.addoption('--basetemp', dest="basetemp", default=None, metavar="dir",
 | |
|                    help="base temporary directory for this test run.")
 | |
|         group._addoption('--iocapture', action="store", default="fd", metavar="method",
 | |
|                    type="choice", choices=['fd', 'sys', 'no'],
 | |
|                    help="set iocapturing method: fd|sys|no.")
 | |
|         group.addoption('--debug',
 | |
|                    action="store_true", dest="debug", default=False,
 | |
|                    help="generate and show debugging information.")
 | |
| 
 | |
|         group = parser.addgroup("dist", "distributed testing") #  see http://pytest.org/help/dist")
 | |
|         group._addoption('--dist', metavar="distmode", 
 | |
|                    action="store", choices=['load', 'each', 'no'], 
 | |
|                    type="choice", dest="dist", default="no", 
 | |
|                    help=("set mode for distributing tests to exec environments.\n\n"
 | |
|                          "each: send each test to each available environment.\n\n"
 | |
|                          "load: send each test to available environment.\n\n"
 | |
|                          "(default) no: run tests inprocess, don't distribute."))
 | |
|         group._addoption('--tx', dest="tx", action="append", default=[], metavar="xspec",
 | |
|                    help=("add a test execution environment. some examples: "
 | |
|                          "--tx popen//python=python2.5 --tx socket=192.168.1.102:8888 "
 | |
|                          "--tx ssh=user@codespeak.net//chdir=testcache"))
 | |
|         group._addoption('-d', 
 | |
|                    action="store_true", dest="distload", default=False,
 | |
|                    help="load-balance tests.  shortcut for '--dist=load'")
 | |
|         group._addoption('-n', dest="numprocesses", metavar="numprocesses", 
 | |
|                    action="store", type="int", 
 | |
|                    help="shortcut for '--dist=load --tx=NUM*popen'")
 | |
|         group.addoption('--rsyncdir', action="append", default=[], metavar="dir1", 
 | |
|                    help="add directory for rsyncing to remote tx nodes.")
 | |
| 
 | |
|     def pytest_configure(self, config):
 | |
|         self.fixoptions(config)
 | |
|         self.setsession(config)
 | |
|         self.loadplugins(config)
 | |
| 
 | |
|     def fixoptions(self, config):
 | |
|         if config.option.numprocesses:
 | |
|             config.option.dist = "load"
 | |
|             config.option.tx = ['popen'] * int(config.option.numprocesses)
 | |
|         if config.option.distload:
 | |
|             config.option.dist = "load"
 | |
|         if config.getvalue("usepdb"):
 | |
|             if config.getvalue("looponfail"):
 | |
|                 raise config.Error("--pdb incompatible with --looponfail.")
 | |
|             if config.option.dist != "no":
 | |
|                 raise config.Error("--pdb incomptaible with distributing tests.")
 | |
| 
 | |
|     def loadplugins(self, config):
 | |
|         for name in config.getvalue("plugin"):
 | |
|             print "importing", name
 | |
|             config.pytestplugins.import_plugin(name)
 | |
| 
 | |
|     def setsession(self, config):
 | |
|         val = config.getvalue
 | |
|         if val("collectonly"):
 | |
|             from py.__.test.session import Session
 | |
|             config.setsessionclass(Session)
 | |
|         else:
 | |
|             if val("looponfail"):
 | |
|                 from py.__.test.looponfail.remote import LooponfailingSession
 | |
|                 config.setsessionclass(LooponfailingSession)
 | |
|             elif val("dist") != "no":
 | |
|                 from py.__.test.dist.dsession import  DSession
 | |
|                 config.setsessionclass(DSession)
 | |
| 
 | |
|     def pytest_item_makereport(self, item, excinfo, when, outerr):
 | |
|         from py.__.test import event
 | |
|         return event.ItemTestReport(item, excinfo, when, outerr)
 | |
| 
 | |
| def test_implied_different_sessions(tmpdir):
 | |
|     def x(*args):
 | |
|         config = py.test.config._reparse([tmpdir] + list(args))
 | |
|         try:
 | |
|             config.pytestplugins.do_configure(config)
 | |
|         except ValueError:
 | |
|             return Exception
 | |
|         return getattr(config._sessionclass, '__name__', None)
 | |
|     assert x() == None
 | |
|     assert x('-d') == 'DSession'
 | |
|     assert x('--dist=each') == 'DSession'
 | |
|     assert x('-n3') == 'DSession'
 | |
|     assert x('-f') == 'LooponfailingSession'
 | |
| 
 | |
| def test_generic(plugintester):
 | |
|     plugintester.apicheck(DefaultPlugin)
 | |
|     
 | |
| def test_plugin_specify(testdir):
 | |
|     testdir.chdir()
 | |
|     config = testdir.parseconfig("-p", "nqweotexistent")
 | |
|     py.test.raises(ImportError, 
 | |
|         "config.pytestplugins.do_configure(config)"
 | |
|     )
 | |
| 
 | |
| def test_plugin_already_exists(testdir):
 | |
|     config = testdir.parseconfig("-p", "default")
 | |
|     assert config.option.plugin == ['default']
 | |
|     config.pytestplugins.do_configure(config)
 | |
| 
 | |
| 
 | |
| class TestDistOptions:
 | |
|     def test_getxspecs(self, testdir):
 | |
|         config = testdir.parseconfigure("--tx=popen", "--tx", "ssh=xyz")
 | |
|         xspecs = config.getxspecs()
 | |
|         assert len(xspecs) == 2
 | |
|         print xspecs
 | |
|         assert xspecs[0].popen 
 | |
|         assert xspecs[1].ssh == "xyz"
 | |
| 
 | |
|     def test_xspecs_multiplied(self, testdir):
 | |
|         xspecs = testdir.parseconfigure("--tx=3*popen",).getxspecs()
 | |
|         assert len(xspecs) == 3
 | |
|         assert xspecs[1].popen 
 | |
| 
 | |
|     def test_getrsyncdirs(self, testdir):
 | |
|         config = testdir.parseconfigure('--rsyncdir=' + str(testdir.tmpdir))
 | |
|         roots = config.getrsyncdirs()
 | |
|         assert len(roots) == 1 + 1 
 | |
|         assert testdir.tmpdir in roots
 | |
| 
 | |
|     def test_getrsyncdirs_with_conftest(self, testdir):
 | |
|         p = py.path.local()
 | |
|         for bn in 'x y z'.split():
 | |
|             p.mkdir(bn)
 | |
|         testdir.makeconftest("""
 | |
|             rsyncdirs= 'x', 
 | |
|         """)
 | |
|         config = testdir.parseconfigure(testdir.tmpdir, '--rsyncdir=y', '--rsyncdir=z')
 | |
|         roots = config.getrsyncdirs()
 | |
|         assert len(roots) == 3 + 1 
 | |
|         assert py.path.local('y') in roots 
 | |
|         assert py.path.local('z') in roots 
 | |
|         assert testdir.tmpdir.join('x') in roots 
 | |
| 
 | |
| def test_dist_options(testdir):
 | |
|     py.test.raises(Exception, "testdir.parseconfigure('--pdb', '--looponfail')")
 | |
|     py.test.raises(Exception, "testdir.parseconfigure('--pdb', '-n 3')")
 | |
|     py.test.raises(Exception, "testdir.parseconfigure('--pdb', '-d')")
 | |
|     config = testdir.parseconfigure("-n 2")
 | |
|     assert config.option.dist == "load"
 | |
|     assert config.option.tx == ['popen'] * 2
 | |
|     
 | |
|     config = testdir.parseconfigure("-d")
 | |
|     assert config.option.dist == "load"
 |