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

时间:2016-04-21 07:39:02

标签: python python-2.7 unit-testing ubuntu-14.04

我是python的新手。我想测试一个接受原始输入并在输入上调用另一个函数的函数。我知道这可以使用mock进行测试,但我不知道如何。

我的功能是这样的:

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测试此功能?

3 个答案:

答案 0 :(得分:1)

主菜单模块:

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'中你将放置所有实际的函数......

答案 1 :(得分:1)

我强烈建议您稍微重构一下代码以使其可测试,只需将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)

这是一种独立于语言的一般良好做法。

答案 2 :(得分:0)

可能是这样的:

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