215 lines
6.2 KiB
JavaScript
215 lines
6.2 KiB
JavaScript
/**
|
||
* k6 压测脚本 - 场景一:普通用户浏览
|
||
*
|
||
* 模拟用户行为:
|
||
* 1. 进入首页 -> 获取轮播图、榜单分类、主播榜单、直播列表
|
||
* 2. 进入社区 -> 获取帖子列表
|
||
* 3. 查看帖子 -> 获取帖子详情、评论列表
|
||
* 4. 翻页浏览 -> 加载更多帖子
|
||
*
|
||
* 运行命令:
|
||
* k6 run --out web-dashboard scenario-browse.js
|
||
*
|
||
* 快速测试:
|
||
* k6 run --out web-dashboard -e QUICK_TEST=true scenario-browse.js
|
||
*/
|
||
|
||
import { BROWSE_OPTIONS, QUICK_TEST_OPTIONS, TEST_DATA } from './config.js';
|
||
import {
|
||
httpGet,
|
||
checkResponse,
|
||
parseResponse,
|
||
thinkTime,
|
||
shortWait,
|
||
getTokenCount,
|
||
API
|
||
} from './utils/helpers.js';
|
||
|
||
// ============================================
|
||
// 压测配置
|
||
// ============================================
|
||
|
||
const isQuickTest = __ENV.QUICK_TEST === 'true';
|
||
|
||
export const options = isQuickTest ? QUICK_TEST_OPTIONS : BROWSE_OPTIONS;
|
||
|
||
// ============================================
|
||
// 初始化阶段(每个 VU 执行一次)
|
||
// ============================================
|
||
|
||
export function setup() {
|
||
const tokenCount = getTokenCount();
|
||
console.log(`========================================`);
|
||
console.log(`场景:普通用户浏览(读操作为主)`);
|
||
console.log(`Token 数量:${tokenCount}`);
|
||
console.log(`模式:${isQuickTest ? '快速测试' : '正式压测'}`);
|
||
console.log(`========================================`);
|
||
|
||
if (tokenCount === 0) {
|
||
throw new Error('没有可用的 Token,请先在 tokens.txt 中添加 Token');
|
||
}
|
||
|
||
return { tokenCount };
|
||
}
|
||
|
||
// ============================================
|
||
// 主测试函数(每个 VU 循环执行)
|
||
// ============================================
|
||
|
||
export default function(data) {
|
||
const vuId = __VU;
|
||
|
||
// 存储动态获取的数据
|
||
let postIds = [];
|
||
|
||
// ==================
|
||
// 步骤1: 首页数据加载
|
||
// ==================
|
||
|
||
// 1.1 获取轮播图
|
||
let res = httpGet(API.HOME.BANNERS, {}, vuId);
|
||
checkResponse(res, 'GetBanners');
|
||
shortWait();
|
||
|
||
// 1.2 获取主播榜单分类
|
||
res = httpGet(API.HOME.CATEGORIES, {}, vuId);
|
||
checkResponse(res, 'StreamerCategories');
|
||
shortWait();
|
||
|
||
// 1.3 获取主播榜单
|
||
res = httpGet(API.HOME.RANKINGS, {
|
||
category: TEST_DATA.category,
|
||
limit: TEST_DATA.rankingLimit,
|
||
}, vuId);
|
||
checkResponse(res, 'Rankings');
|
||
shortWait();
|
||
|
||
// 1.4 获取直播中主播列表
|
||
res = httpGet(API.HOME.LIVE_STREAMERS, {
|
||
page: 1,
|
||
pageSize: 10,
|
||
}, vuId);
|
||
checkResponse(res, 'LiveStreamers');
|
||
|
||
// 模拟用户在首页浏览的思考时间
|
||
thinkTime();
|
||
|
||
// ==================
|
||
// 步骤2: 社区帖子列表
|
||
// ==================
|
||
|
||
// 2.1 获取帖子列表(第1页)
|
||
res = httpGet(API.POSTS.LIST, {
|
||
SortType: 1,
|
||
PageIndex: 1,
|
||
PageSize: TEST_DATA.pageSize,
|
||
}, vuId);
|
||
checkResponse(res, 'GetPosts-Page1');
|
||
|
||
// 解析帖子列表,提取帖子ID
|
||
const postsData = parseResponse(res);
|
||
if (postsData && postsData.items && postsData.items.length > 0) {
|
||
postIds = postsData.items.map(item => item.postId);
|
||
}
|
||
|
||
thinkTime();
|
||
|
||
// 2.2 获取帖子列表(第2页,模拟翻页)
|
||
res = httpGet(API.POSTS.LIST, {
|
||
SortType: 1,
|
||
PageIndex: 2,
|
||
PageSize: TEST_DATA.pageSize,
|
||
}, vuId);
|
||
checkResponse(res, 'GetPosts-Page2');
|
||
|
||
// 追加更多帖子ID
|
||
const postsData2 = parseResponse(res);
|
||
if (postsData2 && postsData2.items && postsData2.items.length > 0) {
|
||
postIds = postIds.concat(postsData2.items.map(item => item.postId));
|
||
}
|
||
|
||
thinkTime();
|
||
|
||
// ==================
|
||
// 步骤3: 查看帖子详情
|
||
// ==================
|
||
|
||
if (postIds.length > 0) {
|
||
// 随机选择一个帖子查看详情
|
||
const randomIndex = Math.floor(Math.random() * postIds.length);
|
||
const postId = postIds[randomIndex];
|
||
|
||
// 3.1 获取帖子详情
|
||
res = httpGet(API.POSTS.DETAIL, {
|
||
PostId: postId,
|
||
}, vuId);
|
||
checkResponse(res, 'GetPostDetail');
|
||
shortWait();
|
||
|
||
// 3.2 获取评论列表(第1页)
|
||
res = httpGet(API.COMMENTS.LIST, {
|
||
PostId: postId,
|
||
SortType: 2,
|
||
PageIndex: 1,
|
||
PageSize: TEST_DATA.commentPageSize,
|
||
}, vuId);
|
||
checkResponse(res, 'GetPostComments-Page1');
|
||
|
||
thinkTime();
|
||
|
||
// 3.3 获取评论列表(第2页,模拟加载更多评论)
|
||
res = httpGet(API.COMMENTS.LIST, {
|
||
PostId: postId,
|
||
SortType: 2,
|
||
PageIndex: 2,
|
||
PageSize: TEST_DATA.commentPageSize,
|
||
}, vuId);
|
||
checkResponse(res, 'GetPostComments-Page2');
|
||
|
||
thinkTime();
|
||
|
||
// 3.4 查看另一个帖子(如果有)
|
||
if (postIds.length > 1) {
|
||
const anotherIndex = (randomIndex + 1) % postIds.length;
|
||
const anotherPostId = postIds[anotherIndex];
|
||
|
||
res = httpGet(API.POSTS.DETAIL, {
|
||
PostId: anotherPostId,
|
||
}, vuId);
|
||
checkResponse(res, 'GetPostDetail-2');
|
||
shortWait();
|
||
|
||
res = httpGet(API.COMMENTS.LIST, {
|
||
PostId: anotherPostId,
|
||
SortType: 2,
|
||
PageIndex: 1,
|
||
PageSize: TEST_DATA.commentPageSize,
|
||
}, vuId);
|
||
checkResponse(res, 'GetPostComments-Another');
|
||
}
|
||
}
|
||
|
||
// ==================
|
||
// 步骤4: 查看更多排行
|
||
// ==================
|
||
|
||
res = httpGet(API.HOME.RANKINGS_MORE, {
|
||
category: TEST_DATA.category,
|
||
page: 1,
|
||
pageSize: 20,
|
||
}, vuId);
|
||
checkResponse(res, 'RankingsMore');
|
||
|
||
thinkTime();
|
||
}
|
||
|
||
// ============================================
|
||
// 结束阶段
|
||
// ============================================
|
||
|
||
export function teardown(data) {
|
||
console.log(`========================================`);
|
||
console.log(`压测结束`);
|
||
console.log(`========================================`);
|
||
}
|