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

问题描述 投票:0回答:2

我目前正在使用赛普拉斯测试一些微服务。要测试REST api,我需要一个令牌来发出请求。此令牌仅可通过本地FE使用-下面给出的图片

Token Image

我必须访问此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);               
                                           })
          })
     })
})

现在,此方法有效,并且我得到了正确的状态以及所有信息,但是我知道这不是组织测试的好方法,而且还会导致很多重复,因为如果我要移动的话,我必须一次又一次地获取令牌在it块之外。

如何组织这种方式,使我可以一次获取token值,然后在测试中使用它。.类似这样的东西

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
 })

})

或者进一步简化为使获得token的重复性最小化。

javascript cypress web-api-testing
2个回答
0
投票

您可以在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
});

0
投票

详细阐述评论,这是一个有效的示例。它假定包含令牌的UI将始终存在于每个测试中。

此解决方案的问题在于,将令牌检索逻辑放入beforeEach将有效地防止在测试开始时出现cy.visit。因此,可以将cy.visit放入beforeEach(在cy.get()之上),或者提出其他解决方案。

// cypress/support/index.js

// override the `cy.request` to automatically supply the Authorization header
// ----------------------------------------------------------------------
const AuthorizationToken = Symbol();
Cypress.Commands.overwrite('request', (origFn, ...args) => {
  // normalize arguments
  // --------------------------------------------------------------------
  let opts;
  if ( args.length === 1 ) {
    opts = typeof args[0] === 'string' ? { url: args[0] } : args[0];
  } else {
    opts = args.length === 2
      ? { url: args[0], body: args[1] }
      : { method: args[0], url: args[1], body: args[2] }
  }
  // set the Auhtorization header (if exists)
  // --------------------------------------------------------------------
  if ( cy.request[AuthorizationToken] ) {
    opts.headers = {
      'Authorization': 'Bearer ' + cy.request[AuthorizationToken],
      ...opts.headers
    };
  }
  // --------------------------------------------------------------------
  return origFn(opts);
});

beforeEach(() => {
  // (1) setup (for demonstraion purposes)
  // ----------------------------------------------------------------------
  cy.document().then( doc => {
    doc.body.innerHTML = '<div class="token">2as24flx9</div>';
  });
  // (2) actual code
  // ----------------------------------------------------------------------
  cy.get('.token').invoke('text').then( token => {
    cy.request[AuthorizationToken] = token;
  });
});
© www.soinside.com 2019 - 2024. All rights reserved.