parent
							
								
									9555d427ae
								
							
						
					
					
						commit
						07c835fdf3
					
				|  | @ -4,7 +4,7 @@ import sys, os | |||
| default_plugins = ( | ||||
|  "session terminal python runner pdb capture mark skipping tmpdir monkeypatch " | ||||
|  "recwarn pastebin unittest helpconfig nose assertion genscript " | ||||
|  "junitxml doctest keyword").split() | ||||
|  "junitxml doctest").split() | ||||
| 
 | ||||
| def main(args=None): | ||||
|     import sys | ||||
|  |  | |||
|  | @ -1,65 +0,0 @@ | |||
| 
 | ||||
| def pytest_addoption(parser): | ||||
|     group = parser.getgroup("general") | ||||
|     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. ") | ||||
| 
 | ||||
| def pytest_collection_modifyitems(items, config): | ||||
|     keywordexpr = config.option.keyword | ||||
|     if not keywordexpr: | ||||
|         return | ||||
|     selectuntil = False | ||||
|     if keywordexpr[-1] == ":": | ||||
|         selectuntil = True | ||||
|         keywordexpr = keywordexpr[:-1] | ||||
| 
 | ||||
|     remaining = [] | ||||
|     deselected = [] | ||||
|     for colitem in items: | ||||
|         if keywordexpr and skipbykeyword(colitem, keywordexpr): | ||||
|             deselected.append(colitem) | ||||
|         else: | ||||
|             remaining.append(colitem) | ||||
|             if selectuntil: | ||||
|                 keywordexpr = None | ||||
| 
 | ||||
|     if deselected: | ||||
|         config.hook.pytest_deselected(items=deselected) | ||||
|         items[:] = remaining | ||||
| 
 | ||||
| def skipbykeyword(colitem, keywordexpr): | ||||
|     """ return True if they given keyword expression means to | ||||
|         skip this collector/item. | ||||
|     """ | ||||
|     if not keywordexpr: | ||||
|         return | ||||
|     chain = colitem.listchain() | ||||
|     for key in filter(None, keywordexpr.split()): | ||||
|         eor = key[:1] == '-' | ||||
|         if eor: | ||||
|             key = key[1:] | ||||
|         if not (eor ^ matchonekeyword(key, chain)): | ||||
|             return True | ||||
| 
 | ||||
| def matchonekeyword(key, chain): | ||||
|     elems = key.split(".") | ||||
|     # XXX O(n^2), anyone cares? | ||||
|     chain = [item.keywords for item in chain if item.keywords] | ||||
|     for start, _ in enumerate(chain): | ||||
|         if start + len(elems) > len(chain): | ||||
|             return False | ||||
|         for num, elem in enumerate(elems): | ||||
|             for keyword in chain[num + start]: | ||||
|                 ok = False | ||||
|                 if elem in keyword: | ||||
|                     ok = True | ||||
|                     break | ||||
|             if not ok: | ||||
|                 break | ||||
|         if num == len(elems) - 1 and ok: | ||||
|             return True | ||||
|     return False | ||||
|  | @ -87,6 +87,71 @@ import py | |||
| def pytest_namespace(): | ||||
|     return {'mark': MarkGenerator()} | ||||
| 
 | ||||
| def pytest_addoption(parser): | ||||
|     group = parser.getgroup("general") | ||||
|     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. ") | ||||
| 
 | ||||
| def pytest_collection_modifyitems(items, config): | ||||
|     keywordexpr = config.option.keyword | ||||
|     if not keywordexpr: | ||||
|         return | ||||
|     selectuntil = False | ||||
|     if keywordexpr[-1] == ":": | ||||
|         selectuntil = True | ||||
|         keywordexpr = keywordexpr[:-1] | ||||
| 
 | ||||
|     remaining = [] | ||||
|     deselected = [] | ||||
|     for colitem in items: | ||||
|         if keywordexpr and skipbykeyword(colitem, keywordexpr): | ||||
|             deselected.append(colitem) | ||||
|         else: | ||||
|             remaining.append(colitem) | ||||
|             if selectuntil: | ||||
|                 keywordexpr = None | ||||
| 
 | ||||
|     if deselected: | ||||
|         config.hook.pytest_deselected(items=deselected) | ||||
|         items[:] = remaining | ||||
| 
 | ||||
| def skipbykeyword(colitem, keywordexpr): | ||||
|     """ return True if they given keyword expression means to | ||||
|         skip this collector/item. | ||||
|     """ | ||||
|     if not keywordexpr: | ||||
|         return | ||||
|     chain = colitem.listchain() | ||||
|     for key in filter(None, keywordexpr.split()): | ||||
|         eor = key[:1] == '-' | ||||
|         if eor: | ||||
|             key = key[1:] | ||||
|         if not (eor ^ matchonekeyword(key, chain)): | ||||
|             return True | ||||
| 
 | ||||
| def matchonekeyword(key, chain): | ||||
|     elems = key.split(".") | ||||
|     # XXX O(n^2), anyone cares? | ||||
|     chain = [item.keywords for item in chain if item.keywords] | ||||
|     for start, _ in enumerate(chain): | ||||
|         if start + len(elems) > len(chain): | ||||
|             return False | ||||
|         for num, elem in enumerate(elems): | ||||
|             for keyword in chain[num + start]: | ||||
|                 ok = False | ||||
|                 if elem in keyword: | ||||
|                     ok = True | ||||
|                     break | ||||
|             if not ok: | ||||
|                 break | ||||
|         if num == len(elems) - 1 and ok: | ||||
|             return True | ||||
|     return False | ||||
| 
 | ||||
| class MarkGenerator: | ||||
|     """ non-underscore attributes of this object can be used as decorators for | ||||
|     marking test functions. Example: @py.test.mark.slowtest in front of a | ||||
|  |  | |||
|  | @ -1,127 +0,0 @@ | |||
| import py | ||||
| 
 | ||||
| class Test_genitems: | ||||
|     def test_check_collect_hashes(self, testdir): | ||||
|         p = testdir.makepyfile(""" | ||||
|             def test_1(): | ||||
|                 pass | ||||
| 
 | ||||
|             def test_2(): | ||||
|                 pass | ||||
|         """) | ||||
|         p.copy(p.dirpath(p.purebasename + "2" + ".py")) | ||||
|         items, reprec = testdir.inline_genitems(p.dirpath()) | ||||
|         assert len(items) == 4 | ||||
|         for numi, i in enumerate(items): | ||||
|             for numj, j in enumerate(items): | ||||
|                 if numj != numi: | ||||
|                     assert hash(i) != hash(j) | ||||
|                     assert i != j | ||||
| 
 | ||||
|     def test_root_conftest_syntax_error(self, testdir): | ||||
|         # do we want to unify behaviour with | ||||
|         # test_subdir_conftest_error? | ||||
|         p = testdir.makepyfile(conftest="raise SyntaxError\n") | ||||
|         py.test.raises(SyntaxError, testdir.inline_genitems, p.dirpath()) | ||||
| 
 | ||||
|     def test_example_items1(self, testdir): | ||||
|         p = testdir.makepyfile(''' | ||||
|             def testone(): | ||||
|                 pass | ||||
| 
 | ||||
|             class TestX: | ||||
|                 def testmethod_one(self): | ||||
|                     pass | ||||
| 
 | ||||
|             class TestY(TestX): | ||||
|                 pass | ||||
|         ''') | ||||
|         items, reprec = testdir.inline_genitems(p) | ||||
|         assert len(items) == 3 | ||||
|         assert items[0].name == 'testone' | ||||
|         assert items[1].name == 'testmethod_one' | ||||
|         assert items[2].name == 'testmethod_one' | ||||
| 
 | ||||
|         # let's also test getmodpath here | ||||
|         assert items[0].getmodpath() == "testone" | ||||
|         assert items[1].getmodpath() == "TestX.testmethod_one" | ||||
|         assert items[2].getmodpath() == "TestY.testmethod_one" | ||||
| 
 | ||||
|         s = items[0].getmodpath(stopatmodule=False) | ||||
|         assert s.endswith("test_example_items1.testone") | ||||
|         print(s) | ||||
| 
 | ||||
| 
 | ||||
| class TestKeywordSelection: | ||||
|     def test_select_simple(self, testdir): | ||||
|         file_test = testdir.makepyfile(""" | ||||
|             def test_one(): assert 0 | ||||
|             class TestClass(object): | ||||
|                 def test_method_one(self): | ||||
|                     assert 42 == 43 | ||||
|         """) | ||||
|         def check(keyword, name): | ||||
|             reprec = testdir.inline_run("-s", "-k", keyword, file_test) | ||||
|             passed, skipped, failed = reprec.listoutcomes() | ||||
|             assert len(failed) == 1 | ||||
|             assert failed[0].nodeid.split("::")[-1] == name | ||||
|             assert len(reprec.getcalls('pytest_deselected')) == 1 | ||||
| 
 | ||||
|         for keyword in ['test_one', 'est_on']: | ||||
|             #yield check, keyword, 'test_one' | ||||
|             check(keyword, 'test_one') | ||||
|         check('TestClass.test', 'test_method_one') | ||||
| 
 | ||||
|     def test_select_extra_keywords(self, testdir): | ||||
|         p = testdir.makepyfile(test_select=""" | ||||
|             def test_1(): | ||||
|                 pass | ||||
|             class TestClass: | ||||
|                 def test_2(self): | ||||
|                     pass | ||||
|         """) | ||||
|         testdir.makepyfile(conftest=""" | ||||
|             import py | ||||
|             class Class(py.test.collect.Class): | ||||
|                 def _keywords(self): | ||||
|                     return ['xxx', self.name] | ||||
|         """) | ||||
|         for keyword in ('xxx', 'xxx test_2', 'TestClass', 'xxx -test_1', | ||||
|                         'TestClass test_2', 'xxx TestClass test_2',): | ||||
|             reprec = testdir.inline_run(p.dirpath(), '-s', '-k', keyword) | ||||
|             py.builtin.print_("keyword", repr(keyword)) | ||||
|             passed, skipped, failed = reprec.listoutcomes() | ||||
|             assert len(passed) == 1 | ||||
|             assert passed[0].nodeid.endswith("test_2") | ||||
|             dlist = reprec.getcalls("pytest_deselected") | ||||
|             assert len(dlist) == 1 | ||||
|             assert dlist[0].items[0].name == 'test_1' | ||||
| 
 | ||||
|     def test_select_starton(self, testdir): | ||||
|         threepass = testdir.makepyfile(test_threepass=""" | ||||
|             def test_one(): assert 1 | ||||
|             def test_two(): assert 1 | ||||
|             def test_three(): assert 1 | ||||
|         """) | ||||
|         reprec = testdir.inline_run("-k", "test_two:", threepass) | ||||
|         passed, skipped, failed = reprec.listoutcomes() | ||||
|         assert len(passed) == 2 | ||||
|         assert not failed | ||||
|         dlist = reprec.getcalls("pytest_deselected") | ||||
|         assert len(dlist) == 1 | ||||
|         item = dlist[0].items[0] | ||||
|         assert item.name == "test_one" | ||||
| 
 | ||||
| 
 | ||||
|     def test_keyword_extra(self, testdir): | ||||
|         p = testdir.makepyfile(""" | ||||
|            def test_one(): | ||||
|                assert 0 | ||||
|            test_one.mykeyword = True | ||||
|         """) | ||||
|         reprec = testdir.inline_run("-k", "-mykeyword", p) | ||||
|         passed, skipped, failed = reprec.countoutcomes() | ||||
|         assert passed + skipped + failed == 0 | ||||
|         reprec = testdir.inline_run("-k", "mykeyword", p) | ||||
|         passed, skipped, failed = reprec.countoutcomes() | ||||
|         assert failed == 1 | ||||
|  | @ -173,3 +173,130 @@ class TestFunctional: | |||
|         result.stdout.fnmatch_lines([ | ||||
|             "keyword: *hello*" | ||||
|         ]) | ||||
| 
 | ||||
| 
 | ||||
| class Test_genitems: | ||||
|     def test_check_collect_hashes(self, testdir): | ||||
|         p = testdir.makepyfile(""" | ||||
|             def test_1(): | ||||
|                 pass | ||||
| 
 | ||||
|             def test_2(): | ||||
|                 pass | ||||
|         """) | ||||
|         p.copy(p.dirpath(p.purebasename + "2" + ".py")) | ||||
|         items, reprec = testdir.inline_genitems(p.dirpath()) | ||||
|         assert len(items) == 4 | ||||
|         for numi, i in enumerate(items): | ||||
|             for numj, j in enumerate(items): | ||||
|                 if numj != numi: | ||||
|                     assert hash(i) != hash(j) | ||||
|                     assert i != j | ||||
| 
 | ||||
|     def test_root_conftest_syntax_error(self, testdir): | ||||
|         # do we want to unify behaviour with | ||||
|         # test_subdir_conftest_error? | ||||
|         p = testdir.makepyfile(conftest="raise SyntaxError\n") | ||||
|         py.test.raises(SyntaxError, testdir.inline_genitems, p.dirpath()) | ||||
| 
 | ||||
|     def test_example_items1(self, testdir): | ||||
|         p = testdir.makepyfile(''' | ||||
|             def testone(): | ||||
|                 pass | ||||
| 
 | ||||
|             class TestX: | ||||
|                 def testmethod_one(self): | ||||
|                     pass | ||||
| 
 | ||||
|             class TestY(TestX): | ||||
|                 pass | ||||
|         ''') | ||||
|         items, reprec = testdir.inline_genitems(p) | ||||
|         assert len(items) == 3 | ||||
|         assert items[0].name == 'testone' | ||||
|         assert items[1].name == 'testmethod_one' | ||||
|         assert items[2].name == 'testmethod_one' | ||||
| 
 | ||||
|         # let's also test getmodpath here | ||||
|         assert items[0].getmodpath() == "testone" | ||||
|         assert items[1].getmodpath() == "TestX.testmethod_one" | ||||
|         assert items[2].getmodpath() == "TestY.testmethod_one" | ||||
| 
 | ||||
|         s = items[0].getmodpath(stopatmodule=False) | ||||
|         assert s.endswith("test_example_items1.testone") | ||||
|         print(s) | ||||
| 
 | ||||
| 
 | ||||
| class TestKeywordSelection: | ||||
|     def test_select_simple(self, testdir): | ||||
|         file_test = testdir.makepyfile(""" | ||||
|             def test_one(): assert 0 | ||||
|             class TestClass(object): | ||||
|                 def test_method_one(self): | ||||
|                     assert 42 == 43 | ||||
|         """) | ||||
|         def check(keyword, name): | ||||
|             reprec = testdir.inline_run("-s", "-k", keyword, file_test) | ||||
|             passed, skipped, failed = reprec.listoutcomes() | ||||
|             assert len(failed) == 1 | ||||
|             assert failed[0].nodeid.split("::")[-1] == name | ||||
|             assert len(reprec.getcalls('pytest_deselected')) == 1 | ||||
| 
 | ||||
|         for keyword in ['test_one', 'est_on']: | ||||
|             #yield check, keyword, 'test_one' | ||||
|             check(keyword, 'test_one') | ||||
|         check('TestClass.test', 'test_method_one') | ||||
| 
 | ||||
|     def test_select_extra_keywords(self, testdir): | ||||
|         p = testdir.makepyfile(test_select=""" | ||||
|             def test_1(): | ||||
|                 pass | ||||
|             class TestClass: | ||||
|                 def test_2(self): | ||||
|                     pass | ||||
|         """) | ||||
|         testdir.makepyfile(conftest=""" | ||||
|             import py | ||||
|             class Class(py.test.collect.Class): | ||||
|                 def _keywords(self): | ||||
|                     return ['xxx', self.name] | ||||
|         """) | ||||
|         for keyword in ('xxx', 'xxx test_2', 'TestClass', 'xxx -test_1', | ||||
|                         'TestClass test_2', 'xxx TestClass test_2',): | ||||
|             reprec = testdir.inline_run(p.dirpath(), '-s', '-k', keyword) | ||||
|             py.builtin.print_("keyword", repr(keyword)) | ||||
|             passed, skipped, failed = reprec.listoutcomes() | ||||
|             assert len(passed) == 1 | ||||
|             assert passed[0].nodeid.endswith("test_2") | ||||
|             dlist = reprec.getcalls("pytest_deselected") | ||||
|             assert len(dlist) == 1 | ||||
|             assert dlist[0].items[0].name == 'test_1' | ||||
| 
 | ||||
|     def test_select_starton(self, testdir): | ||||
|         threepass = testdir.makepyfile(test_threepass=""" | ||||
|             def test_one(): assert 1 | ||||
|             def test_two(): assert 1 | ||||
|             def test_three(): assert 1 | ||||
|         """) | ||||
|         reprec = testdir.inline_run("-k", "test_two:", threepass) | ||||
|         passed, skipped, failed = reprec.listoutcomes() | ||||
|         assert len(passed) == 2 | ||||
|         assert not failed | ||||
|         dlist = reprec.getcalls("pytest_deselected") | ||||
|         assert len(dlist) == 1 | ||||
|         item = dlist[0].items[0] | ||||
|         assert item.name == "test_one" | ||||
| 
 | ||||
| 
 | ||||
|     def test_keyword_extra(self, testdir): | ||||
|         p = testdir.makepyfile(""" | ||||
|            def test_one(): | ||||
|                assert 0 | ||||
|            test_one.mykeyword = True | ||||
|         """) | ||||
|         reprec = testdir.inline_run("-k", "-mykeyword", p) | ||||
|         passed, skipped, failed = reprec.countoutcomes() | ||||
|         assert passed + skipped + failed == 0 | ||||
|         reprec = testdir.inline_run("-k", "mykeyword", p) | ||||
|         passed, skipped, failed = reprec.countoutcomes() | ||||
|         assert failed == 1 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue