Reputation: 495
I have a temperature application that takes user input (what units, temperature) to convert between different temperature units. It involves prompting the user for these units and numbers, through the normal str(input(xyz)) and float(input(123)) type of prompts, after which the rest of the application takes that data and uses it to perform the task, which from some basic manual testing I have found that it does correctly.
I wanted to practice writing unit tests for my application using unittest, and so wrote those too (correctly as well I believe). The tests pass where expected. My issue, however, is that even though I supply data that I will need for the test to work within the test itself, I am still taken through the input prompt in my my main application. While I can just press enter to skip through it and the tests will proceed as expected, I would rather find some way for either unittest to fill in those input prompts itself, bypass that input bit completely, or at least silence it so that I don't have to run through all my input prompts every time. Is it possible to do this with unittest?
Here is the basic structure of what I wrote for my main application
def main():
unit_from, unit_to, temperature = user_input
# continues with the rest of the application using above data...
#function to get user input
def user_input():
#gets user input using str and float prompts.
#and then returns those values for use in the rest of the program
main()
and for the unittests:
import unittest
#module containing classes where the formulas for conversion live
import temperature
#main application that utilzes temperature classes and drives it all
import temp_converter
class FahrenheitConvertTestCase(unittest.TestCase):
#one of my example tests
def test_f_to_c(self):
from_unit = 'FAHRENHEIT'
to_unit = 'CELSIUS'
temp = 32.0
t_convert = temperature.Fahrenheit(temp, from_unit, to_unit)
converted_temp = t_convert.convert()
self.assertEqual(converted_temp, 0.0)
Upvotes: 2
Views: 1614
Reputation: 22021
You have to mock your input methods to return mocked value. See unittest.mock for reference of how to add mocking. Also consider reading Python common mock gotchas, it could save a lot of your time. So after adding mocking your test would look similar to code below:
@mock.patch('input', return_value='1')
def test_f_to_c(self, mock_input):
from_unit = 'FAHRENHEIT'
to_unit = 'CELSIUS'
temp = 32.0
t_convert = temperature.Fahrenheit(temp, from_unit, to_unit)
converted_temp = t_convert.convert()
self.assertEqual(converted_temp, 0.0)
Good Luck !
Upvotes: 1
Reputation: 2456
When you have a module with a function call like
main()
it will be invoked on import of the module.
You can avoid that by wrapping it in the conditional
if __name__ == '__main__':
main()
Then main
will only be called when that module is executed as the main program, not on import.
Upvotes: 1