软件测试-python-UnitTest-笔记

UnitTest

unittest是Python单元测试框架,类似于JUnit框架。

unittest中有4个重要的概念:test fixture, test case, test suite, test runner

Testcase:

一个TestCase的实例就是一个测试用例。什么是测试用例呢?就是一个完整的测试流程,包括测试前准备环境的搭建(setUp),执行测试代码 (run),以及测试后环境的还原(tearDown)。元测试(unit test)的本质也就在这里,一个测试用例是一个完整的测试单元,通过运行这个测试单元,可以对某一个问题进行验证。

Test suite:

多个测试用例集合在一起,就是TestSuite,而且TestSuite也可以嵌套TestSuite。

Test runner:

是来执行测试用例的,其中的run(test)会执行TestSuite/TestCase中的run(result)方法。

TestLoader:

是用来加载TestCase到TestSuite中的,其中有几个loadTestsFrom__()方法,就是从各个地方寻找TestCase,创建它们的实例,然后add到TestSuite中,再返回一个TestSuite实例。

Test fixture:

对一个测试用例环境的搭建和销毁,是一个fixture,通过覆盖 TestCase的setUp()和tearDown()方法来实现。这个有什么用呢?比如说在这个测试用例中需要访问数据库,那么可以在setUp() 中建立数据库连接以及进行一些初始化,在tearDown()中清除在数据库中产生的数据,然后关闭连接。注意tearDown的过程很重要,要为以后的 TestCase留下一个干净的环境。关于fixture,还有一个专门的库函数叫做fixtures,功能更加强大。

使用unittest编写python的单元测试代码,包括如下几个步骤:

1、编写一个python类,继承 unittest模块中的TestCase类,这就是一个测试类

2、在上面编写的测试类中定义测试方法(这个就是指的测试用例),每个方法的方法名要求以 test 打头,没有额外的参数。 在该测试方法中 调用被测试代码,校验测试结果,TestCase类中提供了很多标准的校验方法,如 最常见的assertEqual。

3、执行 unittest.main() ,该函数会负责运行测试,它会实例化所有TestCase的子类,并运行其中所有以test打头的方法。

用法

1.用import unittest导入unittest模块

2.定义一个继承自unittest.TestCase的测试用例类,如class xxx(unittest.TestCase):

3.定义setUp和tearDown,这两个方法与junit相同,即如果定义了则会在每个测试case执行前先执行setUp方法,执行完毕后执行tearDown方法。

4.定义测试用例,名字以test开头,unittest会自动将test开头的方法放入测试用例集中。

5.一个测试用例应该只测试一个方面,测试目的和测试内容应很明确。主要是调用assertEqual、assertRaises等断言方法判断程序执行结果和预期值是否相符。

6.调用unittest.main()启动测试

7.如果测试未通过,则会显示e,并给出具体的错误(此处为程序问题导致)。如果测试失败则显示为f,测试通过为.,如有多个testcase,则结果依次显示。

代码

import unittest

# class FirstTest(unittest.TestCase):
#
#     def test_1(self):
#         print("test_1")
#
#     def test_2(self):
#         print("test_2")
#
#
# if __name__ == '_main':
#     unittest.main()

#
# class NumbersTest(unittest.TestCase):
#
#     def test_even(self):
#         for i in range(0, 6):
#             with self.subTest(i=i):
#                 self.assertEqual(i % 2, 0)


# def setUpModule():
#     createConnection()
#
# def tearDownModule():
#     closeConnection()
#
# class Test(unittest.TestCase):
#     @classmethod
#     def setUpClass(cls):
#         cls._connection = createExpensiveConnectionObject()
#
#     @classmethod
#     def tearDownClass(cls):
#         cls._connection.destroy()

from selenium import webdriver
import time


class TestUnit1(unittest.TestCase):
    # 获取浏览器的驱动
    def setUp(self):
        # 1、self 就是类的引用/实例
        # 2、全局变量的定义:self.变量名
        self.driver = webdriver.Chrome()
        self.driver.maximize_window()
        self.url = "https://www.baidu.com"
        self.driver.get(self.url)
        time.sleep(3)

        # 在百度中搜索信息
        # 测试用例的命名: test_

    def test_search1(self):
        self.driver.find_element("id", "kw").send_keys("顾一野")
        self.driver.find_element("id", "su").click()
        time.sleep(6)

    def test_search2(self):
        self.driver.find_element("id", "kw").send_keys("account")
        self.driver.find_element("id", "su").click()
        time.sleep(6)

    # 关闭浏览器
    def tearDowm(self):
        self.driver.quit()

    # 一个入口
    if __name__ == "__main__":
        unittest.main()
import unittest


class TestCaseDemo(unittest.TestCase):
    def testassertdemo(self):
        self.assertIn(1, [1, 2, 3])
        self.assertNotIn(1, [2, 3, 4])
        self.assertEqual('1', '1')
        self.assertNotEqual(1, 2)
        self.assertTrue(2 == 2)

    def testassertdemo_1(self):
        self.assertDictEqual({"code": 1}, {"code": 1})
        self.assertListEqual([1, 2], [1, 2])
        self.assertMultiLineEqual("name", "name")

    def testassertdemo_2(self):
        self.assertGreater(2, 0)
        self.assertGreaterEqual(2, 0)
        self.assertNotRegex("1", "122")  # 正则是否匹配
        self.assertCountEqual("12", "12")


# 1、第一种方法,一条一条case加载用例
def suite():
    # 创建一个测试套件
    suite = unittest.TestSuite()
    # 将测试用例加载到测试套件中
    case1 = TestCaseDemo("testassertdemo")
    suite.addTest(case1)

    case2 = TestCaseDemo("testassertdemo_1")
    suite.addTest(case2)

    case3 = TestCaseDemo("testassertdemo_2")
    suite.addTest(case3)

    return suite


if __name__ == '__main__':
    runner = unittest.TextTestRunner()
    runner.run(suite())
unittest模块常用方法
assertEqual(a, b)     a == b

assertNotEqual(a, b)     a != b

assertTrue(x)     bool(x) is True

assertFalse(x)     bool(x) is False

assertIs(a, b)     a is b

assertIsNot(a, b)     a is not b

assertIsNone(x)     x is None

assertIsNotNone(x)     x is not None

assertIn(a, b)     a in b

assertNotIn(a, b)     a not in b

assertIsInstance(a, b)     isinstance(a, b)

assertNotIsInstance(a, b)     not isinstance(a, b)

skip方法

有时候,测试用例很多,有些需要执行,有些不想执行,那就需要跳过一些测试用例,这时候就需要用到skip,skip用法:

  1. 无条件跳过,unittest.skip(“xxx”)

  1. 条件为True跳过,unittest.skipIf(1 < 2, ‘xxx’)

  1. 条件为False跳过,unittest.skipUnless(1 > 2, ‘xxx’)

  1. 执行失败不计入case总数中,unittest.expectedFailure

代码

import unittest

class Mytest1(unittest.TestCase):
    def setUp(self) -> None:
        print("===== setUp =====")

    def tearDown(self) -> None:
        print("===== tearDown =====")

    @classmethod
    def setUpClass(cls) -> None:
        print("===== setUpClass =====")

    @classmethod
    def tearDownClass(cls) -> None:
        print("===== tearDownClass =====")

    @unittest.skip("直接跳过")
    def test_1(self):
        print("test_1")

    @unittest.skipIf(1<2,"条件为True则跳过")
    def test_2(self):
        print("test_2")

    @unittest.skipUnless(1<2,"条件为False则跳过")
    def test_3(self):
        print("test_3")

    @unittest.expectedFailure
    def test_4(self):
        print("test_4")
        self.assertEqual(4,5)

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

生成HTML测试报告

from unittest import TestSuite
from HtmlTestRunner import HTMLTestRunner

class Mytest1(unittest.TestCase):

    def test_1(self):
        print("test_1")

    def test_2(self):
        print("test_2")

    def test_3(self):
        print("test_3")

    def test_4(self):
        print("test_4")

if __name__ == "__main__":
    # 创建一个测试套件 suite
    suite = TestSuite()

    # 添加单个测试用例
    suite.addTest(Mytest1("test_3"))
    suite.addTest(Mytest1("test_1"))
    suite.addTest(Mytest1("test_2"))

    # 执行测试并输出html报告,output输出到xx目录下
    runner = HTMLTestRunner(output="result")
    runner.run(suite)

ddt模块

有时我们需要对大量的数据进行同一种逻辑函数测试,这时候可以用到ddt模块。

ddt,是一种 数据驱动测试 思想,数据和用例进行分离,通过外部数据去生成测试用例,可以快速的对大量数据和不同情况进行测试。

首先我们需要在python中安装ddt模块:pip install ddt。

数据引入的方式主要有以下几种:

  1. @data装饰器的方式

  1. json文件

  1. yaml文件

  1. 其他

data装饰器

import unittest
from ddt import ddt, data, unpack

# 先定义@ddt,用于表示要使用ddt了
@ddt
class Mytest1(unittest.TestCase):
    
    # data用于设定参数
    @data("a", "b", "c")
    def test_1(self, text):
        self.assertEqual("a", text)

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

json文件

先编写json文件

[
    {
        "name": "test",
        "age": 18
    },
    {
        "name": "test1",
        "age": 20
    }
]
import unittest
from ddt import ddt, file_data


@ddt
class Mytest1(unittest.TestCase):

    @file_data("/test.json")
    def test_1(self, **text):
        print(text)
        print(type(text))


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

yaml文件

先编写yaml文件

# "-"表示一个列表

-
  name: 'test1'
  age:  18

-
  name: 'test2'
  age:  20
import unittest
from ddt import ddt, file_data

@ddt
class Mytest1(unittest.TestCase):

    @file_data("/Users/tangliqi/Desktop/个人文档/json文件/test.yaml")
    def test_1(self, **text):
        print(text)
        print(type(text))


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

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值