【问题标题】:Angular 6 Jasmine Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVALAngular 6 Jasmine 错误:超时 - 在 jasmine.DEFAULT_TIMEOUT_INTERVAL 指定的超时内未调用异步回调
【发布时间】:2018-11-21 15:37:35
【问题描述】:

我无法测试我的应用程序的某些功能,因为有时(经常)量角器测试在 beforeEach 函数中失败。

可能我错过了一些重要的东西,因为测试随机失败,我发现了一些关于最大化超时的讨论,但它并没有解决问题。

我看到 beforeEach 在测试失败时没有完全执行,只执行第一条指令 ( browser.get ) 然后浏览器始终在同一页面上。

我正在尝试 allScriptsTimeout: 45000 这是一些测试。

describe('Rebus', function() {
  // mi posiziono nella lista ticket dopo ogni test e clicco su nuovo ticket

  beforeEach(function() {

    browser.get(Utils.baseUrl + '/tickets');

    browser.wait(function() {
      return element(by.id('newTicket')).isPresent();
    }, 5000);
    element(by.id('newTicket')).click();



    /**Ora passo dalla lista ticket a selezione blocco*/
    browser.wait(function() {
      return element(by.id('0')).isPresent();
    }, 5000);

    element(by.id('0')).click();
    element(by.id('newTicket')).click();
  });

  it('should buy ordinary ticket eurolevel 3', function() {
    // A questo punto dovrei essere arrivato al form del nuovo ticket
    selectArea('0');
    fillLicensePlate(5, 3);
    fillCountry();
    fillPassengers();
    setEntryDate(now);
    setExitDate(now.add(1, 'd'));

    // vai avanti al secondo step
    element(by.id('stepperNext')).click();

    browser.wait(function() {
      return element(by.id('daysOfStay')).isDisplayed();
    }, 5000);

    // Controllo che il prezzo sia corretto e controllo i giorni di permanenza
    element(by.id('daysOfStay'))
      .getText()
      .then(function(text) {
        expect(text).toContain('1');
      });

    element(by.id('amount'))
      .getText()
      .then(function(text) {
        expect(text).toContain('510', 'Errore nella tariffa');
      });

    browser.wait(function() {
      return element(by.id('save')).isDisplayed();
    }, 5000);

    // salvo il ticket
    element(by.id('save')).click();

    // Controllo che il prezzo sia corretto e controllo i giorni di permanenza
    browser.wait(function() {
      return element(by.name('price')).isPresent();
    }, 5000);

    element(by.name('price'))
      .getText()
      .then(function(text) {
        expect(text).toContain('510', 'Errore nella tariffa');
      });

    expect(element(by.name('addPay')).isPresent()).toBeTruthy(
      'Bottone non presente'
    );
  });

  it('should buy HOTEL ticket eurolevel €3', function() {
    // A questo punto dovrei essere arrivato al form del nuovo ticket
    selectArea('0');
    fillLicensePlate(5, 3);
    fillCountry();
    fillPassengers();
    setEntryDate(now);
    setExitDate(now.add(1, 'd'));

    // Campi opzionali
    setHotelField();
    setAgencyField();

    // vai avanti al secondo step
    element(by.id('stepperNext')).click();

    browser.wait(function() {
      return element(by.id('daysOfStay')).isDisplayed();
    }, 5000);

    // Controllo che il prezzo sia corretto e controllo i giorni di permanenza
    element(by.id('daysOfStay'))
      .getText()
      .then(function(text) {
        expect(text).toContain('1');
      });

    element(by.id('amount'))
      .getText()
      .then(function(text) {
        expect(text).toContain('210', 'Errore nella tariffa');
      });

    browser.wait(function() {
      return element(by.id('save')).isDisplayed();
    }, 5000);

    // salvo il ticket
    element(by.id('save')).click();

    // Controllo che il prezzo sia corretto e controllo i giorni di permanenza
    browser.wait(function() {
      return element(by.name('price')).isPresent();
    }, 5000);

    element(by.name('price'))
      .getText()
      .then(function(text) {
        expect(text).toContain('210', 'Errore nella tariffa');
      });

    expect(element(by.name('addPay')).isPresent()).toBeTruthy(
      'Bottone non presente'
    );
  });

【问题讨论】:

    标签: angular protractor


    【解决方案1】:

    我认为问题在于,您不是在等待异步任务。 browser 对象中的大多数函数都是异步的。意味着它们在不同的线程中执行。因此,每当您调用异步函数时,它都不会等到它完成。不,下一行代码会立即执行。 因此,在您的特定情况下,browser.get()browser.wait()element.click() 函数几乎是同时执行的,并且它从不等待一个函数完成。它们都并行运行,因为最后一个函数已经完成了您的 beforeEach() 停止。

    要等待异步任务,您必须使用 Promises 对象。以下代码将在您的测试中起作用:

    beforeEach(function() {
        browser.get(Utils.baseUrl + '/tickets').then(function () {
            // url '/tickets' opened now
            browser.wait(function() {
                return element(by.id('newTicket')).isPresent();
            }, 5000).then(function() {
                element(by.id('newTicket')).click();
               // next task here..
            });
        });
    });
    

    如果您使用的是打字稿,这可以使用await 以一种非常漂亮的方式完成:

    beforeEach(async function() {
        await browser.get(Utils.baseUrl + '/tickets');
        await browser.wait(function() { 
            return element(by.id('newTicket')).isPresent();
        }, 5000);
        await element(by.id('newTicket').click();
        // next task here..
    });
    

    当同时使用箭头函数时,它几乎变得优雅:

    beforeEach(async () => {
        await browser.get(Utils.baseUrl + '/tickets');
        await browser.wait(() => element(by.id('newTicket')).isPresent()),5000});
        await element(by.id('newTicket').click();
        // next task here..
    });
    

    如果您从未听说过 Promises,只需利用您第二天的工作来了解它们。

    【讨论】:

    • 感谢您的提示。 Angular CLI 代码脚手架确实应该改进,像这样有缺陷的代码永远不应该作为基本示例生成..
    • 看起来,量角器使用 Web 驱动程序控制流自动等待,请参阅protractortest.org/#/async-await
    猜你喜欢
    • 2017-07-24
    • 1970-01-01
    • 2019-09-21
    • 2016-05-30
    • 1970-01-01
    • 1970-01-01
    • 2014-05-01
    相关资源
    最近更新 更多