我正在使用Protractor为我的Angular应用程序编写端到端测试。我可以模拟httpBackend进行单元测试,但我想实际调用服务器并获取JSON响应并再次写入测试返回的数据。
我已经在stackoverflow上阅读了很多内容,但无法理解这是如何完成的。
我使用$ http吗?如何将它注入我的Jasmine测试中?如何将响应JSON恢复到我的Jasmine测试中?
任何有关资源的帮助或链接都会有所帮助。
我再次不想模拟服务器,我想点击服务器并重新获得JSON。
谢谢!
答案 0 :(得分:5)
此刻我正在努力解决这个问题。我认为简短的答案是你设置的应用程序与你自己手动测试它的方式完全相同 - 因此Protractor实际上只是一个机器人用户,它没有(很好,几乎没有)访问应用程序的内部。
因此,如果您的应用程序需要Web服务器(并且大部分都是),那么您启动该Web服务器,然后通过浏览器将量角器连接到您的应用程序并进行练习。
对于我的情况,我的目标是在开始运行我的量角器e2e测试之前使用grunt来调用执行基本数据库设置的任务 - 这应该会给我一个已知的数据库状态。
有一个例子,我一直在编写一个使用Rails 4和AngularJS的教程,关于使用量角器进行e2e测试的部分不是特定于轨道的,可能很有用: http://technpol.wordpress.com/2013/11/16/5-end-to-end-testing/
答案 1 :(得分:3)
量角器应该用于完整堆栈的端到端测试。
在这种情况下,测试通常会运行角度应用程序(填充表单,按下按钮),这将触发角度应用程序调用REST服务器,REST服务器返回数据,Angular应用程序在DOM中进行转换,然后结束 - 结束测试断言。
这意味着您可能需要在启动Protractor之前启动应用程序服务器(承载角度应用程序并且是REST后端,我想)
如何做到这一点超出了量角器的范围。
这方面的困难通常是如何设置数据库,以便e2e测试知道返回JSON服务的期望。
答案 2 :(得分:0)
除了我们的量角器e2e测试之外,我们还会进行这种类型的“直接命中API并测试响应中的数据”集成测试。对于API端测试,您不需要Protractor,因为无需启动浏览器即可将HTTP请求发送到服务器。
这是我们要做的:
describe()/it()/expect()
语法。因此,您无需运行量角器来运行测试,而是运行茉莉花,例如:jasmine --config=jasmine.json path/to/tests/*spec.js
我们的规格文件如下所示:
describe('API Tests written in Jasmine', function() {
beforeAll(() => authAsAdmin());
it('Should get a proposal object as auth\'d user', function() {
const httpOptions = {
uri: `/proposals/100`,
};
return requestWithAuth(httpOptions)
.then(res => {
const proposal = res.body.proposal;
// console.log(`Proposal ${proposal.id} title: ${proposal.title}`);
expect(proposal.id).toEqual(100);
expect(res.statusCode).toEqual(200);
expect(res.statusMessage).toBe('OK');
});
});
我们的规范文件取决于我们在Jasmine帮助器文件(Jasmine工作原理的标准机制的一部分)中设置的一些全局帮助器方法,如下所示:
const rp = require('request-promise');
...
// Declare our helper methods globally so they can be accessed anywhere in tests
global.requestWithAuth = requestWithAuth;
global.authAs = authAs;
global.authAsAdmin = () => authAs(ADMIN_USER);
global.catchErrorInLocation = (error, location) => {
throw new Error(`Error in ${location}\n ${error}`);
};
global.catchErrorInBeforeAll = (error) => catchErrorInLocation(error, 'beforeAll()');
function authAs(user) {
...
}
/**
* Combines a given set of options with the DEFAULT_HTTP_OPTIONS plus a session token
* and initiates an http request, returning a promise for the response.
* @param {Object} options properties matching request-promise API
* @param {string} token, optional session token. sessionToken used by default.
* @returns {Promise} request-promise response
*/
function requestWithAuth(options, token = sessionToken) {
Object.assign(options, { ...DEFAULT_HTTP_OPTIONS, ...options }); // Merge custom options with default options
options.headers['x-token'] = token; // Merge current session token into options
options.uri = `${BASE_URL}${options.uri}`; // Update the URI to include the correct base path
return rp(options);
}
我希望这会有所帮助。