使用 Protractor 的测试间歇性失败 - 承诺执行订单?

Intermittently failing tests with Protractor - promise order execution?

我在一系列测试套件中面临间歇性量角器测试失败,在失败案例中没有任何真实模式来指示可能发生的情况,例如,失败的测试不是同一个。有时我会遇到很多失败案例,而在其他情况下,我只会遇到一个失败案例。

我应该指出,只有在我们配置的 Jenkins CI 服务器上执行测试 运行s 时才会发生这种情况(运行ning 在 linux 下) .在本地 Windows 开发机器上,我们可能会在 30-40 运行 秒后遇到一个失败案例,我可以忍受!

我们正在测试的应用程序目前是使用 angular 1.5 构建的,我们正在使用 angular material 1.1.3

由于 angular material 中使用的动画以及它们可能带来的性能影响,我们已经尝试按照这种方法禁用动画 here 这当然可以使测试更快但对失败没有帮助我们看到的案例/

我现在正处于 运行 一遍又一遍地使用一个测试套件的阶段,在 5 次成功 运行 之后,它在我们的 Jenkins CI 上的第 6 次尝试失败了] environment\linux 框,本地我已经 运行 这个测试很多次了,还没有失败。

下面详细介绍了相关测试套件以及页面 object 文件片段:

//test suite
describe('Operators View', function () {
  var operatorPage = require('./operators.po.js'),
    loginView = require('../login/login.po.js'),
    page = new operatorPage();

  describe('Large screen tests', function () {
    beforeAll(function () {
      loginView.login();
    });

    afterAll(function () {
      loginView.logout();
    });

    it('should create an operator', function () {
      page.settlementBtn.click();
      page.operatorsBtn.click();
      page.fabBtn.click();
      page.createOperator();
      expect(page.headline.getText()).toEqual('Operators');
    });
    });
});

// operators.po.js
var operatorsSection = function() {
    this.helper = new Helpers();
    this.headline = element(by.css('.md-headline'));
    this.settlementBtn = element(by.css('[ui-sref="settlement"]'));
    this.operatorsBtn = element(by.css('[ui-sref="operators"]'));
    this.fabBtn = element(by.css('.md-fab'));

    // Form Elements
    this.licenceNumber = element(by.model('vm.transportOperator.licenceNumber'));
    this.tradingName = element(by.model('vm.tradingName'));
    this.name = element(by.model('vm.name'));
    this.operatorAddressFirstLine = element(by.model('vm.transportOperator.address.line1'));
    this.operatorAddressCityTown = element(by.model('vm.transportOperator.address.line5'));
    this.operatorAddressPostCode = element(by.model('vm.transportOperator.address.postcode'));
    this.payeeAddressFirstLine = element(by.model('vm.transportOperator.payee.address.line1'));
    this.payeeAddressCityTown = element(by.model('vm.transportOperator.payee.address.line4'));
    this.payeeAddressPostCode = element(by.model('vm.transportOperator.payee.address.postcode'));
    this.opID = element(by.model('vm.transportOperator.fields.opID'));
    this.spID = element(by.model('vm.transportOperator.fields.spID'));
    this.schemeSelect = element(by.model('reference.scheme'));
    this.schemeOptions = element(by.exactRepeater('scheme in vm.schemes').row('0'));
    this.alias = element(by.model('reference.alias'));
    this.reference = element(by.model('reference.reference'));
    this.saveBtn = element(by.css('.md-raised'));


    this.createOperator = function() {
      this.licenceNumber.sendKeys(this.helper.getRandomId(10));
      this.tradingName.sendKeys('Protractor Trade Name LTD');
      this.name.sendKeys('Protractor Trade Name');
      this.operatorAddressFirstLine.sendKeys('Protractor Town');
      this.operatorAddressCityTown.sendKeys('Cardiff');
      this.operatorAddressPostCode.sendKeys('PT4 4TP');
      this.payeeAddressFirstLine.sendKeys('Protractor Town');
      this.payeeAddressCityTown.sendKeys('Cardiff');
      this.payeeAddressPostCode.sendKeys('PT4 4TP');
      this.opID.sendKeys('177');
      this.spID.sendKeys('Protractor Spid');
      this.schemeSelect.click();
      this.schemeOptions.click();
      this.alias.sendKeys('PTAlias');
      this.reference.sendKeys('Protractor');
      this.saveBtn.click();
    }

  };
module.exports = operatorsSection;

在此测试套件中,从 PO 文件调用 createOperator 并单击 savteBtn 后,应用程序将转换到显示 table 的状态创建的条目(当然是在成功创建之后)。我们也在使用 angular ui-router,当前版本为 0.2.18

预期失败:

Expected 'Create An Operator' to equal 'Operators'.

然而,所捕获的随附屏幕截图显示了带有 'Operators' 标题的 table 视图,似乎在期望调用中对 page.headline.getText() 的调用被调用得太快了,所以在创建项目和页面更改的数据库操作之前有机会完成吗?

我开始怀疑这是否可以归结为 Protractor 执行的承诺顺序。我看过有关量角器中控制流的文章,以及为什么有时您应该使用 .then() 挂钩量角器调用承诺的结果 - 我发现

这让我想知道我是否应该将调用移动到我的 saveBtn.click(),它在我的页面末尾调用 object 的 createOperator 函数,进入测试套件,所以做这样的事情:

it('should create an operator', function () {
      page.settlementBtn.click();
      page.operatorsBtn.click();
      page.fabBtn.click();
      page.createOperator();
      page.saveBtn.click().then(function(){
        expect(page.headline.getText()).toEqual('Operators');
      });
    });

老实说,我开始抓住这里的救命稻草了,所以来自社区的任何 thoughts\advice 都将不胜感激。

谢谢!

根据要求,这是我用来等待 URL 正常运行的函数。

public waitForUrlToBeLike (urlPart: string, timeout: number = 10000) {
    return browser.wait(() => {
        return browser.driver.getCurrentUrl().then((url) => {
            let regex = new RegExp(urlPart);
            return regex.test(url);
        });
    }, timeout);
}

我还经常使用以下代码来等待元素出现,然后再对它们进行断言:

public waitTillPresent (element: ElementFinder, timeout: number = 10000) {
    return browser.wait(() => {
        return element.isPresent();
    }, timeout);
}