在Chakram接口测试中,如何从Mocha describe块导出变量?
How to Export CSRF Token Variable for Other Test Cases in Chakram?
Problem Description
我目前正在使用Chakram API测试框架测试部分REST API端点。第一个API用于获取CSRF token,该token需在其余端点的请求头中使用。该CSRF API返回如下格式的JSON对象:
{ "csrf_token": "Aajkndaknsda99/adjaj29adja" }
我当前的实现代码如下:
describe('Hits the CSRF API to get the token',()=>{ let csrf_tok; before(()=>{ return chakram.wait(response = chakram.get(API_ENDPOINT, headers)); }); it('gets the csrf token from the response', () => { // 提取token的逻辑 expect(response).to.have.status(200); expect(response.body).to.have.property('csrf_token'); csrf_tok = response.body.csrf_token; }); });
我希望将此代码块中的csrf_tok变量导出,供其他测试用例使用,请问该如何实现?
Solutions
在Chakram(它基于Mocha测试框架)中,共享跨测试套件的变量有几种可靠的方式,我给你列举最常用的三种:
1. 使用全局变量(简单直接,适合小型测试项目)
把csrf_tok定义在所有describe块的外部,让它成为全局作用域的变量,这样其他测试文件就能直接访问它。注意要确保获取token的测试在其他依赖它的测试之前执行(Mocha默认按文件顺序执行,你可以用--file参数指定执行顺序)。
示例代码:
// 在所有测试文件最外层定义全局变量 let globalCsrfToken; describe('Hits the CSRF API to get the token',()=>{ before(()=>{ return chakram.wait(chakram.get(API_ENDPOINT, headers)) .then(response => { globalCsrfToken = response.body.csrf_token; }); }); it('successfully retrieves the CSRF token', () => { expect(globalCsrfToken).to.not.be.undefined; }); }); // 另一个测试文件或测试套件 describe('Test protected API endpoint', () => { it('uses the CSRF token in request headers', () => { const protectedRequest = chakram.get(PROTECTED_API_ENDPOINT, { headers: { 'X-CSRF-Token': globalCsrfToken } }); return chakram.wait(protectedRequest) .then(response => { expect(response).to.have.status(200); }); }); });
2. 使用Mocha的共享上下文(适合同一测试文件内的共享,或通过模块导出上下文)
Mocha允许在before/beforeEach钩子中通过this关键字设置共享变量,不过要注意不能用箭头函数,因为箭头函数不会绑定Mocha的上下文。如果要跨文件共享,可以把上下文封装成模块导出。
示例代码:
// csrf-context.js const chakram = require('chakram'); const API_ENDPOINT = 'your-csrf-api-url'; const headers = {}; // 你的请求头 let csrfContext = {}; before(function() { return chakram.wait(chakram.get(API_ENDPOINT, headers)) .then(response => { csrfContext.token = response.body.csrf_token; }); }); module.exports = csrfContext; // 其他测试文件 const csrfContext = require('./csrf-context'); describe('Test protected endpoint', () => { it('uses shared CSRF token', () => { const request = chakram.get(PROTECTED_URL, { headers: { 'X-CSRF-Token': csrfContext.token } }); return chakram.wait(request).then(res => expect(res).to.have.status(200)); }); });
3. 封装成可复用的函数(最优雅,避免全局变量污染)
创建一个单独的工具模块,写一个函数来获取并返回CSRF token,其他测试用例在需要的时候调用这个函数。这个方法还能处理token过期的情况,自动重新获取。
示例代码:
// csrf-helper.js const chakram = require('chakram'); const API_ENDPOINT = 'your-csrf-api-url'; const headers = {}; let cachedToken; let tokenExpiry; // 如果token有过期时间,可以加上这个 async function getCsrfToken() { // 如果token存在且未过期,直接返回 if (cachedToken && Date.now() < tokenExpiry) { return cachedToken; } // 否则重新获取 const response = await chakram.wait(chakram.get(API_ENDPOINT, headers)); expect(response).to.have.status(200); expect(response.body).to.have.property('csrf_token'); cachedToken = response.body.csrf_token; // 如果API返回过期时间,设置tokenExpiry,比如: // tokenExpiry = Date.now() + (response.body.expires_in * 1000); return cachedToken; } module.exports = { getCsrfToken }; // 其他测试文件 const { getCsrfToken } = require('./csrf-helper'); describe('Test protected API', () => { it('sends request with valid CSRF token', async () => { const token = await getCsrfToken(); const response = await chakram.wait(chakram.get(PROTECTED_URL, { headers: { 'X-CSRF-Token': token } })); expect(response).to.have.status(200); }); });
注意事项
- 确保获取CSRF token的测试在所有依赖它的测试之前执行,Mocha默认按文件顺序执行,你可以用
mocha --file csrf-test.js other-tests.js来强制顺序。 - 第三种方法(工具函数)是最推荐的,因为它更模块化,容易维护,还能处理token刷新的场景。
内容的提问来源于stack exchange,提问作者demouser123
相关产品推荐
相关产品推荐

