2011-06-07 150 views
18

我正在使用Python進行一系列單元測試,其中一些依賴於配置變量的值。這些變量存儲在全局Python配置文件中,並用於其他模塊。我想爲配置變量的不同值編寫單元測試,但尚未找到實現此目的的方法。在Python單元測試框架中修改全局變量

我沒有可能重寫我正在測試的方法的簽名。

這是我想什麼來實現:

from my_module import my_function_with_global_var 

class TestSomething(self.unittest): 

    def test_first_case(self): 
     from config import MY_CONFIG_VARIABLE 
     MY_CONFIG_VARIABLE = True 
     self.assertEqual(my_function_with_global_var(), "First result") 

    def test_second_case(self): 
     from config import MY_CONFIG_VARIABLE 
     MY_CONFIG_VARIABLE = False 
     self.assertEqual(my_function_with_global_var(), "Second result") 

感謝。

編輯:使示例代碼更明確。

回答

28

不要這樣做:

from my_module import my_function_with_global_var 

但這:

import my_module 

然後你可以注入MY_CONFIG_VARIABLE到進口my_module,無被測改變系統,像這樣:

class TestSomething(unittest.TestCase): # Fixed that for you! 

    def test_first_case(self): 
     my_module.MY_CONFIG_VARIABLE = True 
     self.assertEqual(my_module.my_function_with_global_var(), "First result") 

    def test_second_case(self): 
     my_module.MY_CONFIG_VARIABLE = False 
     self.assertEqual(my_module.my_function_with_global_var(), "Second result") 

我做了類似的事情my answer toHow can I simulate input to stdin for pyunit?

+1

太棒了。這確實有效。 – badzil 2011-06-08 16:59:50

+1

@badzil:非常好。現在你有單元測試的覆蓋範圍,你可以刪除(需要)全局變量;-) – Johnsyweb 2011-06-09 00:39:42

+1

我希望我可以。 – badzil 2011-06-09 17:29:54

2

您將代碼導入MY_CONFIG_VARIABLE到本地作用域中,然後立即用不同的對象覆蓋該名稱。這不會改變config模塊中的值。嘗試

import config 
config.MY_CONFIG_VARIABLE = False 

改爲。

+1

也許我忘了別的東西提。我正在測試的函數在一個單獨的模塊中,因此已經導入了我需要修改的全局變量。您提出的修改只會修改測試文件中的全局變量。 – badzil 2011-06-07 16:28:41

+0

@badzil:可能最好的選擇是不要在你正在測試的模塊中使用'from config import MY_CONFIG_VARIABLE',而是'import config'並將變量作爲'config.MY_CONFIG_VARIABLE'來訪問。 – 2011-06-07 17:52:16

+0

謝謝。這工作雖然我正在尋找不修改我正在測試的模塊。我猜測,由於要測試的模塊使用import ... from ...指令,導入後無法更改全局變量的值。 – badzil 2011-06-07 18:28:42

27

您可能想要模擬這些全局變量。這樣做的好處是,一旦你完成了全局變量重置。 Python附帶一個模擬模塊,可以讓您執行此操作。

unittest.mock.patch被用作裝飾:

class TestSomething(self.unittest): 

    @patch('config.MY_CONFIG_VARIABLE', True) 
    def test_first_case(self): 
     self.assertEqual(my_function_with_global_var(), "First result") 

您也可以使用它作爲一個上下文管理器:

def test_first_case(self): 
     with patch('config.MY_CONFIG_VARIABLE', True): 
      self.assertEqual(my_function_with_global_var(), "First result") 
+0

神奇的方法:簡單而有效。感謝分享。特別適用於@Michele的編輯。 – fedorqui 2017-03-09 14:21:15

+0

在我的情況下,我並不關心初始值,但需要驗證全局寫入。這可以使用'patch('config')作爲mock_config'和'self.assertEqual(True,mock_config.MY_CONFIG_VARIABLE)' – codehearts 2017-11-11 23:18:31