Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modifying global variables in Python unittest framework

I am working on a series of unit tests in Python, some of which depend on the value of a configuration variable. These variables are stored in a global Python config file and are used in other modules. I would like to write unit tests for different values of the configuration variables but have not yet found a way to do this.

I do not have the possibility to rewrite the signatures of the methods I'm testing.

This is what I would like to achieve:

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") 

Thanks.

Edit: Made the example code more explicite.

like image 321
badzil Avatar asked Jun 07 '11 16:06

badzil


People also ask

Can you change global variables in Python?

In Python, global keyword allows you to modify the variable outside of the current scope. It is used to create a global variable and make changes to the variable in a local context.

Should you avoid using global variables in Python?

While in many or most other programming languages variables are treated as global if not declared otherwise, Python deals with variables the other way around. They are local, if not otherwise declared. The driving reason behind this approach is that global variables are generally bad practice and should be avoided.

Can you edit global variables?

Functions can access global variables and modify them. Modifying global variables in a function is considered poor programming practice. It is better to send a variable in as a parameter (or have it be returned in the 'return' statement).

How do you manipulate a global variable in Python?

Use of “global†keyword to modify global variable inside a function. If your function has a local variable with same name as global variable and you want to modify the global variable inside function then use 'global' keyword before the variable name at start of function i.e.


2 Answers

You probably want to mock those global variables instead. The advantage of this is that the globals get reset once you're done. Python ships with a mocking module that lets you do this.

unittest.mock.patch be used as a decorator:

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

You can also use it as a context manager:

    def test_first_case(self):         with patch('config.MY_CONFIG_VARIABLE', True):             self.assertEqual(my_function_with_global_var(), "First result") 
like image 186
Flimm Avatar answered Sep 27 '22 18:09

Flimm


Use unittest.mock.patch as in @Flimm's answer, if that's available to you.


Original Answer

Don't do this:

from my_module import my_function_with_global_var 

But this:

import my_module 

And then you can inject MY_CONFIG_VARIABLE into the imported my_module, without changing the system under test like so:

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") 

I did something similar in my answer to How can I simulate input to stdin for pyunit? .

like image 30
Johnsyweb Avatar answered Sep 27 '22 19:09

Johnsyweb