自动化测试的基石-单元测试框架
单元测试的基础概念
测试用例
测试用例是为某个特殊目标而编制的一组测试输入、执行条件以及预期结果,以便测试某个程序路径或核实是否满足某个特定需求。
单元测试
- 单元测试是应用程序的最小可测试部分
- 在面向过程编程中, 单元也可以是整个模块, 但常见的是单个函数或过程
- 在面向对象编程中, 单元通常是整个接口, 例如类, 但可以是单独的方法
单元测试框架
单元测试框架实现了如何通过代码编写自动化测试用例
- 提供用例组织和执行
- 提供丰富的断言方法
- 提供丰富的日志
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
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 ===========================

浙公网安备 33010602011771号