Python + UnitTest 软件测试流程总结

以测试用户登录流程为例:

TestCase:

TestCase 主要用来编写测试用例,这里结合 **断言(assertEqual 和 assertIn)**进行判断,避免了手动书写判断。

python 复制代码
# tools.py
# 登录验证方法
def login(username, password):
    if username == 'admin' and password == '123456':
        return '登录成功'
    else:
        return '登录失败'
python 复制代码
# TestCase.py
# 导入 unittest
import unittest
from tools import login


class TestLogin(unittest.TestCase):
    def test_username_password_ok(self):
        self.assertEqual('登录成功', login('admin', '123456'))

    def test_username_error(self):
        self.assertEqual('登录失败', login('root', '123456'))

    def test_password_error(self):
        self.assertEqual('登录失败', login('admin', '123123'))

    def test_username_password_error(self):
        # self.assertEqual('登录失败', login('root', '123123'))
        self.assertIn('失败', login('aaa', '123123')) # 结果中包含"失败"即可

TestSuite:

TestSuite 用来管理多个 TestCase 文件,使用 unittest.TestSuite() 实例化套件对象,再使用套件对象添加用例方法。

假如创建多个 TestCase 文件:

python 复制代码
# testCase1.py
# 导包
import unittest

# 自定义测试类,继承 unittest 类中 testCase 类
class testDemo1(unittest.TestCase):
    # 测试方法(用例代码)
    def method1(self):
        print('测试方法1-1')

    def method2(self):
        print('测试方法1-2')
python 复制代码
# testCase2.py
# 导包
import unittest

# 自定义测试类,继承 unittest 类中 testCase 类
class testDemo2(unittest.TestCase):
    # 测试方法(用例代码)
    def method1(self):
        print('测试方法2-1')

    def method2(self):
        print('测试方法2-2')

TestRunner:

用来执行对象。

python 复制代码
# TestSuite_Runner.py
# TestSuite用来管理多个TestCase文件
# 1.导包
import unittest
# 2.实例化(创建对象)套件对象
from testCase1 import testDemo1
from testCase2 import testDemo2
from TestCase import TestLogin

suite = unittest.TestSuite()
# 3.使用套件对象添加用例方法
# 方法一:套件对象.addTest(测试类名('方法名'))
suite.addTest(testDemo1('method1'))
suite.addTest(testDemo1('method2'))
suite.addTest(testDemo2('method1'))
suite.addTest(testDemo2('method2'))

# 方法二:将一个测试类中的所有方法进行添加
# 套件对象.addTest(unittest.makeSuite(测试类名))
suite.addTest(unittest.makeSuite(testDemo1))
suite.addTest(unittest.makeSuite(testDemo2))
suite.addTest(unittest.makeSuite(TestLogin))

# 4.实例化运行对象
runner = unittest.TextTestRunner()

# 5.使用运行对象去执行套件对象
# 运行对象.run(套件对象)
runner.run(suite)

TestLoader:

用于多个 TestCase 中有多个 Method 时,写法较简便

python 复制代码
# TestLoader.py
# 1.导包
import unittest

# 2.实例化加载对象并添加用例
# unittest.TestLoader().discover('用例所在的路径', '用例的代码文件名')
suite = unittest.TestLoader().discover('./case', '*.py')
# suite = unittest.defaultTestLoader().discover('./case', '*.py') 两种写法

# 将3.4.合并
unittest.TextTestRunner().run(suite)

TestFixture:

在执行每个测试方法的前后会出现一些重复操作,可以使用 TestFixture 进行书写。

python 复制代码
# TestFixture.py
import unittest

class TestLogin(unittest.TestCase):
    # 1.打开浏览器(整个测试过程中就打开一次浏览器) 类级别
    @classmethod
    def setUpClass(cls) -> None:
        print('打开浏览器')

    # 2.输入网址(每个测试方法都需要一次) 方法级别
    def setUp(self):
        # 每个测试方法执行之前都会调用的方法
        print('输入网址')

    # 3.输入用户名密码验证码点击登录(不同的测试数据) 测试方法
    def test_1(self):
        print('输入正确信息,点击登录1')

    def test_2(self):
        print('输入错误信息,点击登录2')

    # 4.关闭当前页面(每个测试方法都需要一次) 方法级别
    def tearDown(self):
        # 每个测试方法执行之后都会调用的方法
        print('关闭当前页面')

    # 5.关闭浏览器(整个测试过程中就关闭一次浏览器) 类级别
    @classmethod
    def tearDownClass(cls) -> None:
        print('关闭浏览器')

Skip:

不想执行某个测试用例时,可以进行直接跳过(skip)或者条件触发(skipIf)跳过。

python 复制代码
# skip.py
# 导包
import unittest

version = 30

# 自定义测试类
class testDemo(unittest.TestCase):
    # 测试方法
    @unittest.skip('直接跳过')
    def test_method1(self):
        print('测试方法111')

    @unittest.skipIf(version >= 30, '版本高跳过测试')
    def test_method2(self):
        print('测试方法222')

    def test_method3(self):
        print('测试方法333')
# 执行用例(方法)

Parameterized:

在实际开发中,测试用例的数据不能写死,这时用到json文件的读取,之后利用 parameterized 对读取函数进行调用。

首先执行 pip install parameterized 下载;

之后在模块中导入 from parameterized import parameterized

python 复制代码
# 导入unittest/parameterized
import json
import unittest
from parameterized import parameterized
from tools import login


# 组织测试数据
def build_data():
    with open('data.json', encoding='utf-8') as f:
        result = json.load(f)
        data = []
        for info in result:
            data.append((info.get('username'), info.get('password'), info.get('expect')))
    return data

# 定义测试类
class TestLogin(unittest.TestCase):
    # 书写测试方法(用到的测试数据使用变量代替)
    @parameterized.expand(build_data())
    def test_login(self, username, password, expect):
        self.assertEqual(expect, login(username, password))

这里的 data.json:

python 复制代码
[
  {
    "desc": "正确用户名密码",
    "username": "admin",
    "password": "123456",
    "expect":"登录成功"
  },
  {
    "desc": "错误用户名",
    "username": "root",
    "password": "123456",
    "expect":"登录失败"
  },
  {
    "desc": "错误密码",
    "username": "admin",
    "password": "123123",
    "expect":"登录失败"
  }
]

在此过程中会生成测试报告,在终端中执行代码后,按照以下步骤可以进行查看:

运行html文件即可,效果如图:

这样生成的测试报告相对简陋,可以使用第三方库生成,在当前目录中放入顶部的两个文件。

接下来书写以下代码:

python 复制代码
# 利用第三方生成测试报告
# 中文版
# 1.获取第三方的 测试运行类模块,将其放在代码的目录中
# 2.导包 unittest
import unittest
from HTMLTestRunnerCN import HTMLTestReportCN

# 3.使用 套件对象,加载对象 去添加用例方法
suite = unittest.defaultTestLoader.discover('.', 'pa*login.py')
# 4.实例化 第三方的运行对象
file = 'report_cn.html'
with open(file, 'wb') as f:
    # 运行对象(第二个参数是:是否详细 1/2,第三个参数是报告标题,第三个参数是python/pycharm版本)
    runner = HTMLTestReportCN(f, 2, '测试报告中文版', 'python 3.6.7')
    # 5.运行 套件对象
    runner.run(suite)

# --------------------上下两端代码不要一起执行------------------------

# 1.获取第三方的 测试运行类模块,将其放在代码的目录中
# 2.导包 unittest
import unittest
# 英文版
from HTMLTestRunner import HTMLTestRunner

# 3.使用 套件对象,加载对象 去添加用例方法
suite = unittest.defaultTestLoader.discover('.', 'pa*login.py')
# 4.实例化 第三方的运行对象
file = 'report.html'
with open(file, 'wb') as f:
    # 运行对象
    runner = HTMLTestRunner(f, 1, '测试报告', 'python 3.6.8')
    # 5.运行 套件对象
    runner.run(suite)

效果如下:

相关推荐
waterHBO28 分钟前
python 爬虫 selenium 笔记
爬虫·python·selenium
编程零零七1 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
2401_858286112 小时前
52.【C语言】 字符函数和字符串函数(strcat函数)
c语言·开发语言
铁松溜达py2 小时前
编译器/工具链环境:GCC vs LLVM/Clang,MSVCRT vs UCRT
开发语言·网络
everyStudy2 小时前
JavaScript如何判断输入的是空格
开发语言·javascript·ecmascript
AIAdvocate3 小时前
Pandas_数据结构详解
数据结构·python·pandas
小言从不摸鱼3 小时前
【AI大模型】ChatGPT模型原理介绍(下)
人工智能·python·深度学习·机器学习·自然语言处理·chatgpt
C-SDN花园GGbond4 小时前
【探索数据结构与算法】插入排序:原理、实现与分析(图文详解)
c语言·开发语言·数据结构·排序算法
迷迭所归处5 小时前
C++ —— 关于vector
开发语言·c++·算法
架构文摘JGWZ5 小时前
Java 23 的12 个新特性!!
java·开发语言·学习