[QA]单元测试

Reference:
廖雪峰-单元测试

单元测试主要用来对一个方法、一个类或者一个模块进行检查的。基于测试驱动开发(TDD)的思想,为了让编写的某个模块的代码能够通过提前写好的测试代码。
单元测试可考虑的级别https://www.zhihu.com/question/27313846/answer/120164282

我给自己的单元测试设置了5个级别:

  1. Level1:正常流程可用,即一个函数在输入正确的参数时,会有正确的输出
  2. Level2:异常流程可抛出逻辑异常,即输入参数有误时,不能抛出系统异常,而是用自己定义的逻辑异常通知上层调用代码其错误之处
  3. Level3:极端情况和边界数据可用,对输入参数的边界情况也要单独测试,确保输出是正确有效的
  4. Level4:所有分支、循环的逻辑走通,不能有任何流程是测试不到的
  5. Level5:输出数据的所有字段验证,对有复杂数据结构的输出,确保每个字段都是正确的

unittest

官方文档地址:https://docs.python.org/zh-cn/3/library/unittest.html#module-unittest
先来看一下unittest的工作原理:Python必会的单元测试框架 —— unittest
总结一下原理:
写好TestCase,然后由TestLoader加载TestCase到TestSuite,然后由TextTestRunner来运行TestSuite,运行的结果保存在TextTestResult中,我们通过命令行或者unittest.main()执行时,main会调用TextTestRunner中的run来执行,或者我们可以直接通过TextTestRunner来执行用例。这里加个说明,在Runner执行时,默认将执行结果输出到控制台,我们可以设置其输出到文件,在文件中查看结果

unittest使用步骤:
1.创建一个测试用例类继承unittest.TestCase类
2.测试方法名称以test开头,在测试方法内调用方法对预期输出和实际输出进行比较,方法包括不限于assertEqual(),assertTrue(),assertFalse(),assertRaises()。测试方法的执行顺序是按test后字母的顺序执行的。
3.使用unittest.main()来运行测试脚本,也可以通过在命令行使用python -m unittest 测试文件名.测试用例类名的方式进行调用,如下代码,我们使用python -m unittest -v testmodel.MyUnittest进行调用(其中-v可以直观的表现出每一个方法测试时的运行)

import unittest
class MyUnittest(unittest.TestCase):
    def test_upper(self):
        return self.assertEqual('foo'.upper(),'FOO')

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

高阶:

  • 如果需要每个用例开始或者结束之前都调用一次,用setUp()和tearDown()方法,这种用于的场景是:例如在UI自动化测试时,前置是需要打开浏览器,完成测试的操作后再把浏览器关闭?(实际上我觉得这种场景应该是用setUpClass...)
import unittest
class MyUnittest(unittest.TestCase):
    def setUp(self):
        print('preparing condition')
    def tearDown(self):
        print('test down')
    def test_upper(self):
        return self.assertEqual('foo'.upper(),'FOO')
    def test_lower(self):
        return self.assertEqual('FOO'.lower(),'foo')
if __name__ == '__main__':
    unittest.main()

但是如果想要在整个测试类进行测试之前准备或释放环境资源,那么可以用@classmethod装饰器在setUpClass和tearDownClass前面。可以看这个博客的用法selenium中的setUp,tearDown与setUpClass,tearDownClass的区别及用例编写相关注意点 这个博客也提到了,在这种场景下,需要注意的是用例之间的耦合,不要让前一个用例的状态影响到了下一个用例。

  • skip装饰器
    包括三种,unittest.skip()、unittest.skipIf()、unittest.skipUnless(),下面是官方文档的一个例子:
class MyTestCase(unittest.TestCase):

    @unittest.skip("demonstrating skipping")
    def test_nothing(self):
        self.fail("shouldn't happen")

    @unittest.skipIf(mylib.__version__ < (1, 3),
                     "not supported in this library version")
    def test_format(self):
        # Tests that work for only a certain version of the library.
        pass

    @unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
    def test_windows_support(self):
        # windows specific testing code
        pass

    def test_maybe_skipped(self):
        if not external_resource_available():
            self.skipTest("external resource not available")
        # test code that depends on the external resource
        pass

此外,也可以用expectedFailure()装饰器表明这个测试预计失败。

  • subTest()
    Reference:单元测试框架之unittest上下文管理器subTest()
    当在循环中判断时,如果判断结果不符合,我们的测试用例会直接停在当前fail的位置,使用subTest()可以让所有的输入都至少过一遍断言。

  • TestSuite指定测试方法的顺序
    Python单元测试(一)--Unittest

你可能感兴趣的:([QA]单元测试)