自动化测试的基石-单元测试框架

单元测试的基础概念

测试用例

测试用例是为某个特殊目标而编制的一组测试输入、执行条件以及预期结果,以便测试某个程序路径或核实是否满足某个特定需求。

单元测试

  • 单元测试是应用程序的最小可测试部分
  • 在面向过程编程中, 单元也可以是整个模块, 但常见的是单个函数或过程
  • 在面向对象编程中, 单元通常是整个接口, 例如类, 但可以是单独的方法

单元测试框架

单元测试框架实现了如何通过代码编写自动化测试用例

  • 提供用例组织和执行
  • 提供丰富的断言方法
  • 提供丰富的日志

unitest单元测试框架

unitest简介

unittest是python集成的单元测试框架,我们不需要单独安装。围绕unittest单元测试框架有丰富扩展。例如 ddt, HTMLTestRunner 等。

unittest包含四个重要概念

  • Test Case
  • Test Suit
  • Test Fixture
  • Test Runner

unitest用法

用它编写基本的测试用例如下。

被测代码:

# 计算器类
class Calculator:
    """ 用于完成两个数的加减乘除 """

    def __init__(self, a, b):
        self.a = int(a)
        self.b = int(b)

    # 加法
    def add(self):
        return self.a + self.b

    # 减法
    def sub(self):
        return self.a - self.b

    # 乘法
    def mul(self):
        return self.a * self.b

    # 除法
    def div(self):
        return self.a / self.b

unittest编写测试用例:

import unittest
from calculator import Calculator

class TestCalculator(unittest.TestCase):

    def test_add(self):
        c = Calculator(3, 5)
        result = c.add()
        self.assertEqual(result, 8)

    def test_sub(self):
        c = Calculator(7, 2)
        result = c.sub()
        self.assertEqual(result, 5)

    def test_mul(self):
        c = Calculator(3, 3)
        result = c.mul()
        self.assertEqual(result, 10)

    def test_div(self):
        c = Calculator(6, 2)
        result = c.div()
        self.assertEqual(result, 3)


if __name__ == '__main__':
    unittest.main()

规则:

  • 创建的测试类必须集成unittest.TestCase

  • 测试方法必须以test开头。

unitest基础之fixture

Test Fixture简介

Test Fixture代表执行一个或多个测试所需的环境准备,以及关联的清理动作。例如,创建临时或代理数据库、目录或启动服务器进程。

unittest提供的fixture

setUp /tearDown
setUpClass/tearDownClass
setUpModule/tearDownModule

Test Fixture示例

import unittest

def setUpModule():
    print("test module start >>>>>>>>>>>>>>")

def tearDownModule():
    print("test module end >>>>>>>>>>>>>>")

class MyTest(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        print("test class start =======>")

    @classmethod
    def tearDownClass(cls):
        print("test class end  =======>")

    def setUp(self):
        print("test case start -->")

    def tearDown(self):
        print("test case end -->")

    def test_case1(self):
        print("test case1")

    def test_case2(self):
        print("test case2")


if __name__ == '__main__':
    unittest.main()

说明:

setUpModule/tearDownModule :在整个模块的开始与结束时被执行。
setUpClass/tearDownClass:在测试类的开始与结束时被执行。
setUp/tearDown :在测试用例的开始与结束时被执行。

unitest基础之断言

断言简介

在执行用例的过程中,最终用例执行的成功与否,是通过测试得到的实际结果与预期结果进行判断得到的。

断言方法:

assertEqual(a, b)
assertNotEqual(a, b)
assertTrue(x)
assertFalse(x)
assertIs(a, b)
assertIsNot(a, b)
assertIsNone(x)
assertIsNotNone(x)
assertIn(a, b)
assertNotIn(a, b)
assertIsInstance(a, b)
assertNotIsInstance(a, b)

断言示例

import unittest

class TestAssert(unittest.TestCase):

    def test_equal(self):
        self.assertEqual(2+2, 4)
        self.assertEqual("python", "python")
        self.assertNotEqual("hello", "python")

    def test_in(self):
        self.assertIn("hello", "hello world")
        self.assertNotIn("hi", "hello")

    def test_true(self):
        self.assertTrue(True)
        self.assertFalse(False)


if __name__ == '__main__':
    unittest.main()

unitest基础之测试运行

Test Runner简介

Test Runner是一个组件,它用于协调测试的执行并向用户提供结果。Test Runner可以使用图形界面,文本界面或返回特殊值来展示执行测试的结果。

在unittest中运行测试用例有三种方法

方法一

import unittest

……

# 使用main()方法
unittest.main()

方法二

import unittest

……

# 创建测试套件
suit = unittest.TestSuite()
suit.addTest(TestCalculator("test_add"))
suit.addTest(TestCalculator("test_sub"))
suit.addTest(TestCalculator("test_mul"))
suit.addTest(TestCalculator("test_div"))

# 创建测试运行器
runner = unittest.TextTestRunner()
runner.run(suit)

方法三:

import unittest

# 定义测试用例的目录为当前目录中test_case/目录
test_dir = './test_case'
suits = unittest.defaultTestLoader.discover(test_dir, pattern='test*.py')

if __name__ == '__main__':
    runner = unittest.TextTestRunner()
    runner.run(suits)

单元测试框架之nose2

nose

nose是python的一个第三方单元测试框架。用它来编写测试用例更加简单,而且它可以直接运行unittest单元测试框架编写的用例。
目前该项目已经停止维护。

nose2

nose2是一个新项目,不支持nose的所有功能。

nose2的目的是扩展unittest,使测试变得更好、更容易理解。

github: https://github.com/nose-devs/nose2

安装:

pip install nose2

例子:

1、运行unittest测试用例

# in test_simple.py
import unittest

class TestStrings(unittest.TestCase):
    def test_upper(self):
        self.assertEqual("spam".upper(), "SPAM")

执行

$ nose2 -v
test_upper (test_simple.TestStrings) ... ok

----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

2、参数化

# in test_fancy.py
from nose2.tools import params

@params("Sir Bedevere", "Miss Islington", "Duck")
def test_is_knight(value):
    assert value.startswith('Sir')

单元测试框架之pytest

pytest简介

pytest是python第三方单元测试框架。它本身功能非常强大,而且提供丰富的扩展。目前得到广泛的应用。

github:https://github.com/pytest-dev/pytest

安装

pip install pytest

pytest示例

# content of test_sample.py
def inc(x):
    return x + 1


def test_answer():
    assert inc(3) == 5

运行

$ pytest
============================= test session starts =============================
collected 1 items

test_sample.py F

================================== FAILURES ===================================
_________________________________ test_answer _________________________________

    def test_answer():
>       assert inc(3) == 5
E       assert 4 == 5
E        +  where 4 = inc(3)

test_sample.py:5: AssertionError
========================== 1 failed in 0.04 seconds ===========================

  

 

posted @ 2019-12-28 16:52  0bug  阅读(455)  评论(0编辑  收藏  举报