import sys import os import linecache import types from collections import Counter def find_duplicates(top): duplicates = [] for dirpath, dirnames, filenames in os.walk(top): for fname in filenames: root, ext = os.path.splitext(fname) if ext != '.py': continue filename = os.path.join(dirpath, fname) try: source_lines = linecache.getlines(filename) code = compile(''.join(source_lines), filename, 'exec') except: continue duplicates.extend((filename, name) for name, cnt in Counter(testmethod_names(code)).items() if cnt > 1) if duplicates: print('Duplicate test method names:') for filename, name in duplicates: print('{}: {}'.format(filename, name)) def testmethod_names(code, name=[]): name = name + [code.co_name] for c in code.co_consts: if isinstance(c, types.CodeType): for item in testmethod_names(c, name): yield item if name[-1].startswith('test_'): yield '.'.join(name) if __name__ == "__main__": if len(sys.argv) != 2 or not os.path.isdir(sys.argv[1]): print('A directory pathname is required.', file=sys.stderr) sys.exit(1) find_duplicates(sys.argv[1])