我有一个RESTful API,现在我正在开发一个使用数据服务来调用API的angular2应用程序。然后我想用量角器实现端到端测试。我想从非常低的水平开始,所以我进行了测试,以便在点击链接时检查我的组件是否存在。测试看起来像这样:
describe('my-webclient', () => {
it('app should load', () => {
browser.get('/');
expect(element(by.css('my-app')).isPresent()).toBe(true);
});
it('app should have a top navigation', () => {
expect(element(by.css('my-nav-top')).isPresent()).toBe(true);
});
it('app should have a side navigation', () => {
expect(element(by.css('my-nav-side')).isPresent()).toBe(true);
});
it('app should have a content', () => {
expect(element(by.css('my-content')).isPresent()).toBe(true);
});
it('app should load the overview for route "/"', () => {
expect(element(by.css('my-overview')).isPresent()).toBe(true);
});
});
问题是,概述组件使用某些数据服务在ngOnInit
函数中发出HTTP请求。然后,量角器将永远阻止,尽管HTTP请求早已完成。
当我监控测试时,我可以看到应用程序的加载方式,包括从我的API中获取的所有数据。然后什么也没发生,量角器最终会崩溃,说达到了超时。
确切的错误消息是:
Failed: Timed out waiting for Protractor to synchronize with the page after 11 seconds. Please see https://github.com/angular/protractor/blob/master/docs/faq.md
While waiting for element with locator - Locator: By(css selector, my-app)
在google上搜索帮助时,我发现了一些提示,即量角器会等待角度来完成所有事情。嗯,这正是我想要的。当我在chrome的开发人员工具( F12 )中监控网络选项卡时,应用程序加载后不会出现任何内容。因此,没有更多的待处理请求或量角器等待的任何内容。它确实如此,我只是不知道为什么。
所以,这是我的问题:在处理发出HTTP请求的数据服务时,我是否必须考虑一些特殊问题?或者:我可以做些什么来调试为什么量角器仍在等待超时到达之前。
顺便说一下,它绝对是数据服务。如果我在OverviewComponent::ngOnInit
内注释掉所有内容,那么测试将会正常通过我预期的方式。
答案 0 :(得分:7)
(简短回答 - 任何长时间运行的任务(超时,间隔,Promises或Observables)都会阻止测试,如果处理不当.Http会自行清理,因此很可能不你的问题。 )
Http很可能不是你的问题。
Angular 2使用区域来检测它的稳定/不稳定状态,而Protractor使用特定的可注射类 - Testability Class - 来确定应用程序状态。页面中所有现有Angular2应用程序的可测试性都暴露给窗口对象,这就是Protractor在Angular 2上保持标签的方式。
Angular使用区域来维持变化检测。在userland中,我们可以通过NgZone控制代码发生的位置(在角度内或角度内),对于测试和性能两个方面非常有用。在角度区域中运行的任何任务(除非我们另行指定,否则会发生这种情况)将触发更改检测,并且我们等待标记Testability的任何异步任务都不稳定。
这意味着许多事情可能会干扰您的应用的稳定性:
要解决此问题,您需要使用NgZone:
在angular角度之外运行任务this.ngZone.runOutsideAngular(() => {
this._sub = Observable.timer(2000)
.subscribe(() => this.ngZone.run(() => {this.content = "Loaded!"}));
})
查看工作示例in this plunk和this talk by Julie Ralph了解更多详情 - 她是量角器背后的大脑。
答案 1 :(得分:2)
所以Tiagos的答案肯定指出了我正确的方向。我害怕这可能是我的观察者的一个问题。放心地发现它只是一个import React, { Component } from 'react';
class testLayout extends Component {
render() {
let item = this.props.data.items;
return (
<div className="slide">
<img src={item.imgUrl} alt=""/>
<p>{item.text}</p>
</div>
);
}
}
export default testLayout;
()我用来刷新我的jwt。这解决了如下:
window.setInterval