我正在和Cypress一起创建一个API自动化套件.
我有不需要登录的API测试,也有需要登录的API测试.
我已经编写了一个名为‘allAPI’的实用程序方法,我的所有测试都将使用它--它有一系列错误判断,并根据调用者传递给该方法的内容,自动使用相关的头/授权令牌来增加调用.
我还有一个"登录"方法,它可以创建一个存储授权令牌的别名.
在自动化工程师调用CallAPI来执行需要登录的API请求的场景中,我希望能够检测到他们尚未登录,并抛出一条错误消息来提示这一点.
方法1: 如果别名‘accesToken’不存在,则抛出错误.
问题: 似乎不赞成使用cy.state('aliases').
方法2: 使用缺省值"accesToken Not Set"在"BEFORE"挂接中创建别名...
before(() => {
cy.wrap('accessToken not set').as('accessToken');
});
然后在CallAPI中,判断别名的值是否等于‘accesToken Not Set’并抛出错误.
问题:
if (useAccessToken && cy.get('@accessToken') == 'accessToken not set') {
throw new Error('callAPI() - access token not set. Log in first.');
}
if (useAccessToken && cy.get('@accessToken').invoke('text') == 'accessToken not set') {
throw new Error('callAPI() - access token not set. Log in first.');
}
第一条‘if’语句显示"此比较似乎是无意的,因为类型‘Chainable’和‘String’没有重叠."
第二个‘if’语句显示"此比较似乎是无意的,因为类型‘Chainable’和‘String’没有重叠."
我可能错误地认为,在‘if’语句中比较别名中的文本应该是微不足道的,但显然这不是一件事...?
方法3: 这里的用意是在"当时"内进行比较……
cy.get('@accessToken').then(data => {
cy.log(data.text());
});
问题: "data.text不是函数"
方法4: 在我的‘if’语句中,断言别名的文本等于‘accesToken not set’.
if (useAccessToken && cy.get('@accessToken').should('equal', 'accessToken not set')) {
throw new Error('callAPI() - access token not set. Log in first.');
}
问题: 如果此断言失败,Cypress将抛出自己的错误,从而使抛出自定义错误的对象失效.
我的代码是:
const apiURL = Cypress.env('apiUrl');
export const APIURLs = {
Login: `${apiURL}access/login`,
Info: `${apiURL}info`,
InfoHealth: `${apiURL}info/health`
};
export class Common {
logInAndSetAccessToken(emailAddress: string, password: string) {
this.callAPI({
requestObject: {
method: 'POST',
url: APIURLs.Login,
body: {
email: emailAddress,
password: password
}
}, useAccessToken: false
}).then(response => {
cy.wrap(response.body.tokens.accessToken).as('accessToken');
});
}
/**
* 'headers' property, along with the following headers are automatically added to requestObject:
*
* 'Content-Type': 'application/json; charset=utf-8'
*
* 'Authorization': `Bearer ${accessToken}`
*/
callAPI({ url = '', requestObject = {}, useAccessToken = true } = {}) {
if (url.length > 3 && Object.keys(requestObject).length > 0) {
throw new Error('callAPI() - method call ambigious. Pass url or requestObject, not both.');
}
if (url.length < 4 && Object.keys(requestObject).length == 0) {
throw new Error('callAPI() - method call missing necessary information to make API call. Pass url or requestObject.');
}
if (useAccessToken && cy.get('@accessToken') == 'accessToken not set') { // This comparison appears to be unintentional because the types 'Chainable<JQuery<HTMLElement>>' and 'string' have no overlap.
throw new Error('callAPI() - access token not set. Log in first.');
}
if (Object.keys(requestObject).length > 0) {
if (!requestObject.method || !requestObject.url || !requestObject.body) {
throw new Error('callAPI() - method, url or body properties are missing in the requestObject.');
}
if (!requestObject.headers) {
Object.assign(requestObject, { headers: {} });
}
if (!requestObject.headers['Content-Type']) {
Object.assign(requestObject.headers, { 'Content-Type': 'application/json; charset=utf-8' });
}
if (useAccessToken && !requestObject.headers['Authorization']) {
Object.assign(requestObject.headers, { 'Authorization': `Bearer ${cy.get('@accessToken')}` });
}
return cy.request(requestObject);
} else {
if (url.length < 4) {
throw new Error('callAPI() - invalid url, cannot call API.');
}
return cy.request(url);
}
}
}
除非我错过了显而易见的事情(我不会感到惊讶),否则有什么方法可以解决这个问题吗?或者,我应该仅仅依靠API通知自动化工程师他们需要登录吗?
我使用TypeScript,如果这很重要.
感谢您所能提供的任何帮助.