import os
import sys

from optparse import OptionParser


class NoseTestFinder(object):
    def _generate_tests(self, suite):
        from nose.suite import ContextSuite
        from nose.case import Test
        for context in suite._tests:
            if isinstance(context, Test):
                yield context
                continue
            assert isinstance(context, ContextSuite)
            for test in self._generate_tests(context):
                yield test

    def _get_test_name(self, test_wrapper):
        from nose.case import FunctionTestCase
        test = test_wrapper.test
        if isinstance(test, FunctionTestCase):
            return test.test.__name__
        return test.__class__.__name__ + '.' + test._testMethodName

    def _generate_test_names(self, suite):
        from itertools import imap
        return imap(self._get_test_name, self._generate_tests(suite))

    def get_module_tests(self, module):
        import nose
        loader = nose.loader.defaultTestLoader()
        return self._generate_test_names(loader.loadTestsFromName(module))


def _get_prefixed(strings, prefix):
    for string in strings:
        if string.startswith(prefix):
            yield string.replace(prefix, '', 1)


def _get_py_or_dirs(directory, prefix):
    for entry in os.listdir(directory or '.'):
        path = os.path.join(directory, entry)
        if entry.startswith(prefix):
            leftover = entry.replace(prefix, '', 1)
            if os.path.isdir(path):
                yield leftover + '/'
            elif leftover.endswith('.py'):
                yield leftover + ':'


def _complete(thing):
    finder = NoseTestFinder()
    if ':' in thing:
        # complete a test
        module, test_part = thing.split(':')
        tests = list(finder.get_module_tests(module))
        if '.' in test_part:
            # complete a method
            return _get_prefixed(strings=tests, prefix=test_part)
        funcs = [test for test in tests if test.count('.') == 0]
        classes = [test.split('.')[0] for test in tests if '.' in test]
        if test_part in classes:
            # indicate a method should be completed
            return ['.']
        return _get_prefixed(strings=funcs + classes, prefix=test_part)
    if os.path.isdir(thing):
        # complete directory contents
        if thing != '.' and not thing.endswith('/'):
            return ['/']
        return _get_py_or_dirs(thing, '')
    if os.path.exists(thing):
        # add a colon to indicate search for specific class/func
        return [':']
    # path not exists, complete a partial path
    directory, file_part = os.path.split(thing)
    return _get_py_or_dirs(directory, file_part)


def complete(thing):
    for option in _complete(thing):
        sys.stdout.write(thing + option + ' ')  # avoid print for python 3


def main():
    if len(sys.argv) == 1:
        complete('./')
    else:
        complete(sys.argv[1])


if __name__ == '__main__':
    main()

@@ -1628,44 +1628,27 @@
 te(t
-hing):%0A    finder = NoseTestFinder()
+est_finder, thing):
 %0A   
@@ -1757,16 +1757,21 @@
  = list(
+test_
 finder.g
@@ -2695,32 +2695,45 @@
 %0A%0A%0Adef complete(
+test_finder, 
 thing):%0A    for 
@@ -2752,16 +2752,29 @@
 omplete(
+test_finder, 
 thing):%0A
@@ -2870,96 +2870,502 @@
     
-if len(sys.argv) == 1:%0A        complete('./')%0A    else:%0A        complete(sys.argv%5B1
+methods = %7B%0A        'nose': NoseTestFinder,%0A    %7D%0A    parser = OptionParser(usage='usage: %25prog %5Boptions%5D ')%0A    parser.add_option(%0A        %22-s%22,%0A        %22--search-method%22,%0A        help=%22Search method to use when locating tests%22,%0A        choices=methods.keys(),%0A        default='nose',%0A    )%0A    (options, args) = parser.parse_args()%0A    finder_class = methods.get(options.search_method)%0A    finder_instance = finder_class()%0A%0A    complete(finder_instance, './' if len(args) == 0 else args%5B0
 %5D)%0A%0A
-%0A
 if _

Use optparse to allow specifying the test search method. Default, and only current option, is nose