Javascript 使用FE的令牌以更好的方式组织测试

Javascript 使用FE的令牌以更好的方式组织测试,javascript,cypress,web-api-testing,Javascript,Cypress,Web Api Testing,我目前正在使用Cypress测试一些微服务。为了测试RESTAPI,我需要一个令牌来发出请求。此令牌仅通过下面给出的本地FE图像可用 我必须访问此FE才能获取令牌-没有其他方法访问此访问令牌 现在我就这样做 describe('Do some test',()=>{ it('first test',()=>{ //this fetches the value of the token from FE. cy.get('css locator of the

我目前正在使用Cypress测试一些微服务。为了测试RESTAPI,我需要一个令牌来发出请求。此令牌仅通过下面给出的本地FE图像可用

我必须访问此FE才能获取令牌-没有其他方法访问此访问令牌

现在我就这样做

describe('Do some test',()=>{
    it('first test',()=>{
    //this fetches the value of the token from FE.

     cy.get('css locator of the access token').invoke('val').then((token)=>{
       let tok = token;
      cy.request({
        method: 'GET' //or POST
        url: "http://localhost:3001/v1/api1.json",
        headers:{
         "Authorization": "Bearer "+token;
         "Content-Type":"application/json"
            }
               }).as('firsttest').then(()=>{
                             cy.get('@firsttest').its('status').should('eql',200);               
                                           })
          })
     })
})
describe('Do first test',()=>{
     beforeEach(()=>{
     cy.get('get locator of the token').invoke('val').then((token)=>{
        let tok = token;
     })
})

   it('fetch and use token',()=>{
      cy.request({
      method: 'GET' //or POST
      url : 'http://someurl/path',
      headers :{
        "Authorization": "Bearer "+token;  (from beforeEach block)
      }
     })
   })

it('do another test using same token',()=>{
   //do something
 })

})
现在,这可以工作了,我得到了正确的状态和所有信息,但我知道这不是组织测试的好方法,而且会导致大量重复,因为如果我要移出
it
块,我必须一次又一次地获取令牌

我如何组织它,使其能够获取
标记
值一次,然后在测试中使用它。。像这样的东西

describe('Do some test',()=>{
    it('first test',()=>{
    //this fetches the value of the token from FE.

     cy.get('css locator of the access token').invoke('val').then((token)=>{
       let tok = token;
      cy.request({
        method: 'GET' //or POST
        url: "http://localhost:3001/v1/api1.json",
        headers:{
         "Authorization": "Bearer "+token;
         "Content-Type":"application/json"
            }
               }).as('firsttest').then(()=>{
                             cy.get('@firsttest').its('status').should('eql',200);               
                                           })
          })
     })
})
describe('Do first test',()=>{
     beforeEach(()=>{
     cy.get('get locator of the token').invoke('val').then((token)=>{
        let tok = token;
     })
})

   it('fetch and use token',()=>{
      cy.request({
      method: 'GET' //or POST
      url : 'http://someurl/path',
      headers :{
        "Authorization": "Bearer "+token;  (from beforeEach block)
      }
     })
   })

it('do another test using same token',()=>{
   //do something
 })

})

或者更简单地说,获取
令牌的重复性最小化。

您可以在support/command.js中创建一个自定义方法。例如,这里创建了一个名为“Newlogin”的自定义方法

Cypress.Commands.add('Newlogin', (email, password,env) => {
    Cypress.log({
      name: 'loginViaAuth0',
    });
        const options = {
        method: 'POST',
        url: env+'/oauth/token',   // Token Url
        failOnStatusCode: false,
        form:true,
        "body":'grant_type=password&userName='+email+'&Password='+password+'
      }; 
      cy.request(options)  
  });
现在,您可以在任何地方使用cy链接访问此方法

cy.Newlogin(username, password, env) /*Custom method defined in supports/command.js */
            .its('body')
            .then((resp) => {
                resp = JSON.stringify(resp)
                cy.log(resp)
                const token = JSON.parse(resp).access_token
});

下面是一个工作示例,详细说明这些评论。它假定包含令牌的UI将始终存在于每个测试中

此解决方案的问题在于,在每次测试之前将令牌检索逻辑放入
将有效防止测试开始时的
cy.visit
。因此,要么将
cy.visit
放在
beforeach
(在
cy.get()
上方)中,要么提出不同的解决方案

//cypress/support/index.js
//重写“cy.request”以自动提供授权标头
// ----------------------------------------------------------------------
const AuthorizationToken=Symbol();
overwrite('request',(origFn,…args)=>{
//规范化参数
// --------------------------------------------------------------------
让我们选择;
如果(args.length==1){
opts=typeof args[0]=“string”?{url:args[0]}:args[0];
}否则{
opts=args.length==2
?{url:args[0],正文:args[1]}
:{方法:args[0],url:args[1],正文:args[2]}
}
//设置辅助标题(如果存在)
// --------------------------------------------------------------------
if(cy.request[授权令牌]){
opts.headers={
“授权”:“持有人”+cy.request[AuthorizationToken],
…选择标题
};
}
// --------------------------------------------------------------------
返回origFn(opts);
});
在每个之前(()=>{
//(1)设置(用于演示)
// ----------------------------------------------------------------------
cy.document().然后(doc=>{
doc.body.innerHTML='2as24flx9';
});
//(2)实际代码
// ----------------------------------------------------------------------
cy.get('.token')。invoke('text')。然后(token=>{
cy.request[AuthorizationToken]=令牌;
});
});

所以您基本上希望确保所有
cy.request
调用自动提供
Auhtorization
头?在您的情况下,将
之前的
(获取令牌)和覆盖
cy.request
(确保设置了标题)相结合会起作用吗?我认为这是要点。只需要一个小的澄清-每个
之前的
块必须位于测试的
描述
部分,对吗?或者您是否将其包含在
index.js
文件本身中。不,不需要。摩卡允许这样做。