本文大纲截图:

【Web UI自动化测试】Web UI自动化测试之框架篇(全网最全)

【Web UI自动化测试】Web UI自动化测试之框架篇(全网最全)

框架: 框架英文单词 framework,为解决一类事情的功能的集合。需要按照框架的规定(套路)去书写代码。

一、UnitTest框架介绍【文末分享自动化测试学习资源】

1、什么是UnitTest框架?

2、为什么使用UnitTest框架?

3、UnitTest框架核心组成要素

1)TestCase【最核心的模块】

2)TestSuite

3)TestRunner

4)TestLoader

5)Fixture

4、UnitTest框架实践

4.1 TestCase(测试用例)

介绍:

注意:

步骤:

代码:

# 1、导包
import unittest
# 2、新建测试类,需要继承 unittest 模块中的 TestCase类 即可
class TestDemo1(unittest.TestCase):
    # 3、书写测试方法(即 用例代码,目前没有真正的用例代码,使用 print 代替)
    # 注意:书写要求;测试方法 必须以 test_ 开头(本质以 test 开头)
    def test_method1(self):
        print("测试方法1")
    def test_method2(self):
        print("测试方法2")
class TestDemo2(unittest.TestCase):
    def test_method3(self):
        print("测试方法3")
    def test_method4(self):
        print("测试方法4")
# 4、执行用例(方法)
# 4.1 将光标放在 类名后边 运行,会执行类中的 所有测试方法
# 4.2 将光标放在 方法名后边 运行,只执行当前的方法

4.2 TestSuite & TestRunner(测试套件&运行)

介绍:

步骤:

实例化套件对象并添加测试用例:

# 导包
import unittest
from UnitTest_study.hm01_unittest import TestDemo
# 实例化套件对象
suite = unittest.TestSuite()
# 方法1:单个添加测试用例(需要导包TestDemo)
suite.addTest(TestDemo('test_001'))
suite.addTest(TestDemo('test_002'))
# 方法2:批量添加测试用例(需要导包TestDemo)
suite.addTest(unittest.makeSuite(TestDemo))

实例化运行对象:

# 导包
import unittest
# 实例化运行对象
runner = unittest.TextTestRunner()
# 运行测试套件
runner.run(suite)

查看测试执行结果的方法:

【Web UI自动化测试】Web UI自动化测试之框架篇(全网最全)

代码:

方法一:使用套件对象单个(单个方法)添加用例并运行

# 1、导包
import unittest
from unittest_testcase import TestDemo1, TestDemo2
# 2、实例化套件对象(创建套件对象)
suite = unittest.TestSuite()
# 3、使用套件对象 添加 用例方法
suite.addTest(TestDemo1('test_method1'))
suite.addTest(TestDemo1('test_method2'))
suite.addTest(TestDemo2('test_method1'))
suite.addTest(TestDemo2('test_method2'))
# 4、实例化运行对象(创建运行对象)
runner = unittest.TextTestRunner()
# 5、使用运行对象 去执行 套件对象
# 格式:运行对象.run(套件对象)
runner.run(suite)

方法二:使用套件对象批量(单个类)添加用例并运行

# 1、导包
import unittest
from unittest_testcase import TestDemo1, TestDemo2
# 2、实例化套件对象(创建套件对象)
suite = unittest.TestSuite()
# 3、使用套件对象 添加 用例方法
suite.addTest(unittest.makeSuite(TestDemo1))
suite.addTest(unittest.makeSuite(TestDemo2))
# 4、实例化运行对象(创建运行对象)
runner = unittest.TextTestRunner()
# 5、使用运行对象 去执行 套件对象
# 格式:运行对象.run(套件对象)
runner.run(suite)

4.3 TestLoader(测试加载)

介绍: TestLoader(测试加载),和 TestSuite 的作用一样,是对 TestSuite 功能的补充,用来管理组装(打包)多个 TestCase。在一个项目中 TestCase(测试用例)的代码,一般放在一个单独的目录(case)中

步骤

代码:

# 导包
import unittest
# 方法1:实例化对象并添加测试用例
suite = unittest.TestLoader().discover('case', 'test_*.py')
# 方法2:实例化对象并添加测试用例(说明:插件代码中有一句:defaultTestLoader = TestLoader(),所以有了方法2)
suite = unittest.defaultTestLoader.discover('case', 'test_*.py')
# 运行测试套件
unittest.TextTestRunner().run(suite)

4.4 Fixture(测试夹具)

介绍: Fixture(测试夹具)是一个代码结构,书写在 TestCase代码中,可以在每个方法执行前后都会执行的内容(在某些特定情况下会自动执行)。Fixture是一个概述,对一个测试用例环境的初始化和销毁就是一个Fixture。

Fixture控制级别: 方法级别、类级别、模块级别

方法级别【掌握】

class TestDemo(object):
    """测试示例类"""
    def setUp(self):
        """每个方法执行之前都会执行"""
        print("方法 -> 开始")
    def tearDown(self):
        """每个方法执行之后都会执行"""
        print("方法 -> 结束")

类级别【掌握】

class TestDemo(object):
    """测试示例类"""
    @classmethod
    def setUpClass(cls):
        """每个方法执行之前都会执行"""
        print("类 -> 开始")
    @classmethod
    def tearDownClass(cls):
        """每个方法执行之后都会执行"""
        print("类 -> 结束")

模块级别【了解】

# 模块级别的需要写在类的外边,直接定义函数即可
def setUpModule(self):
    """每个方法执行之前都会执行"""
    print("模块 -> 开始")
def tearDownModule(self):
    """每个方法执行之后都会执行"""
    print("模块 -> 结束")
class TestDemo(object):
    """测试示例类"""

代码:

import unittest
class TestLogin(unittest.TestCase):
    def setUp(self) -> None:
        """每个测试方法执行之前都会先调用的方法"""
        print('输入网址...')
    def tearDown(self) -> None:
        """每个测试方法执行之后都会调用的方法"""
        print('关闭当前页面...')
    @classmethod
    def setUpClass(cls) -> None:
        print('1、打开浏览器...')
    @classmethod
    def tearDownClass(cls) -> None:
        print('...5、关闭浏览器')
    def test_01(self):
        print('输入正确用户名密码验证码,点击登录')
    def test_02(self):
        print('输入错误用户名密码验证码,点击登录')

4.5 跳过

介绍:

代码:

import unittest
# version = 30
version = 29
class TestDemo(unittest.TestCase):
    @unittest.skip('没有什么原因,就是不想执行')
    def test_01(self):
        print('测试方法01')
    @unittest.skipIf(version >= 30, '版本大于 30,不用测试')
    def test_02(self):
        print('测试方法02')
    def test_03(self):
        print('测试方法03')

4.6 断言

介绍:

UnitTest断言方法:

【Web UI自动化测试】Web UI自动化测试之框架篇(全网最全)

self.assertEqual(预期结果, 实际结果)

self.assertIn(预期结果, 实际结果)

代码:

import unittest
from UnitTest_study.hm07_login import login
class TestLogin(unittest.TestCase):
    def test_uername_password_ok(self):
        """正确用户名和密码:admin,123456,登录成功"""
        self.assertEqual('登录成功', login('admin', '123456'))

4.7 参数化

介绍:

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

代码示例1:

import unittest
from parameterized import parameterized
from UnitTest_study.hm07_login import login
# 组织测试数据 [(), (), ()]
data = [
    ('admin', '123456', '登录成功'),
    ('root', '123456', '登录失败'),
    ('admin', '123123', '登录失败')
]
# 定义测试类
class TestLogin(unittest.TestCase):
    # 书写测试方法(用到的测试数据使用变量代替)
    # 组织测试数据并传参(装饰器 @)
    @parameterized.expand(data)
    def test_login(self, username, password, expect):
        """正确用户名和密码:admin,123456,登录成功"""
        self.assertEqual(expect, login(username, password))

代码示例2:

测试数据文件: data.json

【Web UI自动化测试】Web UI自动化测试之框架篇(全网最全)

代码:

import json
import unittest
from parameterized import parameterized
from UnitTest_study.hm07_login import login
# 组织测试数据 [(), (), ()]
def build_data():
    with open('data.json', encoding='utf-8') as f:
        result = json.load(f)  # [{}, {}, {}]
        data = []
        for i in result:  # i -> {}
            data.append((i.get('username'), i.get('password'), i.get('expect')))  # [(), (), ()]
    return data
# 定义测试类
class TestLogin(unittest.TestCase):
    # 书写测试方法(用到的测试数据使用变量代替)
    # 组织测试数据并传参(装饰器 @)
    @parameterized.expand(build_data())
    def test_login(self, username, password, expect):
        """正确用户名和密码:admin,123456,登录成功"""
        self.assertEqual(expect, login(username, password))

4.8 测试报告插件

自带的测试报告:

只有单独运行 TestCase 的代码时,才会生成测试报告;位置在控制台左侧区域的右上角

【Web UI自动化测试】Web UI自动化测试之框架篇(全网最全)

第三方测试报告:

HTMLTestRunner 插件:

# 导包
import unittest
from UnitTest_study.HTMLTestRunner import HTMLTestRunner
suite = unittest.defaultTestLoader.discover('.', 'hm08_parameterized1.py')
file = 'report.html'
with open(file, 'wb') as f:
    runner = HTMLTestRunner(f, 2, '测试报告', 'python 3.7')
    runner.run(suite)
# 导包
import unittest
from UnitTest_study.HTMLTestRunnerCN import HTMLTestReportCN
suite = unittest.defaultTestLoader.discover('.', 'hm08_parameterized1.py')
with open('report_CN.html', 'wb') as f:
    HTMLTestReportCN(f).run(suite)

4.9 总结

1)TestCase(测试用例):组织用例文件(TestCase)里面,书写 跳过、断言、参数化,使用Fixture夹具;单个测试文件直接运行,可以得到测试报告;有多个测试文件运行,则需要组装运行生成测试报告。

2、添加测试用例 到 测试套件中

# 导包
import unittest
from UnitTest_study.hm01_unittest import TestDemo
# 实例化套件对象
suite = unittest.TestSuite()
# 方法1:单个添加测试用例(需要导包TestDemo)
suite.addTest(TestDemo('test_001'))
suite.addTest(TestDemo('test_002'))
# 方法2:批量添加测试用例(需要导包TestDemo)
suite.addTest(unittest.makeSuite(TestDemo))
# 导包
import unittest
# 方法1:实例化对象并添加测试用例
suite = unittest.TestLoader().discover('case', 'hm*.py')
#  方法2:实例化对象并添加测试用例
suite = unittest.defaultTestLoader.discover('case', 'hm*.py')
# 运行测试套件
unittest.TextTestRunner().run(suite)

3、实例化运行对象 运行 测试条件

# 导包
import unittest
# 实例化运行对象
runner = unittest.TextTestRunner()
# 运行测试套件
runner.run(suite)
import unittest
from UnitTest_study.HTMLTestRunner import HTMLTestRunner
suite = unittest.defaultTestLoader.discover('.', 'hm08_parameterized1.py')
file = 'report.html'
with open(file, 'wb') as f:
    runner = HTMLTestRunner(f, 2, '测试报告', 'python 3.7')
    runner.run(suite)
import unittest
from UnitTest_study.HTMLTestRunnerCN import HTMLTestReportCN
suite = unittest.defaultTestLoader.discover('.', 'hm08_parameterized1.py')
with open('report_CN.html', 'wb') as f:
    runner = HTMLTestReportCN(f)
    runner.run(suite)

二、PyTest框架介绍

1、什么是PyTest框架?

PyTest是python中一种单元测试框架,同自带的UnitTest测试框架类似,相比于UnitTest框架使用起来更简洁,效率更高。在自动化测试中充当测试执行的功能,并可以与UnitTest互换。

2、为什么使用PyTest框架?

3、PyTest框架安装与基本使用

与UnitTest不同的是,pytest需要先安装才能使用。注意:如果pytest命令无法使用,则需要以管理员身份重新安装pytest。

安装步骤:

测试形式:

运行方式:

# 主函数模式基本格式:
if __name__ = '__main__':
    pytest.main(["-s", "文件名.py"])
#举例:在 test_login.py 文件中增加主函数:
if __name__ = '__main__':
    pytest.main(["-s", "test_login.py"])

4、PyTest框架实践

4.1 配置文件

介绍:

步骤:

示例:

注意:

默认配置:

自定义规则:

4.2 特殊方法

函数级别方法: setupteardown

介绍:

代码格式:

import pytest
class TestDemo(object):
    """测试示例类"""
    def setup(self):
        """开始方法"""
        print("方法 -> 开始")
    def teardown(self):
        """结束方法"""
        print("方法 -> 结束")
    """

举例:函数级别 setupteardown

"""
import pytest
class TestDemo(object):
    """测试示例类"""
    # 说明:特殊方法名写法固定,没有代码提示,需要手写。
    def setup(self):
        """开始方法"""
        print("函数 -> 开始")
    def teardown(self):
        """结束方法"""
        print("函数 -> 结束")
    def test_method1(self):
        """示例测试方法"""
        print("测试方法1")
    def test_method2(self):
        """示例测试方法"""
        print("测试方法2")
if __name__ == '__main__':
    pytest.main(['-s', 'hm05_pytest.py'])

类级别方法: setup_classteardown_class

介绍: 运行于测试类的始末,在一个测试内只运行一次setup_class和teardown_class,不关心测试类内有多少个测试函数

代码格式:

import pytest
class TestDemo(object):
    """测试示例类"""
    def setup_class(self):
        """开始方法"""
        print("类 -> 开始")
    def teardown_class(self):
        """结束方法"""
        print("类 -> 结束")
    """

举例:类级别 setup_classteardown_class

"""
import pytest
class TestDemo(object):
    """测试示例类"""
    # 说明:特殊方法名写法固定,没有代码提示,需要手写。
    def setup_class(self):
        """开始方法"""
        print("类 -> 开始")
    def teardown_class(self):
        """结束方法"""
        print("类 -> 结束")
    def test_method1(self):
        """示例测试方法"""
        print("测试方法1")
    def test_method2(self):
        """示例测试方法"""
        print("测试方法2")
if __name__ == '__main__':
    pytest.main(['-s', 'hm06_pytest.py'])

举例:函数级别和类级别同时使用

"""
特殊方法:函数级别和类级别同时使用
"""
import pytest
class TestDemo(object):
    """测试示例类"""
    # 执行顺序:1 ->3 ->5 ->4 ->3 ->6 ->4 ->2
    def setup_class(self):  # 1
        print("类级别 ->> 开始")
    def teardown_class(self):  # 2
        print("类级别 ->> 结束")
    def setup(self):  # 3
        print("函数级别 -> 开始")
    def teardown(self):  # 4
        print("函数级别 -> 结束")
    def test_method1(self):  # 5
        """示例测试方法"""
        print("测试方法1")
    def test_method2(self):  # 6
        """示例测试方法"""
        print("测试方法2")
if __name__ == '__main__':
    pytest.main(['-s', 'hm07_pytest.py'])

4.3 执行顺序插件

介绍:

代码:

"""
pytest 控制方法执行顺序插件
"""
import pytest
@pytest.mark.run(order=2)
class TestDemo1(object):
    """测试示例类"""
    # 语法:@pytest.mark.run(order=序号)
    # 注意:run(order=序号)没有代码提示,需要手写
    @pytest.mark.run(order=3)
    def test_method1(self):
        """示例测试方法"""
        print("测试方法1")
    @pytest.mark.run(order=1)
    def test_method2(self):
        """示例测试方法"""
        print("测试方法2")
    @pytest.mark.run(order=2)
    def test_method3(self):
        """示例测试方法"""
        print("测试方法3")
# 扩展:序号支持正数和负数,以及正负混合
# 1、纯正数:数越小,优先级越高【掌握】
# 2、纯负数:数越小,优先级越高【了解】
# 3、正负混合:正数先按照顺序执行,负数最后执行【了解】
# 注意:控制方法执行顺序对测试类同样有效
@pytest.mark.run(order=1)
class TestDemo2(object):
    """测试示例类"""
    def test_method(self):
        """示例测试方法"""
        print("测试类2 -> 测试方法")
if __name__ == '__main__':
    pytest.main(['-s', 'hm08_pytest.py'])

4.4 失败重试插件

介绍:

代码: 配置文件

4.5 跳过

介绍:

代码:

@pytest.mark.skipif(condition, reason='xxx')
  """
pytest 跳过测试
"""
import pytest
version = 25  # 模拟软件版本号
class TestDemo(object):
    """测试示例类"""
    def test_method1(self):
        """示例测试方法"""
        print("测试方法1")
    # 注意:reason= 不能省略,否则会报错!
    @pytest.mark.skipif(version >= 25, reason='当前版本不执行')
    def test_method2(self):
        """示例测试方法"""
        print("测试方法2")
    def test_method3(self):
        """示例测试方法"""
        print("测试方法3")
# 说明:同样可以跳过测试类
@pytest.mark.skipif(version >= 25, reason='当前版本不执行')
class TestDemo2(object):
    """测试示例类"""
    def test_method(self):
        """示例测试方法"""
        print("测试类2->测试方法")
if __name__ == '__main__':
    pytest.main(['-s', 'hm09_pytest.py'])

4.6 断言

Python自带断言:

代码:

import pytest
def add_func(num1, num2):
    """加法函数"""
    return num1 + num2
class TestDemo(object):
    """示例测试类"""
    # 调用被测函数
    result = add_func(1, 2)
    # 断言判断结果
    assert 3 == result

4.7 参数化

介绍:

单个参数:

"""
pytest 参数化功能:单个参数
"""
import pytest
class TestDemo(object):
    """示例测试类"""
    # @pytest.mark.parametrize('参数变量', ['数值1', '数值2', ...])
    @pytest.mark.parametrize('name', ['小米', '小新'])
    def test_method1(self, name):
        """示例测试方法"""
        print("获取的名字是:", name)
if __name__ == '__main__':
    pytest.main(['-s', 'hm10_pytest.py'])

多个参数:

代码示例1:

"""
pytest 参数化功能:多个参数
"""
import pytest
class TestDemo(object):
    """示例测试类"""
    @pytest.mark.parametrize('name, pwd', [('admin', 123456), ('test', 654321)])
    def test_method1(self, name, pwd):
        """示例测试方法"""
        print("账号:{} 的秘密是:{}".format(name, pwd))
if __name__ == '__main__':
    pytest.main(['-s', 'hm11_pytest.py'])

代码示例2:

import pytest
def build_test_data():
    """构造测试数据函数"""
    # 中间代码略
    return [('admin', 123456), ('test', 654321), ('xxx', 'yyy')]
class TestDemo(object):
    """示例测试类"""
    # 通过方法引入数据,pytest中必须带小括号
    @pytest.mark.parametrize('name, pwd', build_test_data())
    def test_method1(self, name, pwd):
        """示例测试方法"""
        print("账号:{} 的秘密是:{}".format(name, pwd))

4.8 测试报告插件

介绍:

代码: 配置文件

4.9 PyTest框架运行UnitTest的TestCase

在配置文件中把python_files的名字修改为TestCase测试用例的文件名(xxx.py)即可。

4.10 总结

配置文件:

 【最后可能给予你助力的自动化教程】

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走【Web UI自动化测试】Web UI自动化测试之框架篇(全网最全)

面试资料

我们学习软件测试必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。【Web UI自动化测试】Web UI自动化测试之框架篇(全网最全)

上面是我整理的配套资源,这些资源对于软件测试的的朋友来说应该是最全面最完整的备战仓库,为了更好地整理每个模块,我也参考了很多网上的优质博文和项目,力求不漏掉每一个知识点,很多朋友靠着这些内容进行复习,拿到了BATJ等大厂的offer,这个仓库也已经帮助了很多的软件测试的学习者,希望也能帮助到你。

【Web UI自动化测试】Web UI自动化测试之框架篇(全网最全)

发表回复