javascript - 如何正确地对按钮点击进行 Jasmine 测试

标签 javascript jquery jasmine

我最近开始使用 Jasmine 进行 javascript 测试,但遇到了一个问题。我相信这里有人可以帮助我。

我有以下简单代码,发布在 CodePen 上:

HTML:

<div class="container">
  <button id="btnEraseDiv">Erase Div</button>
</div>

CSS:

.container{
  display:flex;
  flex-direction: column;
  padding:20px;
  background-color:#eef;
}

button{
  padding:10px 0;
  font-size: 1rem;
  background-color:#fdd;
}

#toBeErased{
  padding:10px;
  border:1px solid #ffdddd;
  background-color:#ffccdd;
  margin-bottom:20px;
}

和 JavaScript:

const eraseDiv = () => {
  const myDiv = $('#toBeErased');
  myDiv.children('p').fadeOut(300, () => {
    myDiv.fadeOut(600, () => {
      myDiv.remove();
    });
  })  
}

const addMyDiv = () => {
  const myDiv = $(`<div id="toBeErased">
    <p>This div and all its content will be erased. <br />Click the button bellow to erase it.</p>    
  </div>`);
  if (!document.querySelectorAll('#toBeErased').length) {
    $('div.container').append(myDiv);
  }
};


$(document).ready(() => {
  $('button#btnEraseDiv').on('click', () => {
    eraseDiv();
  });

});

//here starts the test

describe("Erase button functionality", () => {
  beforeEach( () => {
    addMyDiv();
  });

  it('should erase the div when btnEraseDiv clicked - using async', async () => {
    //this test here is the mistery
    const btn = $('button#btnEraseDiv');
    await btn.click();
    expect($('div#toBeErased').length).toBeLessThan(1);
  });

  it('should erase the div when btnEraseDiv clicked - using done and timeout', (done) => {
    //this is working, but i'm sure it is not the right usage
    const btn = $('button#btnEraseDiv');
    btn.click();    
    setTimeout( () => {
      expect($('div#toBeErased').length).toBeLessThan(1);
      done();
    }, 2000);
  });



});

阅读我得出的测试失败的文档:

it('should erase the div when btnEraseDiv clicked - using async', async () => {
    //this test here is the mistery
    const btn = $('button#btnEraseDiv');
    await btn.click();
    expect($('div#toBeErased').length).toBeLessThan(1);
  });

然后我让另一个超时时间大于淡出持续时间并且它有效,但感觉不合适。

it('should erase the div when btnEraseDiv clicked - using done and timeout', (done) => {
    //this is working, but i'm sure it is not the right usage
    const btn = $('button#btnEraseDiv');
    btn.click();    
    setTimeout( () => {
      expect($('div#toBeErased').length).toBeLessThan(1);
      done();
    }, 2000);
  });

有人能指出我正确的方向或给我举个例子吗?

感谢您的宝贵时间!

最佳答案

我认为您使用 done 参数的“不正确”解决方案实际上是一个很好的方法。您使用 async/await 的第一个解决方案并不完全可行,因为 jQuery click() 方法不返回等待类型(a promise 或“thenable”)。

如果您更喜欢async/await 解决方案,您可以尝试以下方法:

// Add a reusable utility method for your tests.
const wait = async ms => new Promise(res => setTimeout(res, ms));

it('should erase the div when btnEraseDiv clicked - using async', async () => {
  $('button#btnEraseDiv').click();

  await wait(2000); // Wait for animations to complete.

  expect($('div#toBeErased').length).toBeLessThan(1);
});

旁注

您可能需要考虑的另一件事是使用像 Nightwatch 这样的 E2E/UI 测试库,尤其是当您要编写和维护大量 UI 测试时。 , Puppeteer , Selenium , Cypress , 或 Protractor (如果您使用的是 Angular)。

这些库将允许您编写与实现代码分开存在的测试。您可以在普通浏览器或 headless 浏览器实例中运行它们。它们都内置了“驱动程序”API 函数,允许您“等待”某些 DOM 条件。例如来自 Nightwatch 的 waitForElementPresent() 或来自 Puppeteer 的 waitForSelector()。还有更多 API 方法可帮助您轻松编写可维护的 E2E/UI 测试。

关于javascript - 如何正确地对按钮点击进行 Jasmine 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59455596/

相关文章:

javascript - Jquery UI DatePicker 限制日期集

javascript - Angular 1.5 测试组件与 jasmine

javascript - 如何检查对象中是否存在相同的字符串?

javascript - 使用模态从父作用域调用函数( Angular )

javascript - webkit 浏览器中来自 getClientRects 的 clientRect 语义

javascript - 找不到点击事件

javascript - RequireJS 工作不一致

javascript - 如何在fancybox上播放音频文件?

node.js - 如何使用 karma 将 Jasmine 测试结果/输出报告到文本文件中

angularjs - Angular 和 Jasmine : How to test requestError/rejection in HTTP interceptor?