92 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			92 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Python
		
	
	
	
| """
 | |
| mark python test functions as expected-to-fail and report them separately. 
 | |
| 
 | |
| usage
 | |
| ------------
 | |
| 
 | |
| Use the generic mark decorator to mark your test functions as 
 | |
| 'expected to fail':: 
 | |
| 
 | |
|     @py.test.mark.xfail
 | |
|     def test_hello():
 | |
|         ...
 | |
| 
 | |
| This test will be executed but no traceback will be reported 
 | |
| when it fails. Instead terminal reporting will list it in the 
 | |
| "expected to fail" section or "unexpectedly passing" section.  
 | |
| 
 | |
| """
 | |
| 
 | |
| import py
 | |
| 
 | |
| pytest_plugins = ['keyword']
 | |
| 
 | |
| def pytest_runtest_makereport(__call__, item, call):
 | |
|     if call.when != "call":
 | |
|         return
 | |
|     if hasattr(item, 'obj') and hasattr(item.obj, 'func_dict'):
 | |
|         if 'xfail' in item.obj.func_dict:
 | |
|             res = __call__.execute(firstresult=True)
 | |
|             if call.excinfo:
 | |
|                 res.skipped = True
 | |
|                 res.failed = res.passed = False
 | |
|             else:
 | |
|                 res.skipped = res.passed = False
 | |
|                 res.failed = True
 | |
|             return res 
 | |
| 
 | |
| def pytest_report_teststatus(report):
 | |
|     if 'xfail' in report.keywords: 
 | |
|         if report.skipped:
 | |
|             return "xfailed", "x", "xfail"
 | |
|         elif report.failed:
 | |
|             return "xpassed", "P", "xpass" 
 | |
| 
 | |
| # called by the terminalreporter instance/plugin
 | |
| def pytest_terminal_summary(terminalreporter):
 | |
|     tr = terminalreporter
 | |
|     xfailed = tr.stats.get("xfailed")
 | |
|     if xfailed:
 | |
|         tr.write_sep("_", "expected failures")
 | |
|         for rep in xfailed:
 | |
|             entry = rep.longrepr.reprcrash 
 | |
|             modpath = rep.item.getmodpath(includemodule=True)
 | |
|             pos = "%s %s:%d: " %(modpath, entry.path, entry.lineno)
 | |
|             reason = rep.longrepr.reprcrash.message
 | |
|             tr._tw.line("%s %s" %(pos, reason))
 | |
| 
 | |
|     xpassed = terminalreporter.stats.get("xpassed")
 | |
|     if xpassed:
 | |
|         tr.write_sep("_", "UNEXPECTEDLY PASSING TESTS")
 | |
|         for rep in xpassed:
 | |
|             fspath, lineno, modpath = rep.item.reportinfo()
 | |
|             pos = "%s %s:%d: unexpectedly passing" %(modpath, fspath, lineno)
 | |
|             tr._tw.line(pos)
 | |
| 
 | |
| 
 | |
| # =============================================================================
 | |
| #
 | |
| # plugin tests 
 | |
| #
 | |
| # =============================================================================
 | |
| 
 | |
| def test_xfail(testdir):
 | |
|     p = testdir.makepyfile(test_one="""
 | |
|         import py
 | |
|         @py.test.mark.xfail
 | |
|         def test_this():
 | |
|             assert 0
 | |
| 
 | |
|         @py.test.mark.xfail
 | |
|         def test_that():
 | |
|             assert 1
 | |
|     """)
 | |
|     result = testdir.runpytest(p)
 | |
|     extra = result.stdout.fnmatch_lines([
 | |
|         "*expected failures*",
 | |
|         "*test_one.test_this*test_one.py:4*",
 | |
|         "*UNEXPECTEDLY PASSING*",
 | |
|         "*test_that*",
 | |
|     ])
 | |
|     assert result.ret == 1
 |