2014-12-29 225 views
1

我試圖用unittest運行我的測試。這裏是我的結構:單元測試失敗,出現sys.exit

projectname/ 
    projectname/ 
     foo.py 
     bar.py 
    tests/ 
     test_foo.py 
     test_bar.py 

我運行它:

cd tests/ 
python -m unittest discover 

但在一個文件中,例如foo.py,我用一個sys.exit(0),和單元測試並不真的很喜歡它:

$ python -m unittest discover 
....E. 
====================================================================== 
ERROR: test_foo (...) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
... 
... 
File "/home/.../projectname/foo.py", line 12, in write 
    sys.exit(0) 
SystemExit: 0 

---------------------------------------------------------------------- 
Ran 6 tests in 0.018s 

FAILED (errors=1) 

sys.exit()使用是自願的,我不能刪除它。我知道有對unittest.main函數調用exit一個選項:

if __name__ == "__main__": 
    unittest.main(exit=False) 

但我想測試在測試目錄中的所有文件。另一種方法是要做到:

if __name__ == '__main__': 
    tests = unittest.TestLoader().discover('.') 
    unittest.TextTestRunner(verbosity=1).run(tests) 

它發現所有TEST_文件,但sys.exit()使得單元測試崩潰。

+2

任何調用'sys.exit'都不是可重用的單元,因爲它的絕對性,所以單元測試並不適用。但是,您可能可以替換該代碼段的'sys.exit',儘管這也會改變被測試者的行爲。你可能能夠捕捉它引發的異常,我相信你只需要捕捉ExceptionBase。 –

回答

0

我不認爲在模塊中使用sys.exit()是一個好主意。但是如果你必須,你應該做的就是編寫一個測試用例,將模塊作爲子進程封裝,可能使用子進程模塊,並驗證退出代碼。你可能還需要一個包裝腳本來調用。換句話說,您調用一個導入該模塊的外部Python腳本,然後退出。然後unittest框架可以通過檢查子進程的返回值來報告通過/失敗。

4

sys.exit實際上並未退出解釋器。它只是提高SystemExit。如果該異常使其位於堆棧的頂部,則解釋器開始退出過程(使用相關的退出值)。

unittest不高興,因爲它正在捕捉異常(因此解釋器不會實際退出),但測試不會被描述爲期望引發該異常。

請嘗試以下操作。

def test_exit_func(self): 
    with self.assertRaises(SystemExit): 
     sys.exit(0)