自学Python+Selenium自动化测试

本文介绍了如何将Python的unittest框架融入到自动化测试中,包括unittest的好处、工作原理、框架拆分、脚本优化和项目结构。通过unittest,可以实现测试用例的组织、丰富的断言方法、日志和报告,以及测试用例的执行和管理。文章还探讨了unittest的测试用例类中的特殊方法、测试用例执行、断言、以及脚本优化,如测试结果优化和测试报告输出。
摘要由CSDN通过智能技术生成

        毛泽东说:“我一生最大的爱好是读书”,“饭可以一日不吃,觉可以一日不睡,书不可以一日不读”。

---毛泽东的读书学习生涯(上)

        学习是文明传承之途、人生成长之梯、政党巩固之基、国家兴盛之要。

---谈论学习也不行?


        退伍回来10个多月,奈何没有相关的软件测试工作经验和经历,而且毕业四五年没碰过了软件专业了,加之现在疫情的变化无常,报培训班时间不够自由,所以回来边恶补专业知识,边找相关工作。只能是四处碰壁,让我学习的欲望更加强烈。

        今天也恰巧看到CSDN话题挑战赛第2期中的《学习笔记》这个参赛话题很符合我,正好把我近期学习的(四)自动化测试-unittest框架简单总结一下,方便自己以后找出来看看。


CSDN话题挑战赛第2期

参赛话题:学习笔记


目    录

        一、前期脚本问题

        二、融入unittest框架

        1、unittest框架好处

        2、unittest框架工作原理

        三、unittest框架拆分介绍

        1、导入unittest包

        2、创建测试用例类

        3、测试用例类中的五种特殊方法(包含使用场景及执行顺序)

        4、创建测试用例

        5、测试用例执行

        6、断言

         7、python代码和运行结果

        四、脚本优化

        1、测试用例主执行文件

        2、测试结果优化

        3、测试报告输出---SMTP(未完结)

        五、项目结构(未完结)

        1、public

        2、test_cases

        3、test_datas

        4、test_reports

        5、test.py

        6、attachments

        7、confs


        一、前期脚本问题

        1、测试用例过多,只能单一执行,或者导包执行。

        2、断言方式简单且不实用,日志只能体现在控制台输出,无法体现在报告中。

        3、无法体现测试报告中的效果:测试用例数量、执行数量、通过数量、失败数量以及失败原因。


        二、融入unittest框架

        不仅仅是代码级别的功能测试、逻辑覆盖

        1、unittest框架好处

        (1)提供用例组织与执行

        (2)提供丰富的断言方法

        (3)提供丰富的日志和报告(HTML格式更直观展示)

        2、unittest框架工作原理

        (1)Fixture(固定件)

        TestCase:测试用例、脚本

        TestSuite:测试集合、套件、文件夹、统一管理多条测试用例

        TestRunner:测试运行器

        TestLoader:测试用例加载器

        TestRusult:测试结果、字典类型

        (2)单元测试代码段

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:bigbear
# datetime:2022/9/3 16:39
# software: PyCharm

"""
    单元测试:
        测试对象:类中的方法(函数)
"""


class MyMath:
    """定义运算函数:实现加减乘除算法"""

    @staticmethod
    def add(a, b):
        """加法"""
        # 测试问题:若a是字符串,b是整型,应该是字符串拼接运算
        if isinstance(a, str) and isinstance(b, int):
            b = str(b)
            return a + b
        else:
            return a + b

    @staticmethod
    def subtract(a, b):
        """减法"""
        return a - b

    @staticmethod
    def multiply(a, b):
        """乘法"""
        return a * b

    @staticmethod
    def divide(a, b):
        """除法"""
        if b == 0:
            return "除数不能是0,小学生都知道的啊"
        else:
            return a / b


if __name__ == '__main__':
    """单元测试-代码功能验证"""
    mm = MyMath()
    # 实现第一条加法测试用例
    actual_value = mm.add(1, 1)
    expect_value = 2
    if actual_value == expect_value:
        print("加法功能实现正确")

    # 实现第二条加法测试用例:can only concatenate str (not "int") to str
    try:
        actual_value = mm.add("a", 1)
        expect_value = "无法运算"
        if actual_value == expect_value:
            print("加法功能实现正确")
    except Exception as e:
        print(f"加法功能实现正确:{e}")

    # 实现第三条加法测试用例
    try:
        actual_value = mm.add("a", "b")
        expect_value = "ab"
        if actual_value == expect_value:
            print("加法功能实现正确")
    except Exception as e:
        print(f"加法功能实现正确:{e}")

        三、unittest框架拆分介绍

        1、导入unittest包

import unittest

        2、创建测试用例类

        继承单元测试框架的单元测试用例的类unittest.TestCase

class MyMathUnittest(unittest.TestCase):
    """继承单元测试框架的单元测试用例类"""

        3、测试用例类中的五种特殊方法(包含使用场景及执行顺序)

        setUp()、test_xxx()、tearDown()执行顺序与位置无关,且每执行一条测试用例,setUp()和tearDown()都会执行一次(无论该测试用例是否通过)。

        @classmethod注解的方法是类方法,不用创建对象也可以用的方法,在对象进入内存之前就已经存在的方法,随着类一起进内存。

        (1)setUp()  # 初始化、环境搭建

        (2)test_xxx()  # 测试用例方法、步骤

        (3)tearDown()  # 还原测试用例环境

        (4)@classmethod-setUpClass()  # 对当前测试用例类的所有测试用例进行初始化,只在类执行开始执行一次

        (5)@classmethod-tearDownClass()  # 对当前测试用例类的所有测试用例资源进行释放,只在类执行结束执行一次

import unittest

# from importlib import import_module
from my_math import MyMath


class MyMathUnittest(unittest.TestCase):
    """继承单元测试框架的单元测试用例类"""

    # 注解:给方法指定特殊含义
    @classmethod
    def setUpClass(cls) -> None:
        print("setUpClass方法")

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

    def setUp(self) -> None:
        """方法名固定、self参数不能少"""
        self.mm = MyMath()
        print("setUp方法")

    def test_add(self):
        """test_是测试用例:加法运算-正向"""
        add_value = self.mm.add(1, 1)
        # 断言方法,判断预期结果和实际结果是否相等
        # AssertionError: 2 != 3 : 预期和实际结果不相等
        self.assertEqual(add_value, 2, "预期和实际结果不相等")
        print("test_add方法")

    def tearDown(self) -> None:
        """方法名固定、self参数不能少"""
        print("tearDown方法")

        4、创建测试用例

        (1)test_开头

import unittest

from my_math import MyMath


class MyMathUnittest(unittest.TestCase):
    """继承单元测试框架的单元测试用例类"""

    def test_add(self):
        """test_是测试用例:加法运算-正向"""
        print("test_add方法")

    def test_add_1(self):
        """test_是测试用例:加法运算-反向"""
        add_value = self.mm.add("a", 1)
        self.assertNotEqual(add_value, "a1", "预期和实际结果不相等")
        print("test_add_0方法")

    def test_add_2(self):
        """test_是测试用例:加法运算-正向"""
        add_value = self.mm.add("a", "b")
        self.assertEqual(add_value, "ab", "预期和实际结果不相等")
        print("test_add_1方法")

        5、测试用例执行

        (1)main()执行方法

        unittest.main()  # 所有测试用例执行一遍,但无法控制执行顺序(默认按照字母顺序执行)

if __name__ == '__main__':
    """此文件运行时执行"""
    # 执行测试用例类中所有的测试用例
    unittest.main()

        (2)TestSuite()自带加载执行方法

        test_suite = unittest.TestSuite()  # 创建测试套件对象

        test_suite.addTest(类名("用例名"))  # 将一条测试用例添加到测试套件,可以多次添加,任意调换顺序即执行顺序

        test_suite.addTests([类名("用例名"),...])  # 将可迭代测试集(列表、字典)中的测试用例添加到测试套件,列表中任意调换顺序即执行顺序

        test_suite.addTests(map(类名, ["用例名",...]))  # 使用map()方法将类应用于用例返回列表

        test_suite.run(unittest.TestResult())  # 运行测试套件,并存储测试结果 

if __name__ == '__main__':
    """此文件运行时执行"""

    # addTest(类名("用例名")):将一条测试用例添加到测试套件,可以多次添加,任意调换顺序即执行顺序
    test_suite = unittest.TestSuite()
    # 在测试套件中添加一条测试用例
    test_suite.addTest(MyMathUnittest("test_add"))
    test_result = unittest.TestResult()
    test_suite.run(test_result)
    print(test_result.__dict__)
if __name__ == '__main__':
    """此文件运行时执行"""

    # addTests([类名("用例名"),...]):将可迭代测试集(列表、字典)中的测试用例添加到测试套件,列表中任意调换顺序即执行顺序
    test_suites = unittest.TestSuite()
    # 在测试套件中添加多条测试用例
    test_list = map(MyMathUnittest, ["test_add_2", "test_add_1", "test_add"])
    test_suites.addTests(test_list)
    test_results = unittest.TestResult()
    test_suites.run(test_results)
    print(test_results.__dict__)

        (3)TestLoader()特定加载方法

        test_loader = unittest.TestLoader()  # 创建测试用例加载器对象

        loader_suite = test_loader.loadTestsFromName("模块名")  # 将某模块中的所有测试用例加载到测试套件中

        loader_suite = test_loader.loadTestsFromName("模块名.类名")  # 将某模块中的某类中的的所有测试用例加载到测试套件中

        loader_suite = test_loader.loadTestsFromName(name="类名", module=import_module("模块名"))  # 将某模块中的某类中的的所有测试用例加载到测试套件中

        loader_suite = test_loader.loadTestsFromName("模块名.类名.测试用例名")  # 将某一条测试用例加载到测试套件中

        loader_suite = test_loader.loadTestsFromName(name="类名.测试用例名", module=import_module("模块名"))  # 将某一条测试用例加载到测试套件中

        # __import__(name):通过python解释器导入模块,非通用

        loader_suite = test_loader.loadTestsFromModule(__import__("模块名"))  # 将某模块中的所有测试用例加载到测试套件中

        # importlib.import_module(name):以编程方式导入模块

        loader_suite = test_loader.loadTestsFromModule(import_module("模块名"))  # 将某模块中的所有测试用例加载到测试套件中

        loader_suite = test_loader.discover("./模块目录", "模块名正则表达式.py")  # 将指定模块中的所有测试用例一次性加载

if __name__ == '__main__':
    """此文件运行时执行"""

    # 加载测试用例到测试套件中
    test_loader = unittest.TestLoader()


    # loadTestsFromName("模块名"):将某模块中的所有测试用例加载到测试套件中
    # loader_suite = test_loader.loadTestsFromName("unittest_frame")


    # loadTestsFromName("模块名.类名"):将某模块中的某类中的的所有测试用例加载到测试套件中
    # loader_suite = test_loader.loadTests
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值