系统介绍
本系统后端使用了springboot框架,前端使用html+css+js搭建,面相于用户网页端应用。提供了用户进行投票,参赛,修改用户信息,查看统计数据等功能。
具体功能如下:
(1):投票功能:用户每天会获得三次投票机会,可以在主页进行投票,对每个投票对象无投票次数限制,票数在每天0点更新.
(2)搜索功能:用户可以通过搜索框输入关键词快速定位到投票对象
(3)参赛功能: 用户可以在个人中心点击我要参赛进行参赛,用户上传文件信息以及昵称即可参赛
(4)统计功能:用户可以查看排行榜前十的投票对象,点击导出按钮可以导出全部投票数据
界面展示
图1注册页面
图2登录页面
图3主页
图4排行榜
图5个人中心
功能测试以及其他测试(黑盒测试)
1.使用xmind提取测试
图6测试点提取
2.编写测试用例
展示部分用例
编号 | 标题 | 优先级 | 模块 | 前置条件 | 测试步骤 | 测试数据 | 预期结果 |
register_001 | 注册成功(用户名,密码.确认密码,验证码都正确 | p0 | 注册 | 打开注册页面 | 1.输入用户名 2.输入密码 3.输入确认密码 4.输入验证码 | 用户名:test 密码:123abc 确认密码:123abc 验证码: xxxx | 注册成功,跳转登录页面 |
register_002 | 注册成功(用户名1位) | p0 | 注册 | 打开注册页面 | 1.输入用户名 2.输入密码 3.输入确认密码 5.输入验证码 | 用户名:t 密码:123abc 确认密码:124abc 验证码: xxxx | 注册成功,跳转登录页面 |
register_003 | 注册成功(用户名6位) | p0 | 注册 | 打开注册页面 | 1.输入用户名 2.输入密码 3.输入确认密码 7.输入验证码 | 用户名:testaa 密码:123abc 确认密码:126abc 验证码: xxxx | 注册成功,跳转登录页面 |
register_004 | 注册失败(用户名为空) | p1 | 注册 | 打开注册页面 | 1.输入用户名 2.输入密码 3.输入确认密码 8.输入验证码 | 用户名: 密码:123abc 确认密码:127abc 验证码: xxxx | 注册失败,提示用户名格式 |
register_005 | 注册失败(用户名7位) | p1 | 注册 | 打开注册页面 | 1.不输入用户名 2.输入密码 3.输入确认密码 5.输入验证码 | 用户名:testabc1 密码:123abc 确认密码:123abc 验证码: xxxx | 注册失败,提示用户名格式 |
register_006 | 注册失败(用户名已存在) | p1 | 注册 | 打开注册页面 | 1.输入用户名 2.输入密码 3.输入确认密码 6.输入验证码 | 用户名:admin 密码: 确认密码:124abc 验证码: xxxx | 注册失败,提示用户名已存在 |
register_007 | 注册失败(确认密码为空) | p1 | 注册 | 打开注册页面 | 1.输入用户名 2.输入密码 3.输入确认密码 7.输入验证码 | 用户名: 密码:123abc 确认密码: 验证码: xxxx | 注册失败,提示请输入确认密码 |
register_008 | 注册失败(验证码为空) | p1 | 注册 | 打开注册页面 | 1.输入用户名 2.输入密码 3.输入确认密码 8.输入验证码 | 用户名:test1 密码:123abc 确认密码:125abc 验证码: | 注册失败,提示请输入验证码 |
… | … | … | … | … | … | … | … |
接口测试(灰盒测试)
本项目接口测试使用pytest框架
1.使用xmind提取接口测试点
图7接口测试测试点
2.编写测试用例
部分接口用例:
ID | 模块 | 优先级 | 用例名称 | 接口名称 | 前置条件 | 请求URL | 请求方法 | 请求头 | 请求参数类型 | 请求参数 | 预期结果 |
register-001 | 注册 | p0 | 注册成功(全部参数正确) | 注册 | 1、获取验证码成功 0、用户名未注册 | /user/register | POST | {"content-Type":"application/json"} | json | { "username": "manager", "password": "123456", "code": "xxxx", } | ①响应状态码:200 ②响应数据: { "msg": "操作成功", "code": 1, "token": "xxxxxx"} |
register-002 | 注册 | P2 | 注册失败(缺少用户名) | 注册 | 1、获取验证码成功 1、用户名未注册 | /user/register | POST | {"content-Type":"application/json"} | json | { "username": "manager", "password": "123456", "code": "xxxx", } | ①响应状态码:200 ②响应数据: { "msg": "用户名不能为空", "code": 0} |
register-003 | 注册 | P2 | 注册失败(已存在的用户名) | 注册 | 1、获取验证码成功 2、用户名已注册 | /user/register | POST | {"content-Type":"application/json"} | json | { "username": "admin", "password": "123456", "code": "xxxx", } | ①响应状态码:200 ②响应数据: { "msg": "用户名已被注册", "code": 0} |
register-004 | 注册 | P2 | 注册失败(用户名过长) | 注册 | 1、获取验证码成功 3、用户名未注册 | /user/register | POST | {"content-Type":"application/json"} | json | { "username": "admin123432", "password": "123456", "code": "xxxx", } | ①响应状态码:200 ②响应数据: { "msg": "用户名格式错误", "code": 0} |
register-005 | 注册 | P2 | 注册失败(密码过短) | 注册 | 1、获取验证码成功 4、用户名未注册 | /user/register | POST | {"content-Type":"application/json"} | json | { "username": "admin", "password": "12345", "code": "xxxx", } | ①响应状态码:200 ②响应数据: { "msg": "密码格式错误", "code": 0} |
register-006 | 注册 | P2 | 注册失败(密码过长) | 注册 | 1、获取验证码成功 5、用户名未注册 | /user/register | POST | {"content-Type":"application/json"} | json | { "username": "admin", "password": "123456abcdefg", "code": "xxxx", } | ①响应状态码:200 ②响应数据: { "msg": "密码格式错误", "code": 0} |
register-007 | 注册 | P2 | 注册失败(密码为空) | 注册 | 1、获取验证码成功 6、用户名未注册 | /user/register | POST | {"content-Type":"application/json"} | json | { "username": "admin", "password": "", "code": "xxxx", } | ①响应状态码:200 ②响应数据: { "msg": "密码格式错误", "code": 0} |
register-008 | 注册 | P2 | 注册失败(验证码为空) | 注册 | 1、获取验证码成功 7、用户名未注册 | /user/register | POST | {"content-Type":"application/json"} | json | { "username": "admin", "password": "123461", "code": "", } | ①响应状态码:200 ②响应数据: { "msg": "验证码为空", "code": 0} |
register-009 | 注册 | p2 | 注册失败(验证码错误) | 注册 | 1、获取验证码成功 8、用户名未注册 | /user/register | POST | {"content-Type":"application/json"} | json | { "username": "admin", "password": "123462", "code": "error", } | ①响应状态码:200 ②响应数据: { "msg": "验证码错误", "code": 0} |
3.搭建测试框架
3.1统一封装请求接口:
注册接口
# 登录:
import requests
import config
# 创建接口类
class RegAPI:
# 初始化
def __init__(self):
# 指定url基本信息
self.url_reg = config.BASE_URL + "/user/register"
# 登录
def register(self, test_data):
return requests.post(url=self.url_reg, json=test_data)
登录接口
# 登录:
import requests
import config
# 创建接口类
class LoginAPI:
# 初始化
def __init__(self):
# 指定url基本信息
self.url_login = config.BASE_URL + "/user/login"
# 登录
def login(self, test_data):
return requests.post(url=self.url_login, json=test_data)
统计接口
# 登录:
import requests
import config
# 创建接口类
class StatisticAPI:
# 初始化
def __init__(self):
# 指定url基本信息
self.url_top10 = config.BASE_URL + "/competitors/topTen"
self.url_export = config.BASE_URL + "/competitors/export"
# top10
def top10Statistic(self, test_data,headers):
return requests.get(url=self.url_top10,params=test_data,headers=headers)
# 导出
def exportExcel(self, headers):
return requests.get(url=self.url_export, headers=headers)
分页查询接口:
import requests
import config
# 创建接口类
class PageAPI:
# 初始化
def __init__(self):
# 指定url基本信息
self.url_page_search = config.BASE_URL + "/competitors/page"
# 分页查询
def page_search(self, test_data,headers):
return requests.get(url=self.url_page_search, json=test_data,headers=headers)
投票接口:
# 登录:
import requests
import config
# 创建接口类
class VoteAPI:
# 初始化
def __init__(self):
# 指定url基本信息
self.url_vote = config.BASE_URL + "/competitors/vote"
def vote(self, test_data,headers):
self.url_update_status = self.url_vote
return requests.put(url=self.url_update_status,params=test_data,headers=headers)
3.2编写测试用例:
注册接口测试:
import os
import pytest
import config
from api.register import RegAPI
import json
def build_data(json_file):
# 定义空列表
test_data = []
# 打开json文件
with open(json_file, "r") as f:
# 加载json文件数据
json_data = json.load(f)
# 循环遍历测试数据
for case_data in json_data:
# 转换数据格式[{},{}] ==> [(),()]
username = case_data.get("username")
password = case_data.get("password")
code = case_data.get("code")
test_data.append((username, password, code))
# 返回处理之后测试数据
return test_data
class TestLoginAPI:
def setup_method(self):
self.reg_api = RegAPI()
@pytest.mark.parametrize("username, password, code",build_data(json_file=config.BASE_PATH + "\\data\\reg.json"))
def test01_login(self,username,password,code):
login_data = {
"username": username,
"password": password,
}
res = self.reg_api.register(test_data=login_data)
# 使用code来做断言
assert res.json()['code'] == code
登录接口测试:
import os
import pytest
import config
from api.login import LoginAPI
import json
def build_data(json_file):
# 定义空列表
test_data = []
# 打开json文件
with open(json_file, "r") as f:
# 加载json文件数据
json_data = json.load(f)
# 循环遍历测试数据
for case_data in json_data:
# 转换数据格式[{},{}] ==> [(),()]
username = case_data.get("username")
password = case_data.get("password")
code = case_data.get("code")
test_data.append((username, password, code))
# 返回处理之后测试数据
return test_data
class TestLoginAPI:
def setup_method(self):
self.login_api = LoginAPI()
@pytest.mark.parametrize("username, password, code",build_data(json_file=config.BASE_PATH + "\\data\\login.json"))
def test01_login(self,username,password,code):
login_data = {
"username": username,
"password": password,
}
res = self.login_api.login(test_data=login_data)
# print(res.json())
# 使用code来做断言
assert res.json()['code'] == code
上传文件接口测试:
import pytest
import requests
import config
from common.yaml_util import YamlUtil
# 上传成功
def test01_upload_success():
token = YamlUtil().read_extract_yaml('token')
headers = {
'Authorization': f'{token}'
}
f = open(config.BASE_PATH + "/data/test.jpg", "rb")
response = requests.post(url=config.BASE_URL+'/upload',files={"img": f},headers=headers)
assert response.status_code == 200
# 文件类型不对
def test02_upload_failure():
token = YamlUtil().read_extract_yaml('token')
headers = {
'Authorization': f'{token}'
}
f = open(config.BASE_PATH + "/data/git.doc", "rb")
response = requests.post(url=config.BASE_URL+'/upload',files={"img": f},headers=headers)
assert response.status_code == 400
# 图片大小过大
def test03_upload_failure():
token = YamlUtil().read_extract_yaml('token')
headers = {
'Authorization': f'{token}'
}
f = open(config.BASE_PATH + "/data/big.jpg", "rb")
response = requests.post(url=config.BASE_URL+'/upload',files={"img": f},headers=headers)
assert response.status_code == 400
# 图片数据为空
def test03_upload_failure():
token = YamlUtil().read_extract_yaml('token')
headers = {
'Authorization': f'{token}'
}
response = requests.post(url=config.BASE_URL+'/upload',files={"img": None},headers=headers)
assert response.status_code == 400
分页查询接口测试
import os
import pytest
import config
from api.register import RegAPI
import json
def build_data(json_file):
# 定义空列表
test_data = []
# 打开json文件
with open(json_file, "r") as f:
# 加载json文件数据
json_data = json.load(f)
# 循环遍历测试数据
for case_data in json_data:
# 转换数据格式[{},{}] ==> [(),()]
username = case_data.get("username")
password = case_data.get("password")
code = case_data.get("code")
test_data.append((username, password, code))
# 返回处理之后测试数据
return test_data
class TestLoginAPI:
def setup_method(self):
self.reg_api = RegAPI()
@pytest.mark.parametrize("username, password, code",build_data(json_file=config.BASE_PATH + "\\data\\reg.json"))
def test01_login(self,username,password,code):
login_data = {
"username": username,
"password": password,
}
res = self.reg_api.register(test_data=login_data)
# 使用code来做断言
assert res.json()['code'] == code
统一做未登录的接口测试:
#统一测试未登录接口
import requests
import config
# 未登录分页查询
def test_page():
testData = {
"page": "1",
"pageSize": "10",
"title": "张三",
}
response = requests.get(url=config.BASE_URL + "/competitors/page",params=testData)
assert response.status_code == 401
def test_statistic():
response = requests.get(url=config.BASE_URL + "/competitors/topTen")
assert response.status_code == 401
def test_export():
response = requests.get(url=config.BASE_URL + "/competitors/export")
assert response.status_code == 401
3.3执行测试用例并生成报告
图8报告图