我在使用Protractor编写的自动化测试中遇到了一个奇怪的问题。我们需要测试一堆通过HTTP返回JSON的API端点,而不是实际网站,因此我的团队决定使用Chakram而不是依赖于Protractor。
我有一个负责访问API的页面对象:
const qs = require('querystring')
const chakram = require('chakram');
function MyApi() {
const domain = // read from a configuration file
this.readImportantBusinessData = (queryParams) => {
const serviceUrl = `${domain}/services/seriousBusiness.json`;
const queryString = qs.stringify(queryParams);
const fullUrl = `${serviceUrl}?${queryString}`;
return chakram.get(fullUrl).then((response) => {
return response;
});
};
};
module.exports = new MyApi();
然后,在我的一个规范中,我调用readImportantBusinessData
函数来检查它是否返回了预期的数据。
return MyApi.readImportantBusinessData(validParameters).then((response) => {
chakramExpect(response).to.have.status(HTTP_200_OK);
chakramExpect(response).to.have.json({
"foo" : "bar"
});
});
根据我运行此代码的环境,测试通过或失败,并显示错误消息,基本上表示未收到任何响应。
Failed: Cannot read property 'statusCode' of undefined
我可以确认我正在点击的服务器正在运行,并且在使用网络浏览器时我可以得到正确的响应。
当我使用AWS中托管的共享服务器时,我的测试中的rquest成功,当我使用在VirtualBox中运行的本地服务器时失败。
为什么Chakram根本没有收到回复?
答案 0 :(得分:1)
对expect
的调用只显示undefined
,但我设法记录整个响应对象,由chakram.get
{ error: { Error: self signed certificate
at TLSSocket.<anonymous> (_tls_wrap.js:1103:38)
at emitNone (events.js:106:13)
at TLSSocket.emit (events.js:208:7)
at TLSSocket.finishInit (_tls_wrap.js:637:8)
at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:467:38) code: 'DEPTH_ZERO_SELF_SIGNED_CERT' },
response: undefined,
body: undefined,
jar:
RequestJar {
jar: CookieJar { enableLooseMode: true, store: { idx: {} } }
},
url: 'https://www.example.com/myService.json?foo=bar',
responseTime: 29.524212
}
这意味着Chakram遇到了我在本地开发环境中使用的自签名证书的问题。其他服务器托管在云中,并正确设置其证书。
快速Google搜索通过设置:
返回了许多建议来修改驱动此行为的全局参数process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
但是,这会影响整个节点进程,而不仅仅是我的测试。这些只是我在本地运行的测试,而不是与实际用户数据有关的测试。但是,如果我要使这些调用的安全性更加宽松,我需要这样做以尽可能地限制这种调用的范围。
值得庆幸的是,chakram.get使用request库,可以非常自定义请求。
chakram.get
允许我通过:
params
对象可选的其他请求选项,请参阅热门request library选项
这些options反过来允许我指定:
agentOptions
- 并传递其选项。注意:对于HTTPS,请参阅tls API doc for TLS/SSL options和上述文档。
最后,在agentOptions
中,可以传递rejectUnauthorized
值,该值允许忽略证书错误,用于发出单个请求。
因此,在我的页面对象中,我可以使用:
return chakram.get(fullUrl, {
agentOptions : {
//Hack to allow requests to the local env with a self-signed cert
rejectUnauthorized : false
}
}).then((response) => {
return response;
});
尽管使用自签名证书,这仍然可以使测试成功。
解决方案是为每个环境和域提供有效的证书,在这种情况下,问题首先不存在。
答案 1 :(得分:-1)
这是因为它的异步和ur函数在没有完成chakram请求的情况下执行。 等待请求完成以获得响应。