前言(测试的相关知识)
- 软件测试的生命周期
需求分析—测试计划—测试设计/开发—测试执行—测试评估
-
各个阶段所要完成的任务
1.需求分析:验证需求的合理性,正确性:细化需求,写测试用例。
2.测试计划:考虑测试人数,测试环境,测试时间,测试设备等。
3.测试设计/开发:根据需求写测试用例。
4.测试执行:开发已经完成,执行测试用例,验证功能。提交BUG,验证BUG。
5.测试评估:写了多少测试用例,执行了多少,剩余的测试用例数。BUG数量,解决的BUG 数量,遗留的BUG及解决方案。 -
测试用例的设计方法
基于需求的设计方法,等价类,边界值,因果图,场景设计法,错误猜测法。
提示:以下是本篇文章正文内容,下面案例可供参考
一、需求分析
功能需求:
1.题目列表页的展示——能成功展示题目列表页
2.题目详情页的展示——单击某一道题目,可以跳转到指定页面
3.用户提交代码的功能——当用户输入正确或者不正确的代码,点击提交,可以正常在下方输出结果
4.新增,删除题目,页面会展示相应操作后的结果,同时数据库内的数据也发生改变
性能需求:
1.单个/多个用户点击一道题目的跳转时间——满足用户需求
2.单个/多个用户提交代码到输出结果的时间——满足用户需求
3.提交多行代码运行时间——不会超出用户可以等待的最大时间
4.多个用户提交代码系统是否稳定——稳定
5.频繁提交代码是否出现闪退——否
安全需求:
1.不输入代码或者输入危险操作的代码——会有提示
2.能否防止SQL注入——可以
3.能否防止XSS脚本攻击——可以
易用性需求:
1.页面展示直观,提交按钮直观易用
2.题目跳转链接直观可见
3.页面展示符合用户习惯
兼容性需求:
1.支持各种浏览器访问
2.支持同一浏览器的不同版本
3.支持不同的操作系统
界面需求:
1.布局:布局合理美观
2.题目展示页每一行题目展示风格相同
3.页面最多展示多少个题目
4.当题目过长时能够分行展示
5.字体大小合适,风格一致
二、测试设计
测试目的 | 测试项目能否实现各种功能,是否满足用户需求 |
---|---|
测试对象 | 项目数据库模块以及功能模块 |
测试环境 | Windows11 Edge浏览器 |
测试方式 | 手工+自动化测试 |
测试方法 | 白盒测试+黑盒测试 |
测试依据 | 测试用例 |
测试框架 | Junit框架、unnitest框架、selenium |
测试功能模块 | 数据库增删查改,题目展示、跳转、代码提交 |
三、测试计划
1.功能测试:
1).题目展示及提交
- 进入题目列表页,可以展示全部题目
- 单击某个题目,可以跳转到对应页面
- 对应页面可以完整展示题目详情
- 代码框模板代码正确
- 不写代码,单击提交按钮,下面显示错误信息
- 写正确和错误代码,分别对应通过和不通过提示信息
- 写危险代码,提示框提示危险代码
- 操作数据库增删查改,页面能分别展示数据库操作之后的结果,同时数据库的数据也发生变化
2).异常情况
- 数据库连接错误,不能正常显示题目
- 在新增题目时停止服务,是否新增成功:
Tomcat服务器停止,新增失败
服务器关机,新增失败
在新增题目之前停止服务,新增失败
在新增题目之后停止服务,新增成功
3).网络测试
- 弱网:网页显示慢
- 网络断开:页面还存在
2.兼容性测试:
1).各种浏览器器访问:
- 谷歌
- 火狐
- IE
- edge
均可正常显示
2).同一浏览器不同版本
3).不同的操作系统:
Linux,Windows
3.安全性测试:
编写带有对电脑有害的代码时,是否会有提示:有
4.易用性测试:
- 页面展示直观,提交按钮直观易用
- 题目跳转链接直观可见
5.性能测试:
- 点击某一题目跳转速度快
- 提交代码出现结果时间快
- 多个用户同时提交,同时点击
- 代码量过多时,运行速度
- 频繁提交代码是否出现闪退
6.界面测试:
1).布局
- 布局合理美观
- 题目展示页每一行题目展示风格一致
- 页面最多展示多少个题目
- 当题目过长是否会分行
2).字体
- 字体大小合适
- 字体风格一致
四、测试执行
1.手工测试
1)功能模块
功能模块 | 对应测试项 |
---|---|
进入题目列表页 | 正常展示全部题目 |
单击某个题目 | 跳转到指定题目对应页面 |
题目对应页面 | 可以完整展示题目详情 |
题目对应页面 | 代码框模板代码正确 |
单击提交按钮 | 不写代码:显示错误信息;写正确和错误代码:分别对应通过和不通过提示信息;写危险代码:提示危险代码 |
题目列表页展示:
题目详情页展示:
代码编辑框展示:
单击提交按钮,不写代码(乱码是因为字符集设置问题):
单击提交按钮,写错误代码(用例1通过,用例2未通过):
单击提交按钮,写正确代码(项目出错):
异常测试 | 对应测试项 |
---|---|
数据库连接错误 | 不能正常显示题目 |
Tomcat服务器停止 | 不能新增成功 |
数据库连接错误:
Tomcat服务器停止:题目新增失败
网络测试 | 对应测试项 |
---|---|
访问网址进去后网络断开 | 页面还显示,仍然可以跳转;点击提交仍然可以提交 |
访问服务器之前网络断开 | 进入不了页面 |
访问网址进去后网络断开:
访问服务器之前网络断开:仍可以进去页面
2)兼容性模块
兼容性测试 | 对应测试项 |
---|---|
不同浏览器 | 火狐 Egde均可访问 |
Egde:
火狐:
3)安全性模块
安全性测试 | 对应测试项 |
---|---|
用户输入的代码中带有“Runtime” | 出现提示信息,运行不成功 |
用户输入的代码中带有“exec” | 出现提示信息,运行不成功 |
用户输入的代码中带有“java.io” | 出现提示信息,运行不成功 |
用户输入的代码中带有“java.net” | 出现提示信息,运行不成功 |
当访问对应id页面时,带有SQL语句 | 页面展示不出来 |
用户输入的代码中带有“Runtime”:
用户输入的代码中带有“exec” :
用户输入的代码中带有“java.io” :
用户输入的代码中带有“java.net”
当访问对应id页面时,带有SQL语句:页面展示不出来
3)界面模块
界面测试 | 对应测试点 |
---|---|
题目展示页每一行题目展示风格一致 | √ |
布局合理美观 | √ |
字体大小合适 | √ |
字体风格一致 | √ |
当题目过长是否会分行 | 提示过长,插入不成功 |
当题目过长:
2.利用框架测试
1.单元测试
准备工作
- 采用Junit框架进行单元测试,首先将如下代码加入到pom.xml里的dependencies中。
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
- 对题目管理的增删查进行单元测试
选中题目管理的类名(ProblemDao)按ctrl+shift+T则自动生成单元测试类.
下面我们将分别测试新增题目,删除题目,查找所有题目,查找单个题目等方法。
1.新增题目
2.展示指定id题目信息
3.展示全部题目信息
4.删除题目
2.自动化测试(回归测试)
利用selenium工具和unittest框架对项目的跳转到指定题目页、以及输入代码和不输入代码点击提交按钮做自动化测试,并且生成到HTML测试报告中.
1.对指定题目,跳转到其对应展示页面:
(这里用了两种定位方式,分别是xpath和link_text)
import time
from selenium import webdriver
import unittest
class My(unittest.TestCase):
# self是类的实例
def setUp(self):
self.driver = webdriver.Firefox()
self.url = "http://localhost:8080/unititled12022.2/"
self.driver.maximize_window()
def tearDown(self):
self.driver.quit()
def test_oj1(self):
driver = self.driver
driver.get(self.url)
driver.find_element_by_link_text("两数之和1").click()
time.sleep(3)
# @unittest.skip("skipping")
def test_oj2(self):
driver = self.driver
driver.get(self.url)
driver.find_element_by_xpath("/html/body/section[2]/div/div/div/div/table/tbody/tr[2]/td[2]/a").click()
time.sleep(3)
if __name__ == "__main__":
unittest.main()
2.分别对输入代码和不输入代码点击提交按钮做自动化测试
import time
from selenium import webdriver
import unittest
class My2(unittest.TestCase):
# self是类的实例
def setUp(self):
self.driver = webdriver.Firefox()
self.url = "http://localhost:8080/unititled12022.2/problemDetail.html?id=2"
self.driver.maximize_window()
def tearDown(self):
self.driver.quit()
def test_oj3(self):
driver = self.driver
driver.get(self.url)
driver.find_element_by_id("submitButton").click()
time.sleep(3)
# @unittest.skip("skipping")
def test_oj4(self):
driver = self.driver
driver.get(self.url)
driver.find_element_by_xpath("/html/body/section[2]/div/div[2]/div/div/div/textarea").send_keys("int[] ret={"
"0,"
"1}; return "
"ret;")
time.sleep(3)
if __name__=="__main__":
unittest.main()
3.对这四个测试用例生成HTML报告
import HTMLTestRunner
import os.path
import sys
import time
from src import th
from src import fir
import unittest
def createsuite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(fir.My))
suite.addTest(unittest.makeSuite(th.My2))
return suite
if __name__ == "__main__":
# 1.创建当前路径的文件夹
curpath = sys.path[0]
print(sys.path)
print(sys.path[0])
if not os.path.exists(curpath + '/resultreport'):
os.makedirs(curpath + '/resultreport')
# 2.解决重复性 time.time()是时间戳 localtime是化成本地的时间
now = time.strftime("%Y-%m-%d-%H %M %S", time.localtime(time.time()))
print(time.time())
print(time.localtime(time.time()))
fliename = curpath + '/resultreport' + now + 'resultreport.html'
# 打开html文件,以wb写的方式
with open(fliename, 'wb') as fp:
runner = HTMLTestRunner.HTMLTestRunner(stream=fp, title=u"测试报告",
description=u"用例执行情况", verbosity=2)
suite2 = createsuite()
runner.run(suite2)
执行结果
生成的HTML报告