UnitTest实例实战

1、UnitTest案例准备

通过PyCharm在工程目录下创建UnitTestDemo的PythonPackage。UnitTest的案例均存在UnitTestDemo下。

(1)、创建基础待测方法。在UnitTestDemo下新建mathfunc.py文件,代码如下:

# 加法,返回a+b的值

def add(a, b):
    return a+b

# 减法,返回a-b的值
def minus(a,b):
    return a-b

# 乘法,返回a*b的值
def multi(a, b):
    return a*b

# 除法,返回a/b的值
def divide(a,b):
    return a/b


(2)、设计测试用例。为前面的测试方法设计测试用例,在UnitTestDemo下创建test_mathfunc.py文件,代码如下:

import unittest
from UnitTestDemo.mathfunc import *

class TestMathFunc(unittest.TestCase):
    """测试mathfunc.py"""

    def test_add(self):
        """测试加法add"""
        self.assertEqual(3, add(1, 2))
        self.assertNotEqual(3, add(2, 2))

    def test_minus(self):
        """测试减法minus"""
        self.assertEqual(1, minus(3, 2))

    def test_multi(self):
        """测试乘法multi"""
        self.assertEqual(6, multi(2, 3))

    def test_divide(self):
        """测试除法divide"""
        self.assertEqual(2, divide(6, 3))
        self.assertEqual(2.5, divide(5, 2))

2、组织与设定测试用例的执行顺序

测试套件(TestSuite)是多个测试用例的集合,是针对被测程序的对应功能和模块创建的一组测试。

通过TestSuite()的addTest()方法手动把TestCase添加到TestSuite中,或通过Test Loader把TestCase自动加载到Test Suite中。首先创建测试套件,执行单挑用例调用addTest()方法,在UnitTestDemo下创建test_suite.py文件,代码如下:

import unittest
from UnitTestDemo.test_mathfunc import TestMathFunc

if __name__ == "__main__":
    suite = unittest.TestSuite()
    # addTest()添加单个TestSuit
    suite.addTest(TestMathFunc("test_multi"))
    runner = unittest.TextTestRunner()
    runner.run(suite)

执行多条测试用例addTests()方法,test_suite,py文件下的代码如下:

import unittest
from UnitTestDemo.test_mathfunc import TestMathFunc

if __name__ == "__main__":
    suite = unittest.TestSuite()
    # addTest()添加单个TestSuit
    # suite.addTest(TestMathFunc("test_multi"))
    tests = [TestMathFunc("test_add"), TestMathFunc("test_divide"),         TestMathFunc("test_minus")]
    suite.addTests(tests)
    runner = unittest.TextTestRunner()
    runner.run(suite)

3、测试结果 

TextTestRunner测试执行器负责测试执行调度并且生成测试结果给用户。可以将测试结果直接在控制台输出,也可以将测试结果输出到外部文件中。

有时候想要很清楚的看到每条用例执行的详细信息,可以通过设置verbosity参数来实现。verbosity默认值为1,可以设置为0 和2.

  • 0(静默模式):只能获得总的测试用例数和总的结果;
  • 1(默认模式):非常类似于静默模式,只是在每个成功的用例i起那面有个“.”,每个失败的用例起那面有个“E”;
  • 2(详细模式):测试结果会显示每个测试用例的所有相关信息,并且在命令行里加入不同的参数可以起到一起的现过。

(1)将结果输出到IDE中。

verbosity=0,修改test_suite.py文件,代码如下:

import unittest
from UnitTestDemo.test_mathfunc import TestMathFunc

if __name__ == "__main__":
    suite = unittest.TestSuite()
    tests = [TestMathFunc("test_add"), TestMathFunc("test_divide"), TestMathFunc("test_minus")]
    suite.addTests(tests)
    runner = unittest.TextTestRunner(verbosity=0)
    runner.run(suite)

运行结果:

设置verbosity=1,运行代码,结果如下:

设置verbosity=2,运行代码,结果如下:

(2)将结果输出到外部文件中

优化test_suite.py文件,通过stream参数将结果输出到外部文件中,优化test_suite.py文件后的代码如下:

import unittest
from UnitTestDemo.test_mathfunc import TestMathFunc

if __name__ == "__main__":
    suite = unittest.TestSuite()
    # addTest()添加单个TestSuit
    # suite.addTest(TestMathFunc("test_multi"))
    tests = [TestMathFunc("test_add"), TestMathFunc("test_divide"), TestMathFunc("test_minus")]
    suite.addTests(tests)
    # runner = unittest.TextTestRunner(verbosity=2)
    # runner.run(suite)
    with open("F:\\result.txt", "a") as f:
        runner = unittest.TextTestRunner(stream=f, verbosity=2)
        runner.run(suite)

运行后可以在F盘下发现多了一个result.txt文件。result.txt文件如下:

4、测试初始化与还原 

通过使用Fixture,可以定义测试执行之前的准备工作和测试执行之后的清理工作。

  • setUp():执行用例的前置条件,如建立数据库连接;
  • tearDown():执行完用例后,为了不影响下一次用例的执行,一般有一个数据还原的过程,tearDown()是执行用例的后置条件,如关闭数据库连接。

下面结合案例,分别针对初始化与还原的接种方式进行详细介绍:

方式1:setUp()与tearDown()方法.

  • setUp():每个测试case运行之前执行;
  • tearDown():每个测试擦色运行完后执行。

修改UnitTestDemo创建的test_mathfunc.py文件,增加setUp()与tearDown()方法,代码如下:

import unittest
from UnitTestDemo.mathfunc import *

class TestMathFunc(unittest.TestCase):
    """测试mathfunc.py"""
    # 在每条测试用例执行之前准备好测试环境
    def setUp(self) -> None:
        print("do something before test!")


    def test_add(self):
        """测试加法add"""
        self.assertEqual(3, add(1, 2))
        self.assertNotEqual(3, add(2, 2))

    def test_minus(self):
        """测试减法minus"""
        self.assertEqual(1, minus(3, 2))

    def test_multi(self):
        """测试乘法multi"""
        self.assertEqual(6, multi(2, 3))

    def test_divide(self):
        """测试除法divide"""
        self.assertEqual(2, divide(6, 3))
        self.assertEqual(2, divide(5, 2))

    # 在每条测试用例执行结束之后清理测试环境,还原到初始状态

    def tearDown(self) -> None:
        print("do something after test!")


方式2:setUpClass()与tearDownClass()方法

  • setUpClass():必须使用@classmethod装饰器,初始化操作在所有case运行前只运行一次;
  • testDownClass():必须使用@classmethod装饰器,还原操作在所有case运行后只运行一次。

修改UintTestDemo创建的test_mathtunc.py文件,在其中增加setUpClass()与tearDownClass()方法,代码如下:

import unittest
from UnitTestDemo.mathfunc import *

class TestMathFunc(unittest.TestCase):
    """测试mathfunc.py"""
    # 在每条测试用例执行之前准备好测试环境
    # def setUp(self) -> None:
    #     print("do something before test!")

    @classmethod
    def setUpClass(cls) -> None:
        print("so something before testClass,only run once!")

    def test_add(self):
        """测试加法add"""
        self.assertEqual(3, add(1, 2))
        self.assertNotEqual(3, add(2, 2))

    def test_minus(self):
        """测试减法minus"""
        self.assertEqual(1, minus(3, 2))

    def test_multi(self):
        """测试乘法multi"""
        self.assertEqual(6, multi(2, 3))

    def test_divide(self):
        """测试除法divide"""
        self.assertEqual(2, divide(6, 3))
        self.assertEqual(2, divide(5, 2))

    # 在每条测试用例执行结束之后清理测试环境,还原到初始状态
    # def tearDown(self):
    #     print("do something after test!")

    # def tearDown(self) -> None:
    #     print("do something after test!")

    @classmethod
    def tearDownClass(cls) -> None:
        print("do something after testClass,only run once")

运行结果:

5、测试用例跳过(skip)

在执行测试用例时,有时候有些用例时不需要执行的,UniteTest提供了跳过用例的方法。

  • @unittest.skip(reason):强制跳过,不需要判断条件。reason参数时跳过原因的描述,必须填写。
  • @unittest.skipUnless(condition,reason):condition为True时将跳过用例。
  • @unittest.expectedFailure:如果test失败了,这个test不计入失败的case数目。

 下面以@unittest.skipUnless为例,通过@unittest.skipUnless来跳过执行某条测试用例。修改test_mathfunc.py文件,修改后的代码如下:

import unittest
from UnitTestDemo.mathfunc import *

class TestMathFunc(unittest.TestCase):
    """测试mathfunc.py"""

    def test_add(self):
        """测试加法add"""
        self.assertEqual(3, add(1, 2))
        self.assertNotEqual(3, add(2, 2))

    def test_minus(self):
        """测试减法minus"""
        self.assertEqual(1, minus(3, 2))

    def test_multi(self):
        """测试乘法multi"""
        self.assertEqual(6, multi(2, 3))

    def test_divide(self):
        """测试除法divide"""
        self.assertEqual(2, divide(6, 3))
        self.assertEqual(2.5, divide(5, 2))


未添加test_mathfunc.py添加@unittest.skipUnless前,运行结果如下:

添加了@unittest.skipUnless后,运行结果如下:

可以看到test_add()用例未被执行,被跳过了,这是由于@unittest.skipUnless(condition,reason):当condition为False(@unittest.skipUnless(1 > 2, "don't run the case!"))时跳过了用例。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值