feat: 员工信息管理功能完善
- 将员工表org_no字段迁移至dept_id,关联系统部门表 - 更新员工信息相关DTO、VO和Controller,使用deptId替代orgNo - 添加员工信息管理OpenSpec规范文档(proposal/design/spec/tasks) - 更新API文档,反映部门关联变更 - 添加数据库迁移脚本employee_org_no_to_dept_id.sql - 新增员工信息分页接口测试脚本(PowerShell/Python) - 更新CLAUDE.md,添加MCP数据库工具使用说明 Co-Authored-By: Claude (glm-4.7) <noreply@anthropic.com>
This commit is contained in:
63
test/pagination_test_report_20260128_152606.txt
Normal file
63
test/pagination_test_report_20260128_152606.txt
Normal file
@@ -0,0 +1,63 @@
|
||||
============================================================
|
||||
分页接口总数测试报告
|
||||
============================================================
|
||||
|
||||
测试时间: 2026-01-28 15:26:06
|
||||
|
||||
测试统计:
|
||||
总测试数: 8
|
||||
通过: 0
|
||||
失败: 8
|
||||
错误: 0
|
||||
|
||||
测试接口:
|
||||
1. /dpc/employee/list - 员工列表(MyBatis Plus分页)
|
||||
2. /dpc/intermediary/list - 中介黑名单列表(若依startPage分页)
|
||||
|
||||
------------------------------------------------------------
|
||||
详细结果:
|
||||
------------------------------------------------------------
|
||||
|
||||
测试: 员工列表 - 第1页(10条/页)
|
||||
API类型: MyBatis Plus
|
||||
状态: FAIL
|
||||
错误: 响应缺少data字段
|
||||
|
||||
测试: 员工列表 - 第2页(10条/页)
|
||||
API类型: MyBatis Plus
|
||||
状态: FAIL
|
||||
错误: 响应缺少data字段
|
||||
|
||||
测试: 员工列表 - 第1页(5条/页)
|
||||
API类型: MyBatis Plus
|
||||
状态: FAIL
|
||||
错误: 响应缺少data字段
|
||||
|
||||
测试: 员工列表 - 第1页(20条/页)
|
||||
API类型: MyBatis Plus
|
||||
状态: FAIL
|
||||
错误: 响应缺少data字段
|
||||
|
||||
测试: 中介黑名单 - 第1页(10条/页)
|
||||
API类型: 若依startPage
|
||||
状态: FAIL
|
||||
错误: 响应缺少data字段
|
||||
|
||||
测试: 中介黑名单 - 第2页(10条/页)
|
||||
API类型: 若依startPage
|
||||
状态: FAIL
|
||||
错误: 响应缺少data字段
|
||||
|
||||
测试: 中介黑名单 - 第1页(5条/页)
|
||||
API类型: 若依startPage
|
||||
状态: FAIL
|
||||
错误: 响应缺少data字段
|
||||
|
||||
测试: 中介黑名单 - 第1页(20条/页)
|
||||
API类型: 若依startPage
|
||||
状态: FAIL
|
||||
错误: 响应缺少data字段
|
||||
|
||||
------------------------------------------------------------
|
||||
测试结论:
|
||||
✗ 存在分页接口总数返回异常
|
||||
84
test/pagination_test_report_20260128_152638.txt
Normal file
84
test/pagination_test_report_20260128_152638.txt
Normal file
@@ -0,0 +1,84 @@
|
||||
============================================================
|
||||
分页接口总数测试报告
|
||||
============================================================
|
||||
|
||||
测试时间: 2026-01-28 15:26:38
|
||||
|
||||
测试统计:
|
||||
总测试数: 8
|
||||
通过: 7
|
||||
失败: 1
|
||||
错误: 0
|
||||
|
||||
测试接口:
|
||||
1. /dpc/employee/list - 员工列表(MyBatis Plus分页)
|
||||
2. /dpc/intermediary/list - 中介黑名单列表(若依startPage分页)
|
||||
|
||||
------------------------------------------------------------
|
||||
详细结果:
|
||||
------------------------------------------------------------
|
||||
|
||||
测试: 员工列表 - 第1页(10条/页)
|
||||
API类型: MyBatis Plus
|
||||
状态: PASS
|
||||
页码: 1/10
|
||||
返回行数: 10
|
||||
总数: 199
|
||||
预期行数: 10
|
||||
|
||||
测试: 员工列表 - 第2页(10条/页)
|
||||
API类型: MyBatis Plus
|
||||
状态: PASS
|
||||
页码: 2/10
|
||||
返回行数: 10
|
||||
总数: 199
|
||||
预期行数: 10
|
||||
|
||||
测试: 员工列表 - 第1页(5条/页)
|
||||
API类型: MyBatis Plus
|
||||
状态: PASS
|
||||
页码: 1/5
|
||||
返回行数: 5
|
||||
总数: 199
|
||||
预期行数: 5
|
||||
|
||||
测试: 员工列表 - 第1页(20条/页)
|
||||
API类型: MyBatis Plus
|
||||
状态: PASS
|
||||
页码: 1/20
|
||||
返回行数: 20
|
||||
总数: 199
|
||||
预期行数: 20
|
||||
|
||||
测试: 中介黑名单 - 第1页(10条/页)
|
||||
API类型: 若依startPage
|
||||
状态: PASS
|
||||
页码: 1/10
|
||||
返回行数: 1
|
||||
总数: 1
|
||||
预期行数: 1
|
||||
|
||||
测试: 中介黑名单 - 第2页(10条/页)
|
||||
API类型: 若依startPage
|
||||
状态: FAIL
|
||||
错误: 行数不匹配
|
||||
|
||||
测试: 中介黑名单 - 第1页(5条/页)
|
||||
API类型: 若依startPage
|
||||
状态: PASS
|
||||
页码: 1/5
|
||||
返回行数: 1
|
||||
总数: 1
|
||||
预期行数: 1
|
||||
|
||||
测试: 中介黑名单 - 第1页(20条/页)
|
||||
API类型: 若依startPage
|
||||
状态: PASS
|
||||
页码: 1/20
|
||||
返回行数: 1
|
||||
总数: 1
|
||||
预期行数: 1
|
||||
|
||||
------------------------------------------------------------
|
||||
测试结论:
|
||||
✗ 存在分页接口总数返回异常
|
||||
84
test/pagination_test_report_20260128_153235.txt
Normal file
84
test/pagination_test_report_20260128_153235.txt
Normal file
@@ -0,0 +1,84 @@
|
||||
============================================================
|
||||
分页接口总数测试报告
|
||||
============================================================
|
||||
|
||||
测试时间: 2026-01-28 15:32:35
|
||||
|
||||
测试统计:
|
||||
总测试数: 8
|
||||
通过: 7
|
||||
失败: 1
|
||||
错误: 0
|
||||
|
||||
测试接口:
|
||||
1. /dpc/employee/list - 员工列表(MyBatis Plus分页)
|
||||
2. /dpc/intermediary/list - 中介黑名单列表(若依startPage分页)
|
||||
|
||||
------------------------------------------------------------
|
||||
详细结果:
|
||||
------------------------------------------------------------
|
||||
|
||||
测试: 员工列表 - 第1页(10条/页)
|
||||
API类型: MyBatis Plus
|
||||
状态: PASS
|
||||
页码: 1/10
|
||||
返回行数: 10
|
||||
总数: 199
|
||||
预期行数: 10
|
||||
|
||||
测试: 员工列表 - 第2页(10条/页)
|
||||
API类型: MyBatis Plus
|
||||
状态: PASS
|
||||
页码: 2/10
|
||||
返回行数: 10
|
||||
总数: 199
|
||||
预期行数: 10
|
||||
|
||||
测试: 员工列表 - 第1页(5条/页)
|
||||
API类型: MyBatis Plus
|
||||
状态: PASS
|
||||
页码: 1/5
|
||||
返回行数: 5
|
||||
总数: 199
|
||||
预期行数: 5
|
||||
|
||||
测试: 员工列表 - 第1页(20条/页)
|
||||
API类型: MyBatis Plus
|
||||
状态: PASS
|
||||
页码: 1/20
|
||||
返回行数: 20
|
||||
总数: 199
|
||||
预期行数: 20
|
||||
|
||||
测试: 中介黑名单 - 第1页(10条/页)
|
||||
API类型: 若依startPage
|
||||
状态: PASS
|
||||
页码: 1/10
|
||||
返回行数: 1
|
||||
总数: 1
|
||||
预期行数: 1
|
||||
|
||||
测试: 中介黑名单 - 第2页(10条/页)
|
||||
API类型: 若依startPage
|
||||
状态: FAIL
|
||||
错误: 行数不匹配
|
||||
|
||||
测试: 中介黑名单 - 第1页(5条/页)
|
||||
API类型: 若依startPage
|
||||
状态: PASS
|
||||
页码: 1/5
|
||||
返回行数: 1
|
||||
总数: 1
|
||||
预期行数: 1
|
||||
|
||||
测试: 中介黑名单 - 第1页(20条/页)
|
||||
API类型: 若依startPage
|
||||
状态: PASS
|
||||
页码: 1/20
|
||||
返回行数: 1
|
||||
总数: 1
|
||||
预期行数: 1
|
||||
|
||||
------------------------------------------------------------
|
||||
测试结论:
|
||||
✗ 存在分页接口总数返回异常
|
||||
140
test/test_pagination.ps1
Normal file
140
test/test_pagination.ps1
Normal file
@@ -0,0 +1,140 @@
|
||||
# Pagination API Test Script
|
||||
# Test employee list pagination and total count
|
||||
|
||||
$BaseUrl = "http://localhost:8080"
|
||||
$LoginUrl = "$BaseUrl/login/test"
|
||||
$ListUrl = "$BaseUrl/dpc/employee/list"
|
||||
|
||||
# Login to get token
|
||||
$loginBody = @{
|
||||
username = "admin"
|
||||
password = "admin123"
|
||||
} | ConvertTo-Json
|
||||
|
||||
Write-Host "Logging in..." -ForegroundColor Cyan
|
||||
$loginResponse = Invoke-RestMethod -Uri $LoginUrl -Method Post -Body $loginBody -ContentType "application/json"
|
||||
$token = $loginResponse.token
|
||||
|
||||
Write-Host "Login success!" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
$headers = @{
|
||||
Authorization = "Bearer $token"
|
||||
}
|
||||
|
||||
# Test function
|
||||
function Test-Page {
|
||||
param(
|
||||
[int]$PageNum,
|
||||
[int]$PageSize
|
||||
)
|
||||
|
||||
Write-Host "========== Testing: pageNum=$PageNum, pageSize=$PageSize ==========" -ForegroundColor Yellow
|
||||
|
||||
$queryParams = @{
|
||||
pageNum = $PageNum
|
||||
pageSize = $PageSize
|
||||
}
|
||||
|
||||
$queryString = ($queryParams.GetEnumerator() | ForEach-Object { "$($_.Key)=$($_.Value)" }) -join '&'
|
||||
$url = "$ListUrl?$queryString"
|
||||
|
||||
try {
|
||||
$response = Invoke-RestMethod -Uri $url -Method Get -Headers $headers
|
||||
|
||||
$rows = $response.rows.Count
|
||||
$total = $response.total
|
||||
$code = $response.code
|
||||
|
||||
Write-Host " Response Code: $code" -ForegroundColor Cyan
|
||||
Write-Host " Returned Rows: $rows" -ForegroundColor Cyan
|
||||
Write-Host " Total Records: $total" -ForegroundColor Cyan
|
||||
|
||||
# Calculate expected values
|
||||
$expectedTotalPages = [Math]::Ceiling($total / $pageSize)
|
||||
$expectedRows = if ($PageNum -lt $expectedTotalPages) { $pageSize } elseif ($PageNum -eq $expectedTotalPages) { $total - ($pageSize * ($PageNum - 1)) } else { 0 }
|
||||
|
||||
Write-Host " Expected Rows: $expectedRows" -ForegroundColor Cyan
|
||||
Write-Host " Expected Total Pages: $expectedTotalPages" -ForegroundColor Cyan
|
||||
|
||||
# Verify
|
||||
$isCorrect = $rows -eq $expectedRows
|
||||
if ($isCorrect) {
|
||||
Write-Host " Result: CORRECT" -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host " Result: WRONG! Got $rows rows, expected $expectedRows" -ForegroundColor Red
|
||||
}
|
||||
|
||||
# Show returned employee IDs
|
||||
if ($response.rows -and $response.rows.Count -gt 0) {
|
||||
$ids = ($response.rows | ForEach-Object { $_.employeeId }) -join ', '
|
||||
Write-Host " Employee IDs: $ids" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
return @{
|
||||
Success = ($code -eq 200)
|
||||
Rows = $rows
|
||||
Total = $total
|
||||
ExpectedRows = $expectedRows
|
||||
IsCorrect = $isCorrect
|
||||
Response = $response
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Host " Error: $_" -ForegroundColor Red
|
||||
return @{
|
||||
Success = $false
|
||||
Error = $_.Exception.Message
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "================ Starting Pagination Tests ================" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
|
||||
# Test cases
|
||||
$testCases = @(
|
||||
@{ PageNum = 1; PageSize = 10; Description = "Page 1, Size 10" }
|
||||
@{ PageNum = 2; PageSize = 10; Description = "Page 2, Size 10" }
|
||||
@{ PageNum = 1; PageSize = 5; Description = "Page 1, Size 5" }
|
||||
@{ PageNum = 3; PageSize = 5; Description = "Page 3, Size 5" }
|
||||
@{ PageNum = 1; PageSize = 20; Description = "Page 1, Size 20" }
|
||||
@{ PageNum = 1; PageSize = 3; Description = "Page 1, Size 3" }
|
||||
)
|
||||
|
||||
$results = @()
|
||||
$allCorrect = $true
|
||||
|
||||
foreach ($testCase in $testCases) {
|
||||
Write-Host ""
|
||||
$result = Test-Page -PageNum $testCase.PageNum -PageSize $testCase.PageSize
|
||||
$results += [PSCustomObject]@{
|
||||
Test = $testCase.Description
|
||||
PageNum = $testCase.PageNum
|
||||
PageSize = $testCase.PageSize
|
||||
ReturnedRows = $result.Rows
|
||||
TotalRecords = $result.Total
|
||||
ExpectedRows = $result.ExpectedRows
|
||||
Correct = if ($result.IsCorrect) { "PASS" } else { "FAIL" }
|
||||
}
|
||||
|
||||
if (-not $result.IsCorrect) {
|
||||
$allCorrect = $false
|
||||
}
|
||||
|
||||
Start-Sleep -Milliseconds 200
|
||||
}
|
||||
|
||||
# Show summary
|
||||
Write-Host ""
|
||||
Write-Host "================ Test Results Summary ================" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
$results | Format-Table -AutoSize
|
||||
|
||||
Write-Host ""
|
||||
if ($allCorrect) {
|
||||
Write-Host "PASS - All tests passed! Pagination is working correctly." -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host "FAIL - Some tests failed! Please check pagination logic." -ForegroundColor Red
|
||||
}
|
||||
437
test/test_pagination.py
Normal file
437
test/test_pagination.py
Normal file
@@ -0,0 +1,437 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""分页接口总数测试脚本
|
||||
测试接口:
|
||||
1. /dpc/employee/list - 员工列表(MyBatis Plus分页)
|
||||
2. /dpc/intermediary/list - 中介黑名单列表(若依startPage分页)
|
||||
"""
|
||||
|
||||
import sys
|
||||
import io
|
||||
import requests
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
# 设置stdout编码为UTF-8
|
||||
if sys.platform == 'win32':
|
||||
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
|
||||
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8')
|
||||
|
||||
BASE_URL = "http://localhost:8080"
|
||||
LOGIN_URL = f"{BASE_URL}/login/test"
|
||||
EMPLOYEE_LIST_URL = f"{BASE_URL}/dpc/employee/list"
|
||||
INTERMEDIARY_LIST_URL = f"{BASE_URL}/dpc/intermediary/list"
|
||||
|
||||
# 测试结果存储
|
||||
test_results = []
|
||||
|
||||
|
||||
def login():
|
||||
"""登录获取token"""
|
||||
print("=" * 60)
|
||||
print("步骤1: 获取认证Token")
|
||||
print("=" * 60)
|
||||
|
||||
login_body = {
|
||||
"username": "admin",
|
||||
"password": "admin123"
|
||||
}
|
||||
|
||||
try:
|
||||
# 使用json参数发送JSON格式请求体
|
||||
response = requests.post(LOGIN_URL, json=login_body)
|
||||
print(f"请求URL: {LOGIN_URL}")
|
||||
print(f"请求参数: {login_body}")
|
||||
print(f"响应状态码: {response.status_code}")
|
||||
|
||||
data = response.json()
|
||||
if data.get("code") == 200:
|
||||
token = data.get("token")
|
||||
print(f"✓ Token获取成功: {token[:20]}...")
|
||||
return token
|
||||
else:
|
||||
print(f"✗ Token获取失败: {data.get('msg')}")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"✗ 异常: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def test_page(url, token, page_num, page_size, test_name, api_type):
|
||||
"""测试指定分页参数的接口"""
|
||||
print(f"\n========== 测试: {test_name} ==========")
|
||||
print(f"API类型: {api_type}")
|
||||
print(f"URL: {url}")
|
||||
print(f"参数: pageNum={page_num}, pageSize={page_size}")
|
||||
|
||||
params = {
|
||||
"pageNum": page_num,
|
||||
"pageSize": page_size
|
||||
}
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Bearer {token}"
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.get(url, params=params, headers=headers)
|
||||
print(f"响应状态码: {response.status_code}")
|
||||
|
||||
if response.status_code != 200:
|
||||
print(f"✗ HTTP错误: {response.text}")
|
||||
test_results.append({
|
||||
"test_name": test_name,
|
||||
"api_type": api_type,
|
||||
"status": "FAIL",
|
||||
"error": f"HTTP {response.status_code}"
|
||||
})
|
||||
return None
|
||||
|
||||
data = response.json()
|
||||
print(f"响应内容:\n{json.dumps(data, indent=2, ensure_ascii=False)}")
|
||||
|
||||
code = data.get("code", 0)
|
||||
|
||||
if code != 200:
|
||||
print(f"✗ 业务错误: {data.get('msg')}")
|
||||
test_results.append({
|
||||
"test_name": test_name,
|
||||
"api_type": api_type,
|
||||
"status": "FAIL",
|
||||
"error": data.get("msg", "Unknown error")
|
||||
})
|
||||
return None
|
||||
|
||||
# 检查响应结构 - 支持两种格式
|
||||
# 格式1: {data: {total, rows}, code, msg}
|
||||
# 格式2: {total, rows, code, msg}
|
||||
if "data" in data:
|
||||
response_data = data["data"]
|
||||
rows = response_data.get("rows", [])
|
||||
total = response_data.get("total")
|
||||
else:
|
||||
# 扁平结构格式
|
||||
rows = data.get("rows", [])
|
||||
total = data.get("total")
|
||||
|
||||
rows_count = len(rows)
|
||||
print(f"\n--- 分页数据分析 ---")
|
||||
print(f"返回行数(rows): {rows_count}")
|
||||
print(f"总数(total): {total}")
|
||||
|
||||
# 验证total字段
|
||||
if total is None:
|
||||
print(f"✗ 响应缺少total字段")
|
||||
test_results.append({
|
||||
"test_name": test_name,
|
||||
"api_type": api_type,
|
||||
"status": "FAIL",
|
||||
"error": "响应缺少total字段"
|
||||
})
|
||||
return None
|
||||
|
||||
if not isinstance(total, int):
|
||||
print(f"✗ total类型错误: {type(total)}")
|
||||
test_results.append({
|
||||
"test_name": test_name,
|
||||
"api_type": api_type,
|
||||
"status": "FAIL",
|
||||
"error": f"total类型错误: {type(total)}"
|
||||
})
|
||||
return None
|
||||
|
||||
if total < 0:
|
||||
print(f"✗ total值无效: {total}")
|
||||
test_results.append({
|
||||
"test_name": test_name,
|
||||
"api_type": api_type,
|
||||
"status": "FAIL",
|
||||
"error": f"total值无效: {total}"
|
||||
})
|
||||
return None
|
||||
|
||||
# 计算预期值
|
||||
expected_total_pages = (total + page_size - 1) // page_size
|
||||
if page_num < expected_total_pages:
|
||||
expected_rows = page_size
|
||||
elif page_num == expected_total_pages:
|
||||
expected_rows = total - (page_size * (page_num - 1))
|
||||
else:
|
||||
expected_rows = 0
|
||||
|
||||
print(f"预期行数: {expected_rows}")
|
||||
print(f"预期总页数: {expected_total_pages}")
|
||||
|
||||
# 验证行数是否正确
|
||||
is_correct = rows_count == expected_rows
|
||||
|
||||
if is_correct:
|
||||
print(f"✓ 测试通过 - 分页总数返回正常")
|
||||
test_results.append({
|
||||
"test_name": test_name,
|
||||
"api_type": api_type,
|
||||
"status": "PASS",
|
||||
"page_num": page_num,
|
||||
"page_size": page_size,
|
||||
"rows_count": rows_count,
|
||||
"total": total,
|
||||
"expected_rows": expected_rows
|
||||
})
|
||||
else:
|
||||
print(f"✗ 测试失败 - 预期{expected_rows}行,实际{rows_count}行")
|
||||
test_results.append({
|
||||
"test_name": test_name,
|
||||
"api_type": api_type,
|
||||
"status": "FAIL",
|
||||
"page_num": page_num,
|
||||
"page_size": page_size,
|
||||
"rows_count": rows_count,
|
||||
"total": total,
|
||||
"expected_rows": expected_rows,
|
||||
"error": f"行数不匹配"
|
||||
})
|
||||
|
||||
# 显示返回的ID
|
||||
if rows:
|
||||
if "employeeId" in rows[0]:
|
||||
ids = ', '.join([str(r.get("employeeId")) for r in rows])
|
||||
print(f"员工ID: {ids}")
|
||||
elif "intermediaryId" in rows[0]:
|
||||
ids = ', '.join([str(r.get("intermediaryId")) for r in rows])
|
||||
print(f"中介ID: {ids}")
|
||||
|
||||
return {
|
||||
"success": True,
|
||||
"rows": rows_count,
|
||||
"total": total,
|
||||
"expected_rows": expected_rows,
|
||||
"is_correct": is_correct
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
print(f"✗ 异常: {e}")
|
||||
test_results.append({
|
||||
"test_name": test_name,
|
||||
"api_type": api_type,
|
||||
"status": "ERROR",
|
||||
"error": str(e)
|
||||
})
|
||||
return None
|
||||
|
||||
|
||||
def test_consistency(url, token, test_name, api_type):
|
||||
"""测试不同pageSize下total是否一致"""
|
||||
print(f"\n========== 测试总数一致性: {test_name} ==========")
|
||||
|
||||
page_sizes = [10, 20, 50]
|
||||
totals = []
|
||||
|
||||
for size in page_sizes:
|
||||
params = {"pageNum": 1, "pageSize": size}
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
|
||||
try:
|
||||
response = requests.get(url, params=params, headers=headers)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("code") == 200:
|
||||
# 支持两种响应格式
|
||||
if "data" in data:
|
||||
total = data.get("data", {}).get("total")
|
||||
else:
|
||||
total = data.get("total")
|
||||
totals.append(total)
|
||||
print(f"pageSize={size}: total={total}")
|
||||
except Exception as e:
|
||||
print(f"✗ 异常: {e}")
|
||||
|
||||
if len(set(totals)) == 1 and totals[0] is not None:
|
||||
print(f"✓ 不同pageSize下总数一致: {totals[0]}")
|
||||
return True
|
||||
else:
|
||||
print(f"✗ 不同pageSize下总数不一致: {totals}")
|
||||
return False
|
||||
|
||||
|
||||
def generate_report():
|
||||
"""生成测试报告"""
|
||||
print("\n" + "=" * 60)
|
||||
print("测试报告")
|
||||
print("=" * 60)
|
||||
|
||||
# 按API类型分组
|
||||
employee_results = [r for r in test_results if "员工" in r.get("test_name", "")]
|
||||
intermediary_results = [r for r in test_results if "中介" in r.get("test_name", "")]
|
||||
|
||||
pass_count = sum(1 for r in test_results if r["status"] == "PASS")
|
||||
fail_count = sum(1 for r in test_results if r["status"] == "FAIL")
|
||||
error_count = sum(1 for r in test_results if r["status"] == "ERROR")
|
||||
|
||||
print(f"\n总测试数: {len(test_results)}")
|
||||
print(f"通过: {pass_count}")
|
||||
print(f"失败: {fail_count}")
|
||||
print(f"错误: {error_count}")
|
||||
|
||||
# 员工接口结果
|
||||
print(f"\n--- 员工列表接口 (MyBatis Plus) ---")
|
||||
print(f"测试数: {len(employee_results)}")
|
||||
for r in employee_results:
|
||||
status_icon = "✓" if r["status"] == "PASS" else "✗"
|
||||
print(f"{status_icon} {r['test_name']}: {r['status']}")
|
||||
if r["status"] == "PASS":
|
||||
print(f" 页码: {r.get('page_num')}/{r.get('page_size')}, "
|
||||
f"返回行数: {r.get('rows_count')}, 总数: {r.get('total')}")
|
||||
else:
|
||||
print(f" 错误: {r.get('error', 'Unknown')}")
|
||||
|
||||
# 中介黑名单接口结果
|
||||
print(f"\n--- 中介黑名单接口 (若依startPage) ---")
|
||||
print(f"测试数: {len(intermediary_results)}")
|
||||
for r in intermediary_results:
|
||||
status_icon = "✓" if r["status"] == "PASS" else "✗"
|
||||
print(f"{status_icon} {r['test_name']}: {r['status']}")
|
||||
if r["status"] == "PASS":
|
||||
print(f" 页码: {r.get('page_num')}/{r.get('page_size')}, "
|
||||
f"返回行数: {r.get('rows_count')}, 总数: {r.get('total')}")
|
||||
else:
|
||||
print(f" 错误: {r.get('error', 'Unknown')}")
|
||||
|
||||
# 总体结论
|
||||
print(f"\n--- 测试结论 ---")
|
||||
if fail_count == 0 and error_count == 0:
|
||||
print("✓ 所有分页接口总数返回正常")
|
||||
else:
|
||||
print("✗ 存在分页接口总数返回异常")
|
||||
|
||||
# 保存报告到文件
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
report_file = f"test/pagination_test_report_{timestamp}.txt"
|
||||
|
||||
with open(report_file, "w", encoding="utf-8") as f:
|
||||
f.write("=" * 60 + "\n")
|
||||
f.write("分页接口总数测试报告\n")
|
||||
f.write("=" * 60 + "\n\n")
|
||||
f.write(f"测试时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n")
|
||||
|
||||
f.write("测试统计:\n")
|
||||
f.write(f" 总测试数: {len(test_results)}\n")
|
||||
f.write(f" 通过: {pass_count}\n")
|
||||
f.write(f" 失败: {fail_count}\n")
|
||||
f.write(f" 错误: {error_count}\n\n")
|
||||
|
||||
f.write("测试接口:\n")
|
||||
f.write(" 1. /dpc/employee/list - 员工列表(MyBatis Plus分页)\n")
|
||||
f.write(" 2. /dpc/intermediary/list - 中介黑名单列表(若依startPage分页)\n\n")
|
||||
|
||||
f.write("-" * 60 + "\n")
|
||||
f.write("详细结果:\n")
|
||||
f.write("-" * 60 + "\n\n")
|
||||
|
||||
for r in test_results:
|
||||
f.write(f"测试: {r['test_name']}\n")
|
||||
f.write(f"API类型: {r['api_type']}\n")
|
||||
f.write(f"状态: {r['status']}\n")
|
||||
if r['status'] == 'PASS':
|
||||
f.write(f" 页码: {r.get('page_num')}/{r.get('page_size')}\n")
|
||||
f.write(f" 返回行数: {r.get('rows_count')}\n")
|
||||
f.write(f" 总数: {r.get('total')}\n")
|
||||
f.write(f" 预期行数: {r.get('expected_rows')}\n")
|
||||
else:
|
||||
f.write(f" 错误: {r.get('error', 'Unknown')}\n")
|
||||
f.write("\n")
|
||||
|
||||
f.write("-" * 60 + "\n")
|
||||
f.write("测试结论:\n")
|
||||
if fail_count == 0 and error_count == 0:
|
||||
f.write("✓ 所有分页接口总数返回正常\n")
|
||||
else:
|
||||
f.write("✗ 存在分页接口总数返回异常\n")
|
||||
|
||||
print(f"\n报告已保存至: {report_file}")
|
||||
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
print("\n" + "=" * 60)
|
||||
print("分页接口总数测试")
|
||||
print("=" * 60)
|
||||
print(f"测试时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
|
||||
# 获取token
|
||||
token = login()
|
||||
if not token:
|
||||
print("\n✗ 无法获取token,测试终止")
|
||||
return
|
||||
|
||||
print("\n✓ 登录成功,开始测试")
|
||||
|
||||
# 员工列表接口测试用例
|
||||
employee_test_cases = [
|
||||
{"page_num": 1, "page_size": 10, "desc": "员工列表 - 第1页(10条/页)"},
|
||||
{"page_num": 2, "page_size": 10, "desc": "员工列表 - 第2页(10条/页)"},
|
||||
{"page_num": 1, "page_size": 5, "desc": "员工列表 - 第1页(5条/页)"},
|
||||
{"page_num": 1, "page_size": 20, "desc": "员工列表 - 第1页(20条/页)"},
|
||||
]
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("测试员工列表接口(MyBatis Plus分页)")
|
||||
print("=" * 60)
|
||||
|
||||
for test_case in employee_test_cases:
|
||||
test_page(
|
||||
EMPLOYEE_LIST_URL,
|
||||
token,
|
||||
test_case["page_num"],
|
||||
test_case["page_size"],
|
||||
test_case["desc"],
|
||||
"MyBatis Plus"
|
||||
)
|
||||
|
||||
# 测试总数一致性
|
||||
test_consistency(
|
||||
EMPLOYEE_LIST_URL,
|
||||
token,
|
||||
"员工列表-总数一致性",
|
||||
"MyBatis Plus"
|
||||
)
|
||||
|
||||
# 中介黑名单接口测试用例
|
||||
intermediary_test_cases = [
|
||||
{"page_num": 1, "page_size": 10, "desc": "中介黑名单 - 第1页(10条/页)"},
|
||||
{"page_num": 2, "page_size": 10, "desc": "中介黑名单 - 第2页(10条/页)"},
|
||||
{"page_num": 1, "page_size": 5, "desc": "中介黑名单 - 第1页(5条/页)"},
|
||||
{"page_num": 1, "page_size": 20, "desc": "中介黑名单 - 第1页(20条/页)"},
|
||||
]
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("测试中介黑名单接口(若依startPage分页)")
|
||||
print("=" * 60)
|
||||
|
||||
for test_case in intermediary_test_cases:
|
||||
test_page(
|
||||
INTERMEDIARY_LIST_URL,
|
||||
token,
|
||||
test_case["page_num"],
|
||||
test_case["page_size"],
|
||||
test_case["desc"],
|
||||
"若依startPage"
|
||||
)
|
||||
|
||||
# 测试总数一致性
|
||||
test_consistency(
|
||||
INTERMEDIARY_LIST_URL,
|
||||
token,
|
||||
"中介黑名单-总数一致性",
|
||||
"若依startPage"
|
||||
)
|
||||
|
||||
# 生成报告
|
||||
generate_report()
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("测试完成")
|
||||
print("=" * 60)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user