1 简介
python测试类似JUnit,包含测试用例(TestCase)、套件(TestSuite)和TextTestRunner。测试方法以test_
开头。例如:
```python
import unittest
class TestIntegerArithmetic(unittest.TestCase):
def test_add(self):
self.assertEqual(1 + 2, 3)
def test_multiply(self):
self.assert
测试用例可以通过setUp
和tearDown
方法准备和清理环境。
通过unittest.main()
运行测试,
命令行接口如python -m unittest [options] tests
。
探索性测试使用discover
,信号处理允许捕获中断。unittest提供全面功能,Go更注重并发性能。
2 经典方式:Py的测试
Python的内建框架名为unittest,它非常适合测试具有相当线性控制流的代码。
基本上是按面向对象的编程方式一步一步的假设和拆除套件。
组织方式简介
py内置测试包为 unittest, 测试套件与 go 的xUnit 级别层次类似,测试包,测试模块,测试类(包括测试套件设置),测试用例。
它基于 JUnit的启发。 这个模块包含的核心框架类支持 测试用例和套件的基础架构 例如 TestCase TestSuite。
并且提供运行测试和基于文本类的执行报告(TextTestRunner) 。一个最基础的例子,用例始终以test 开头
#//test_module import unittest class IntegerArithmeticTestCase(unittest.TestCase): def testAdd(self): self.assertEqual((1 + 2), 3) self.assertEqual(0 + 1, 1) def testMultiply(self): self.assertEqual((0 * 10), 0) self.assertEqual((5 * 8), 40) if __name__ == '__main__': unittest.main()
只要在 main 函数中声明了unittest.main(),这将被解析为测试模块,以下方式 执行它
python -m unittest test_module
3 实例:测试脚手架和套件
脚手架
对应每个级别都可用有设置不同层次的套件,例如下,设置fixture,可以称之为脚手架,
在setup中 从环境中读取ip信息,以便在执行用例时做为全局的信息依据。并在此时获得日志处理对象logger:
class TestCase(unittest.TestCase):
def __init__(self, method_name): unittest.TestCase.__init__(self, method_name) def setUp(self): self.ip = os.getenv('ip') self.logger = logger def tearDown(self): self.logger.info("===== Teardown Section of %s =====" % self.__class__.__name__)
- 测试套件处理
这里只有简单的 成功和失败两类,如果case有更多共性,比如校验名称长度,也可以在这里做为套件处理。
class RpcTest(TestCase): def successTest(self, rpc, method='POST', jsons=None): resp = rpc.Request( jsons, method) if resp['message'] != 'true': self.assertEqual(resp['message'], True, msg=(resp, True)) else: self.assertEqual(resp['message'], 'true', msg=(resp, 'true')) return resp
def failTest(self, rpc, params, errorCode, errorMessage=None, jsons=None, method='POST'):
resp = rpc.Request(params=params, jsons=jsons, method=method)
if resp['code'] != errorCode:
self.assertEqual(resp['code'], errorCode, msg=(resp, errorCode))
else:
self.assertEqual(resp['code'], errorCode)
return resp
def nameScopeTest(...):
...
用例设置
在具体用例中执行套件设置时,比如开始时清理环境,DB信息设置等等。 比如在结束后清理环境,还原DB,环境信息等等。
并且其内部包,在某些特殊的场景,比如环境所属地址ip 为内部环境,不需要执行失败的校验,则可选择跳过。
class RpcBaseTest(RpcTest):
scope = 'rpc' scopeIp = self.ip condition = self.CheckScope(self.ip) @classmethod def setUpClass(cls): cls.successCode = 200 self.logger.info("test setup") def testPing(self): self.SuccessTest(...) @unittest.skipIf(condition=condition, reason=scopeIp) def testPingFail(self): self.FailTest(...) @classmethod def setTearDown(cls): cls.ClearDB() self.logger.info("test tear down")
相对而言,因为py发展历史长久充分,单测包 提供的功能比较全面。 go 的功能稍微差一些,但是在性能校验中有更多支持。
执行的命令行接口指令类似于 go
python -m unittest
python -m unittest test_module1 test_module2
python -m unittest test_module.TestClass
python -m unittest test_module.TestClass.test_method更多的功能包括探索性测试和信号处理。
探索性测试
在 TestLoader.discover() 中实现,但也可以通过命令行使用。它在命令行中的基本用法如下:cd project_directory
python -m unittest discover信号处理 它提供了捕获中断行为(control-C)时的选项。
因此允许测试继续并报告结果,但是多次中断将退出执行。python -m unittest -c/--catch
该命令行选项。 它提供了测试运行期间处理 control-C 的更友好方式。
4 小结
综上,在python中 单元测试 unittest是一种经典的实现方式。
而go更注重并发性能的调试,也是其优点。
在py中unittest包括以下主要信息:
1 脚手架:test fixture
test fixture 表示为了开展一项或多项测试所需要进行的准备工作脚手架,以及所有相关的清理操作。 举个例子,这可能包含创建临时或代理的数据库、目录,再或者启动一个服务器进程。
2 用例:test case
一个测试用例是一个独立的测试单元。它检查输入特定的数据时的响应。 unittest 提供一个基类: TestCase ,用于新建测试用例。
3 套件:test suite
test suite 是一系列的测试用例,或测试套件,或两者皆有。它用于归档需要一起执行的测试。 诸如: setUp(),tearDown(), setUpClasee(), tearDownClass(). setUpModule(), tearDownModule()
4 执行器:test runner
test runner 是一个用于执行和输出测试结果的组件。这个运行器可能使用图形接口、文本接口,或返回一个特定的值表示运行测试的结果。