本文档介绍在云压测脚本模式中常用的 JavaScript 基础语法,包括变量声明、条件语句、错误处理(try/catch)、循环语句和数组操作等。这些基础语法是编写压测脚本的基础,掌握这些内容有助于构建更强大的压测脚本。
变量声明
在压测脚本中,可以使用
var、let 或 const 声明变量:var:函数作用域变量(不推荐使用)。let:块作用域变量,可以重新赋值。const:块作用域常量,声明后不能重新赋值。使用前提
所有代码需放在
export default function() 函数中执行。变量名需符合 JavaScript 标识符规范。
建议使用
const 声明不会改变的变量,使用 let 声明需要重新赋值的变量。示例
示例1:变量声明和使用
本示例演示如何声明和使用变量,适用于需要在脚本中存储和操作数据的场景。
import http from 'pts/http';export default function () {// 使用 const 声明常量const baseUrl = 'http://example.com/api';const apiKey = 'your-api-key';// 使用 let 声明可变变量let requestCount = 0;let lastResponse = null;// 使用变量构建请求const resp = http.get(`${baseUrl}/users`, {headers: {'Authorization': `Bearer ${apiKey}`}});// 更新变量值requestCount++;lastResponse = resp;console.log(`请求次数: ${requestCount}`);console.log(`响应状态: ${lastResponse.statusCode}`);}
示例2:变量作用域
本示例演示变量的作用域,适用于需要理解变量可见性的场景。
export default function () {// 函数作用域变量const globalVar = 'I am global in this function';if (true) {// 块作用域变量const blockVar = 'I am in block scope';let mutableVar = 'I can be changed';console.log(globalVar); // 可以访问console.log(blockVar); // 可以访问mutableVar = 'Changed value';}// console.log(blockVar); // 错误:blockVar 不可访问// console.log(mutableVar); // 错误:mutableVar 不可访问}
条件语句
函数说明
条件语句用于根据不同的条件执行不同的代码,在压测脚本中常用于:
根据响应状态码执行不同逻辑。
根据数据内容进行分支处理。
实现错误处理和重试机制。
控制脚本执行流程。
使用前提
所有代码需放在
export default function() 函数中执行。条件表达式需返回布尔值或可转换为布尔值的值。
语法说明
if (condition) { ... }:单条件判断。if (condition) { ... } else { ... }:双分支判断。if (condition1) { ... } else if (condition2) { ... } else { ... }:多分支判断。switch (value) { case ...: ... break; default: ... }:多值判断。示例
示例1:基本条件判断
本示例演示如何使用 if/else 进行条件判断,适用于根据响应状态执行不同逻辑的场景。
import http from 'pts/http';import { check } from 'pts';export default function () {const resp = http.get('http://example.com/api/user');// 根据状态码执行不同逻辑if (resp.statusCode === 200) {console.log('请求成功');const data = resp.json();console.log('用户数据:', data);} else if (resp.statusCode === 404) {console.log('用户不存在');} else if (resp.statusCode === 401) {console.log('未授权,需要登录');} else {console.log('请求失败,状态码:', resp.statusCode);}// 使用三元运算符const message = resp.statusCode === 200 ? '成功' : '失败';console.log('请求结果:', message);}
示例2:使用 switch 语句
本示例演示如何使用 switch 语句处理多个值的情况,适用于需要根据特定值执行不同操作的场景。
import http from 'pts/http';export default function () {const resp = http.get('http://example.com/api/status');const status = resp.json().status;switch (status) {case 'active':console.log('状态:活跃');// 执行活跃状态相关操作break;case 'inactive':console.log('状态:非活跃');// 执行非活跃状态相关操作break;case 'pending':console.log('状态:待处理');// 执行待处理状态相关操作break;default:console.log('未知状态:', status);}}
示例3:复杂条件判断
本示例演示如何进行复杂的条件判断,适用于需要组合多个条件的场景。
import http from 'pts/http';import { check } from 'pts';export default function () {const resp = http.get('http://example.com/api/data');// 组合多个条件if (resp.statusCode === 200 && resp.body) {const data = resp.json();if (data.success === true && data.items && data.items.length > 0) {console.log('数据获取成功,共', data.items.length, '条记录');} else {console.log('数据为空或格式不正确');}} else {console.log('请求失败或响应为空');}// 使用逻辑运算符const isValid = resp.statusCode >= 200 && resp.statusCode < 300;const hasData = resp.body && resp.body.length > 0;if (isValid && hasData) {check('响应有效', () => true);}}
错误处理(try/catch)
函数说明
try/catch 语句用于捕获和处理代码执行过程中可能出现的错误,在压测脚本中常用于:捕获 JSON 解析错误。
处理网络请求异常。
处理数据格式错误。
实现优雅的错误处理和日志记录。
防止脚本因单个错误而中断执行。
使用前提
所有代码需放在
export default function() 函数中执行try 块中可能抛出错误的代码。catch 块用于捕获和处理错误。语法说明
try { ... } catch (error) { ... }:基本错误捕获error.message:获取错误消息。error.stack:获取错误堆栈信息(如果可用)。示例
示例1:捕获 JSON 解析错误
本示例演示如何使用 try/catch 捕获 JSON 解析错误,适用于处理可能格式不正确的响应数据。
import http from 'pts/http';export default function () {const resp = http.get('http://example.com/api/data');try {// 尝试解析 JSON,如果格式不正确会抛出异常const data = JSON.parse(resp.body);console.log('解析成功:', data);// 使用解析后的数据if (data.items) {console.log('数据项数量:', data.items.length);}} catch (error) {// 捕获解析错误console.error('JSON 解析失败:', error.message);console.log('原始响应体:', resp.body);}}
示例2:处理 HTTP 请求错误
本示例演示如何使用 try/catch 处理 HTTP 请求可能出现的错误,适用于需要优雅处理网络异常的场景。
import http from 'pts/http';export default function () {try {const resp = http.get('http://example.com/api/user');if (resp.statusCode === 200) {const userData = resp.json();console.log('用户信息:', userData);} else {console.log('请求失败,状态码:', resp.statusCode);}} catch (error) {console.error('请求处理出错:', error.message);// 可以在这里实现重试逻辑或记录错误日志}}
示例3:多层错误处理
本示例演示如何进行多层错误处理,适用于需要区分不同类型错误的场景。
import http from 'pts/http';export default function () {try {const resp = http.get('http://example.com/api/data');try {const data = resp.json();try {// 访问可能不存在的嵌套属性const value = data.user.profile.email;console.log('邮箱:', value);} catch (error) {console.error('访问嵌套属性失败:', error.message);// 使用默认值console.log('使用默认邮箱');}} catch (error) {console.error('JSON 解析失败:', error.message);}} catch (error) {console.error('请求失败:', error.message);}}
示例4:错误处理和重试机制结合
本示例演示如何将错误处理与重试机制结合,适用于需要自动重试失败请求的场景。
import http from 'pts/http';import { sleep } from 'pts';export default function () {const maxRetries = 3;let lastError = null;for (let attempt = 1; attempt <= maxRetries; attempt++) {try {console.log(`尝试第 ${attempt} 次请求`);const resp = http.get('http://example.com/api/data');if (resp.statusCode === 200) {const data = resp.json();console.log('请求成功:', data);lastError = null; // 清除错误break; // 成功则退出循环} else {// 状态码不是 200,记录错误信息lastError = new Error(`HTTP 状态码: ${resp.statusCode}`);console.error(`第 ${attempt} 次尝试失败:`, lastError.message);}} catch (error) {lastError = error;console.error(`第 ${attempt} 次尝试失败:`, error.message);}if (lastError && attempt < maxRetries) {console.log(`等待 1 秒后重试...`);sleep(1);}}if (lastError) {console.error('所有重试均失败,最后错误:', lastError.message);}}
循环语句
函数说明
循环语句用于重复执行代码,在压测脚本中常用于:
遍历数组或对象。
批量发送请求。
实现重试机制。
处理列表数据。
使用前提
所有代码需放在
export default function() 函数中执行。循环条件需能正确终止,避免无限循环。
注意循环性能,避免在循环中进行耗时操作。
语法说明
for (init; condition; increment) { ... }:传统 for 循环。for (item of array) { ... }:for...of 循环(遍历数组)。for (key in object) { ... }:for...in 循环(遍历对象)。while (condition) { ... }:while 循环。array.forEach((item, index) => { ... }):数组 forEach 方法。示例
示例1:for 循环遍历数组
本示例演示如何使用 for 循环遍历数组,适用于需要逐个处理数组元素的场景。
import http from 'pts/http';export default function () {// 定义用户 ID 数组const userIds = ['1001', '1002', '1003', '1004', '1005'];// 使用传统 for 循环for (let i = 0; i < userIds.length; i++) {const userId = userIds[i];const resp = http.get(`http://example.com/api/users/${userId}`);console.log(`用户 ${userId} 信息:`, resp.json());}}
示例2:for...of 循环
本示例演示如何使用 for...of 循环遍历数组,适用于需要简洁语法的场景。
import http from 'pts/http';import { sleep } from 'pts';export default function () {const endpoints = ['/api/users','/api/products','/api/orders'];// 使用 for...of 循环for (const endpoint of endpoints) {const resp = http.get(`http://example.com${endpoint}`);console.log(`请求 ${endpoint},状态码:`, resp.statusCode);sleep(1); // 每次请求间隔 1 秒}}
示例3:forEach 方法
本示例演示如何使用 forEach 方法遍历数组,适用于需要对每个元素执行操作的场景。
import http from 'pts/http';export default function () {const products = [{ id: 1, name: 'Product A' },{ id: 2, name: 'Product B' },{ id: 3, name: 'Product C' }];// 使用 forEach 方法products.forEach((product, index) => {console.log(`处理产品 ${index + 1}:`, product.name);const resp = http.post('http://example.com/api/products', {body: JSON.stringify(product)});console.log(`产品 ${product.id} 创建结果:`, resp.statusCode);});}
示例4:while 循环实现重试
本示例演示如何使用 while 循环实现重试机制,适用于需要重试失败请求的场景。
import http from 'pts/http';import { sleep } from 'pts';export default function () {let retryCount = 0;const maxRetries = 3;let resp = null;// 使用 while 循环实现重试while (retryCount < maxRetries) {resp = http.get('http://example.com/api/data');if (resp.statusCode === 200) {console.log('请求成功');break; // 成功则退出循环}retryCount++;console.log(`请求失败,第 ${retryCount} 次重试`);sleep(1); // 等待 1 秒后重试}if (resp && resp.statusCode !== 200) {console.log('重试失败,最终状态码:', resp.statusCode);}}
数组操作
函数说明
数组是 JavaScript 中常用的数据结构,在压测脚本中常用于:
存储多个数据项。
批量处理数据。
参数化测试数据。
收集和处理响应数据。
使用前提
所有代码需放在
export default function() 函数中执行。数组索引从0开始。
数组可以包含任意类型的元素。
常用方法
array.length:获取数组长度。array.push(item):向数组末尾添加元素。array.pop():移除并返回数组最后一个元素。array.shift():移除并返回数组第一个元素。array.unshift(item):向数组开头添加元素。array.map(fn):映射数组元素。array.filter(fn):过滤数组元素。array.find(fn):查找数组元素。array.includes(item):检查数组是否包含元素。示例
示例1:数组声明和基本操作
本示例演示如何声明数组并进行基本操作,适用于需要存储和操作多个数据的场景。
import http from 'pts/http';export default function () {// 声明数组的多种方式const numbers = [1, 2, 3, 4, 5];const strings = ['apple', 'banana', 'orange'];const mixed = [1, 'hello', true, { key: 'value' }];// 访问数组元素console.log('第一个数字:', numbers[0]); // 输出: 1console.log('数组长度:', numbers.length); // 输出: 5// 修改数组元素numbers[0] = 10;console.log('修改后的数组:', numbers);// 添加元素numbers.push(6);console.log('添加元素后:', numbers);}
示例2:数组遍历和处理
本示例演示如何遍历数组并处理每个元素,适用于批量处理数据的场景。
import http from 'pts/http';export default function () {// 定义用户 ID 数组const userIds = ['1001', '1002', '1003'];const results = [];// 遍历数组并处理for (const userId of userIds) {const resp = http.get(`http://example.com/api/users/${userId}`);if (resp.statusCode === 200) {const userData = resp.json();results.push({userId: userId,name: userData.name,status: 'success'});} else {results.push({userId: userId,status: 'failed',statusCode: resp.statusCode});}}console.log('处理结果:', results);console.log('成功数量:', results.filter(r => r.status === 'success').length);}
示例3:数组方法的使用
本示例演示如何使用数组的高级方法,适用于需要转换、过滤和查找数据的场景。
import http from 'pts/http';export default function () {// 原始数据const products = [{ id: 1, name: 'Product A', price: 100 },{ id: 2, name: 'Product B', price: 200 },{ id: 3, name: 'Product C', price: 150 }];// 使用 map 转换数组const productNames = products.map(p => p.name);console.log('产品名称:', productNames);// 使用 filter 过滤数组const expensiveProducts = products.filter(p => p.price > 150);console.log('高价产品:', expensiveProducts);// 使用 find 查找元素const product = products.find(p => p.id === 2);console.log('找到的产品:', product);// 使用 includes 检查元素const hasProductA = productNames.includes('Product A');console.log('是否包含 Product A:', hasProductA);}
示例4:动态构建数组
本示例演示如何动态构建数组,适用于需要根据条件或循环生成数据的场景。
import http from 'pts/http';import util from 'pts/util';export default function () {// 动态生成用户 ID 数组const userIds = [];for (let i = 1; i <= 10; i++) {userIds.push(`user_${i}`);}console.log('生成的用户 ID:', userIds);// 从响应中提取数据构建数组const resp = http.get('http://example.com/api/users');const users = resp.json().users || [];// 提取用户 ID 数组const extractedIds = users.map(user => user.id);console.log('提取的用户 ID:', extractedIds);// 使用数组存储请求结果const requestResults = [];for (const userId of userIds.slice(0, 5)) { // 只处理前 5 个const userResp = http.get(`http://example.com/api/users/${userId}`);requestResults.push({userId: userId,statusCode: userResp.statusCode,success: userResp.statusCode === 200});}console.log('请求结果统计:', {total: requestResults.length,success: requestResults.filter(r => r.success).length,failed: requestResults.filter(r => !r.success).length});}