/** * 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(`========================================`); }