自动化测试:电商管理系统元素定位练习​

本次专题我们来说一下 Python中Unittest 框架的使用及如何通过HTMLTestRunner实现自动化测试报告的自动生成。案例中的代码我们仍旧使用课堂学习中部署的“电商管理系统”来实现。本次练习包括以下几个操作:

l 测试用例整体结构设计

l 测试用例的实现

l 测试套的组织及测试报告的生成

1. 测试用例整体结构设计

Unittest原名为PyUnit,是由java的JUnit衍生而来,用于编写和运行可重复的测试。基于断言机制来判断函数或方法的实际输出结果和期望输出结果是否一致,测试用例提供参数来执行函数或方法,获取它们的执行结果,然后使用断言方法来判断该函数或方法的输出结果与期望输出结果是否一致,如果一致则说明测试通过;如果不一致则说明测试不通过。

Unittest 要求单元测试类必须继承 TestCase,该类中的测试方法应以test开头,没有参数和返回值。另外可以通过在单元测试中增加两个特殊函数setUp()和tearDown()函数,用于实现在每调用一个测试方法的前后分别执行指定的动作,其中setUp是在测试函数调用前执行,tearDown是在之后执行。

我们首先为登录功能编写一个测试用例,代码结构如下,一共演示包括三个测试方法:

在这里插入图片描述

2. 测试用例的实现

接下来我们完成测试用例内容的实现。按照上面的结构,一共实现两个测试用例,一个登录的测试用例,一个增加商品类型的测试用例。

登录测试用例。这里将系统登录页面的打开和关闭功能分别封装进setUp和tearDown函数内部,这样后续每个方法执行的前后会自动打开登录页面并在测试执行之后关闭登录页面。

代码实现如下:

import unittest
from time import sleep
from selenium import webdriver


# 登录测试用例
class LoginTest(unittest.TestCase):
 # 每执行一个测试方法前,先打开登录页面
 def setUp(self):
 self.driver = webdriver.Firefox()
 self.driver.implicitly_wait(10)
 self.driver.get('http://39.96.181.61/qftest-ds/index.php?m=backend&c=main&a=index')

 # 每执行一个测试方法后,关闭浏览器
 def tearDown(self):
 self.driver.quit()

 # 测试方法1:无效用户名登录测试
 def test_01_invalid_username(self):
 self.driver.find_element_by_id("username").send_keys('abcdefg')
 self.driver.find_element_by_id("password").send_keys('qftestxxxxx')
 self.driver.find_element_by_link_text('登 陆').click()
        sleep(2)
 # 断言:如果登录失败,应该显示提示信息,包含文字:"错误的用户名或密码"
 self.assertIn('错误的用户名或密码', self.driver.page_source)

 # 测试方法2:无效密码登录测试
 def test_02_invalid_password(self):
 self.driver.find_element_by_id("username").send_keys('admin')
 self.driver.find_element_by_id("password").send_keys('123456')
 self.driver.find_element_by_link_text('登 陆').click()
        sleep(2)
 # 断言:如果登录失败,应该显示提示信息,包含文字:"错误的用户名或密码"
 self.assertIn('错误的用户名或密码', self.driver.page_source)

 # 测试方法3:有效用户名和密码登录测试
 def test_03_valid(self):
 self.driver.find_element_by_id("username").send_keys('admin')
 self.driver.find_element_by_id("password").send_keys('qftestxxxxxx')
 self.driver.find_element_by_link_text('登 陆').click()
        sleep(2)
 # 断言:如果登录成功,应该进入系统桌面,包含文字:"常用菜单"
 self.assertIn('常用菜单', self.driver.page_source)


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

增加商品类型测试用例。这里将系统登录和退出及关闭浏览器功能分别封装进setUp和tearDown函数内部,这样后续每个方法执行的前后会自动完成登录并在测试执行之后退出和关闭登录页面。
代码实现如下:
import random
import unittest
from time import sleep
from selenium import webdriver
from selenium.webdriver.support.select import Select


# 增加商品分类测试用例
class AddTypeTest(unittest.TestCase):

 def setUp(self):
 self.driver = webdriver.Firefox()
 self.driver.implicitly_wait(10)
 self.driver.get('http://39.96.181.61/qftest-ds/index.php?m=backend&c=main&a=index')
 self.driver.find_element_by_id("username").send_keys('admin')
 self.driver.find_element_by_id("password").send_keys('qftestxxxxxxx')
 self.driver.find_element_by_link_text('登 陆').click()
        sleep(3)

 def tearDown(self):
 self.driver.switch_to.default_content()
 self.driver.find_element_by_link_text("退出登录").click()
        sleep(2)
 self.driver.quit()

 # 测试方法1:是否可要正确打开商品分类页面
 def test_01_open_type(self):
        sleep(5)
 # 依次点击目录:商品管理 - 商品分类
 self.driver.find_element_by_xpath('/html/body/div[5]/div[1]/div[2]/h3/a').click()
 self.driver.find_element_by_partial_link_text('商品分类').click()
        sleep(5)
 # 切换到内部 iframe
 self.driver.switch_to.frame('main')
 # 断言:如果打开商品分类页面成功,应该包含显示文字:"分类名称"
 self.assertIn('分类名称', self.driver.page_source)

 # 测试方法2:是否可要新增商品分类,并且添加成功
 def test_02_add_type(self):
        sleep(5)
 # 依次点击目录:商品管理 - 商品分类
 self.driver.find_element_by_xpath('/html/body/div[5]/div[1]/div[2]/h3/a').click()
 self.driver.find_element_by_partial_link_text('商品分类').click()
        sleep(5)
 self.driver.switch_to.frame('main')
 # 点击“新增分类”按钮
 self.driver.find_element_by_xpath('/html/body/div/div[2]/div[1]/a[1]/font').click()
        sleep(1)

 # 输入分类名称
 self.driver.find_element_by_id('cate_name').send_keys('奥里给')
        sleep(1)

 # 从下拉列表中随机选择一个上级分类
 father_type = self.driver.find_element_by_id('parent_id')
        father_type_opts = Select(father_type).options
        rom = random.randint(0, len(father_type_opts) - 1)
        Select(father_type).select_by_index(rom)
        sleep(1)

 # 点击“保存并提交”按钮
 self.driver.find_element_by_css_selector('html body div.content form div.box div.submitbtn button.ubtn.btn').click()
        sleep(5)

 # 断言:新增的分类名称,应该显示在返回的分类表格页面中
 self.assertIn('奥里给', self.driver.page_source)


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

3. 测试套的组织及测试报告的生成

对于测试用例的执行,我们使用unittest下面的测试套件类TestSuite,从它的类定义来看,可以理解为多个独立的测试用例(test case)可以构成一个测试套件。

想让测试用例按顺序执行,要用到TestSuite类的addTest方法。调用addTest方法后,先添加的先执行,后添加的后执行。但是这里提请大家注意一下,在PyCharm中,addTest方法并没有起到作用,原因是在PyCharm中,引入了unittest模块,会默认按照unittest模式执行,此时需要将unittest模式转换成普通模式。

我们在做自动化测试的时候,希望能生一张漂亮的测试报告来展示用例执行的结果,这里我们使用HTMLTestRunner来实现。HTMLTestRunner 是 Python 标准库的 unittest 模块的一个扩展。它生成易于使用的 HTML 测试报告。

代码实现如下:

import unittest
from HTMLTestRunner import HTMLTestRunner
from F01_login_test import LoginTest
from F02_add_type_test import AddTypeTest


# 定义测试套(包含要运行的测试用例及方法)
def test_suite():
    suite = unittest.TestSuite()

    # 添加第一个测试用例及所属测试方法
    suite.addTest(LoginTest('test_01_invalid_username'))
    suite.addTest(LoginTest('test_02_invalid_password'))
    suite.addTest(LoginTest('test_03_valid'))

    # 添加第二个测试用例及所属方法
    suite.addTest(AddTypeTest('test_01_open_type'))
    suite.addTest(AddTypeTest('test_02_add_type'))

    return suite


if __name__ == '__main__':
    # 设置测试报告输出文件
    with open('./test_report.html', 'wb') as f:
        runner = HTMLTestRunner(stream=f,
                                title="自动化测试报告",
                                description="电商系统自动化测试报告")
        # 运行测试套
        runner.run(test_suite())

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/391562.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

linux kernel 内存踩踏之KASAN_SW_TAGS(二)

一、背景 linux kernel 内存踩踏之KASAN(一)_kasan版本跟hasan版本区别-CSDN博客 上一篇简单介绍了标准版本的KASAN使用方法和实现,这里将介绍KASAN_SW_TAGS和KASAN_HW_TAGS 的使用和背后基本原理,下图是三种方式的对比&#x…

线索化二叉树(先序,中序,后序)+线索化二叉树的遍历【java详解】

目录 线索化二叉树的基本介绍: 举个栗子: 二叉树的中序线索化: 创建HeroNode类,表示节点信息: 编写中序线索化方法代码: 中序线索化遍历代码: 测试代码: 测试结果&#xff1a…

一起学量化之RSI指标

RSI指标 Relative Strength Index,相对强弱指数(RSI),是一个衡量资产过度买入或过度卖出状态的技术指标。 1. RSI的基本概念 当RSI超过70时,通常被认为是超买状态。当RSI低于30时,通常被认为是超卖状态。RSI超过80,被认为是严重超买状态。RSI低于20,被认为是严重超卖状…

微波炉维修笔记

微波主要是靠2.45GHz 左右的微波(12.2cm 波长)加热水分子实现食物加热 所有不要使用金属器皿进行加热,要么因为电磁屏蔽,起不到加热效果,要么火光四射 微波炉基本组成 借鉴姜师傅的视频 碰到不加热其它都正常的问题 1.检查高压电容 使用万…

第10章 JDBC

10.1 什么是JDBC JDBC的全称是Java数据库连接(Java Database Connectivity),它是一套用于执行SQL语句的Java API。应用程序可通过这套API连接到关系型数据库,并使用SQL语句完成对数据库中数据的新增、删除、修改和查询等操作。 …

Trie 字典树的两种实现方式

Trie,又称字典树、单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是…

github Two-factor authentication (2FA)is required for your GitHub account

问题 github 2FA认证 详细问题 笔者使用GitKraken,使用github登录,github要去 Two-factor authentication (2FA)is required for your GitHub account,即进行2FA认证 解决方案 解决方案一、 微信 → \rightarrow →搜索腾讯身份验证器…

内存块与内存池

(1)在运行过程中,MemoryPool内存池可能会有多个用来满足内存申请请求的内存块,这些内存块是从进程堆中开辟的一个较大的连续内存区域,它由一个MemoryBlock结构体和多个可供分配的内存单元组成,所有内存块组…

java 培训班预定管理系统Myeclipse开发mysql数据库web结构jsp编程servlet计算机网页项目

一、源码特点 java 培训班预定管理系统是一套完善的java web信息管理系统 采用serlvetdaobean,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xf…

java 宠物医院系统Myeclipse开发mysql数据库web结构jsp编程计算机网页项目

一、源码特点 java 宠物医院系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0&…

Excel如何把窗口冻结,在下拉滚动条的时候仍然可以看到前几行数据?

** 共分2个情况: ①: 冻结首行: 作用:只冻结第一行的数据窗口。在下拉滚动条时,首行不会动,其他数据行会动步骤如下:1、鼠标放在首行的最左边,然后左键点一下先选中整行2、然后&am…

OpenAI发布Sora技术报告深度解读!真的太强了!

😎 作者介绍:我是程序员洲洲,一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究生。公粽号:洲与AI。 🎈 本文专栏:本文收录…

IP地址+子网掩码+CIDR学习笔记

目录 一、IP地址 1、表示方法: 2、特殊IP地址 二、子网掩码 1、判断网络位和主机位 2、子网划分 三、无分类编址CIDR 1、CIDR路由汇聚 汇聚规则: 汇聚ID: 2、最佳路由匹配原则 一、IP地址 1、表示方法: 机器中存放的…

UE Get节点和源码

文章目录 概要UE Get节点有哪些常见的应用场景相关源码 概要 UE Get节点在Unreal Engine的蓝图系统中用于获取变量的值。这个节点通常用于从变量中读取数据,以便在游戏的逻辑流程中使用。 要使用Get节点,你首先需要有一个已经定义的变量。然后&#xf…

电梯控制系列之电梯结构介绍

这篇博客介绍单部10层电梯的完整控制程序框架编写过程,编程语言:SCL,控制器型号:S7-1200PLC。本篇博客介绍和电梯控制相关的一些电梯结构介绍。本文只可作为学习参考资料,行业控制需要遵循电梯安全相关规范。 1、电梯…

【Linux系统化学习】缓冲区

目录 缓冲区 一个样例 现象解释 缓冲区存在的位置 缓冲区 在刚开始学习C语言的时候我们就听过缓冲区这个名词,很是晦涩难懂;在Linux下进程退出时也包含缓冲区,因此缓冲区到底是什么?有什么作用? 让我们先从一个小…

微服务—DSL基础语法与RestClient操作

本博客为个人学习笔记,学习网站:黑马程序员SpringCloud 2021教程 目录 DSL语法 索引库操作 mapping属性 创建索引库 字段拷贝 查询、删除、修改索引库 文档操作 新增文档 查询、删除文档 修改文档 全量修改 增量修改 DSL文档语法小结 Rest…

JWT登录验证前后端设计与实现笔记

设计内容 前端 配置全局前置路由守卫axios拦截器登录页面和主页 后端 JWT的封装登录接口中间件放行mysql数据库的连接 详细设计 路由设计 配置全局前置守卫,如果访问的是登录页面则放行,不是则进入判断是否有token,没有则拦截回到登录…

17-k8s控制器资源-job控制

job控制器:就是一次性任务的pod控制器,pod完成作业后不会重启,其重启策略是:Never 1,job控制器案例描述 启动一个pod,执行完成一个事件,然后pod关闭; 事件:计算π的值&a…

[java基础揉碎]类与对象

目录 类与对象的引出: 类与对象的概述: 类与对象在内存中的布局: 属性的注意细节: 类与对象在内存中创建的过程: 类与对象的引出: 例如这样一个问题: 如果用单独变量来解决, 就会有一个问题, 不利于数据的管理, 将所有猫的信息都给拆解了: 如果用数组来解决, 则会有 1)数…
最新文章