Python单元测试:如何测试调用其他函数的函数?

Python单元测试:如何测试调用其他函数的函数?

问题描述:

我是python的新手。我想测试一个采用原始输入并在输入上调用另一个函数的函数。我知道这可以使用模拟测试,但我不知道如何。Python单元测试:如何测试调用其他函数的函数?

我的功能是这样的:

def show_main_menu(self): 
    """shows main menu to user""" 
    print '1:create account \t 2:Log in \t any other to exit \n' 
    while True: 
     try: 
      option = int(raw_input('Enter your option: \t')) 
     except ValueError: 
      print 'please enter valid input \n' 
      continue 
     else: 
      break 
    if option == 1: 
     self.add_account() 
     print '\n ***successfully created account***\n' 
     self.menu_post_transaction() 
    elif option == 2: 
     self.login() 
    else: 
     print 'Thank you for using our services' 
     exit() 

如何使用unittest我测试这个功能呢?

+0

的可能的复制[我怎么能模拟输入标准输入的PyUnit?](http://*.com/questions/6271947/how-can-i-simulate-input-to-stdin-for-pyunit) – user590028

主菜单模块:

import unittest 
from your_tests_directory import add_account_test, login_test 

def menu(): 
    loader = unittest.TestLoader() 
    suite = unittest.TestSuite() 

    option = int(raw_input('Enter your option: \t')) 
    if option == 1: 
     module = add_account_test 
    else: 
     module = login_test 

    suite.addTest(loader.loadTestsFromModule(module)) 
    unittest.TextTestRunner(verbosity=2).run(suite) 

if __name__ == '__main__': 
    menu() 

add_account_test模块:

import unittest 
from other_module import add_account, menu_post_transaction 

class AddAccountTest(unittest.TestCase): 
    def test_account(self): 
     add_account() 
     print '\n ***successfully created account***\n' 
     menu_post_transaction() 

login_test模块:

import unittest 
from other_module import login 

class LoginTest(unittest.TestCase): 
    def test_login(self): 
     login() 
在 'other_module' 你会把所有的实际功能

...

它c乌尔德是这样的:

from unittest.mock import patch 
from unittest import TestCase 

@patch('yourmodule.show_main_menu', return_value='1') 
def test_answer_one(self, input): 
    self.assertEqual(show_main_menu(), '\n ***successfully created account***\n') 

@patch('yourmodule.show_main_menu', return_value='5') 
def test_answer_five(self, input): 
    self.assertEqual(show_main_menu(), 'Thank you for using our services') 

我强烈建议你重构你的代码位,使之可测试的,仅通过提取raw_input相关代码的功能,你不会需要模拟什么,_get_raw_input()将是可重复使用。

在测试你只需要通过自己的函数中的参数get_option简单地返回一个任意选择。

PS:show_main_menu功能,可以在一些改名像launch_action

#!/usr/bin/env python2 
# coding=utf-8 

def _get_raw_input(prompt): 
    while True: 
     try: 
      return int(raw_input(prompt)) 
     except ValueError: 
      print 'please enter valid input \n' 
      continue 
     else: 
      break 

class Foo: 
    def menu_post_transaction(self): print 'menu_post_transaction' 
    def add_account(self): print "### 1. add_account" 
    def login(self): print "### 2. login" 

    def show_main_menu(self, get_option=_get_raw_input): 
      """shows main menu to user""" 
      print '1:create account \t 2:Log in \t any other to exit \n' 
      option = get_option('Enter your option: \t') 
      if option == 1: 
       self.add_account() 
       print '\n ***successfully created account***\n' 
       self.menu_post_transaction() 
      elif option == 2: 
       self.login() 
      else: 
       print 'Thank you for using our services' 

if __name__ == "__main__": 

    Foo().show_main_menu(lambda _: 1) 
    Foo().show_main_menu(lambda _: 2) 
    Foo().show_main_menu(lambda _: 3) 

这是一个一般的好习惯独立于语言。