我最近开始使用 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/