[英]Is it possible to run unit tests on code that uses subprocess?
我的 Django 應用程序有一些管理命令,這些命令使用 subprocess.Popen subprocess.Popen(['manage.py', '<command>', ...)
啟動其他管理命令。 它們保持這樣主要是為了並行運行進程並防止一個命令干擾另一個命令。
但是,在編寫單元測試時,這些新流程不使用測試環境和數據庫,因此會失敗。
現在,我添加了一個運行call_command()
而不是 Popen( Popen()
的設置(見下文):
if settings.TESTING:
self.returncode = call_command(self.command, *params)
else:
self.process = subprocess.Popen(['python', 'manage.py', self.command] + params)
# ... later on:
self.process.wait()
self.returncode = self.process.returncode
然而,子流程調用和等待所涉及的邏輯仍未測試。 是否可以在單元測試中測試子進程調用?
注意:測試數據庫不是內存中的 SQLite - 我知道那行不通。 它是一個實際的數據庫,每次運行都會創建和銷毀。
如果您將其視為單元測試,那么您可以模擬您的命令調用以返回模擬數據,以確保命令調用者工作正常。
對於命令代碼的覆蓋率,您還可以使用call_command
方法僅為該命令編寫另一個單元測試。
像這樣:
class TestYourCommandCaller(TestCase):
...
@mock.patch('subprocess.Popen')
def test_your_business_which_call_the_command(self, mock_process):
# Mock your process
call_your_function_which_create_processes()
# Assert your process have been called
和另一個測試你的命令也覆蓋命令代碼:
class TestYourCommand(TestCase):
def test_command_call(self):
call_command('command_name', *params)
# Assert the result
是的,你可以這樣做。 目前我有通過子進程運行多個程序的代碼。 我正在使用 unittest 來確保執行此操作的函數產生預期的 output。 也許一些純粹主義者會認為這是對單元測試的不當使用,但它對我的測試自動化很有用。 一個相當簡單的例子如下:
call_ls.py:
import subprocess
def call_ls():
subproc = subprocess.Popen(['ls', 'empty_dir'],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
result = subproc.communicate()
return result
test_call_ls.py:
import unittest
import call_ls
class TestCallLs(unittest.TestCase):
def test_call_ls(self):
test_out = call_ls.call_ls()
self.assertEqual((b'', None), test_out)
if __name__ == '__main__':
unittest.main()
斷言中的元組用於處理 subprocess.communicate() 返回的內容。 如您所料,目錄“empty_dir”中沒有任何內容。 運行測試給出了預期的結果:
$ python test_call_ls.py
.
----------------------------------------------------------------------
Ran 1 test in 0.006s
OK
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.