![单元测试 jest<a class=](https://img-blog.csdnimg.cn/img_convert/1ab080ffacd32f5f01d1d2a3d829c383.png)
jest单元测试
Jest is a new javascript testing tool announced today. I thought I'd take it out for a spin testing the UI of a simple vanilla JS app - no CommonJS modules, no fancy stuff. Just old school JavaScript. Granted, it's probably not what the tool was optimized to do, but it totally worked.
Jest是今天宣布的新的javascript测试工具。 我以为我会试一试简单的普通JS应用程序的用户界面-没有CommonJS模块,没有花哨的东西。 只是老式JavaScript。 当然,这可能不是该工具经过优化的功能,但它完全可以正常工作。
该应用程序 (The app)
It's a simple HTML page with inline CSS and JS that validates username and password and paints some of the UI in red if there's a validation error. Give it a try
这是一个带有内联CSS和JS的简单HTML页面,它可以验证用户名和密码,并在出现验证错误时将用户界面涂成红色。 试一试
Markup:
标记:
<p class="error error-box hidden" id="err">Please fill in the required fields</p>
<form onsubmit="return validateSubmit(this)" method="post" action="/cgi-bin/perlbaby.pl">
<ul>
<li><label id="username-label" for="username">Username</label>
<input id="username"></li>
<li><label id="password-label" for="password">Password</label>
<input id="password"></li>
</ul>
<button type="submit" id="button">go</button>
</form>
CSS:
CSS:
.hidden {display: none}
.error {color: red}
.error-box {border: 1px solid red}
When the user submits the form, the function validateSubmit()
is called to do the validation. There's no framework so everything is pretty old school:
当用户提交表单时,将调用函数validateSubmit()
进行验证。 没有框架,所以一切都太老了:
function validateSubmit(f) {
var validates = true;
['username', 'password'].forEach(function(field) {
if (!document.getElementById(field).value) {
validates = false;
document.getElementById(field + '-label').className = 'error';
} else {
document.getElementById(field + '-label').className = '';
}
});
document.getElementById('err').className = validates
? 'hidden'
: 'error error-box';
if (validates) {
// fancy stuff goeth here
}
return false;
}
Actually it was even older school, but the test didn't quite work because JSDOM which is used behind the scenes for the DOM stuff doesn't support ancient stuff like accessing form elements of the sort: document.forms.username
. JSDOM also don't seem to support classList
property at the moment, which is a bummer, but I'm sure will be added eventually. Anyway.
实际上,这甚至是更老的学校,但是该测试并没有完全起作用,因为在DOM东西背后使用的JSDOM不支持古老的东西,例如访问sort的表单元素: document.forms.username
。 JSDOM目前似乎还不支持classList
属性,这实在classList
,但是我敢肯定最终会添加它。 无论如何。
Feel free to play with the page and try to submit emtpy fields to see the UI changes
随意使用页面并尝试提交空字段以查看UI更改
![](https://img-blog.csdnimg.cn/img_convert/77c1675699ac3f142bf414cf98affb19.png)
OK, so how do you test that this page behaves as expected. Enter Jest.
好的,那么您如何测试此页面的行为是否符合预期。 输入笑话。
笑话 (Jest)
To install Jest, go
要安装Jest ,请转到
$ npm install -g jest-cli
You then need to create a package.json
file where your app lives, like:
然后,您需要在应用程序所在的位置创建一个package.json
文件,例如:
{
"scripts": {
"test": "jest"
}
}
Now you're ready to run tests!
现在您可以运行测试了!
$ cd ~/apps/app
$ mkdir __tests__
$ npm test
> @ test ~/apps/app/jester
> jest
Found 0 matching tests...
0/0 tests failed
Run time: 0.596s
Cool, it works! Only there are no tests to run.
太酷了,它有效! 只有没有要运行的测试。
一个测试例子 (A test example)
If you're familiar with Jasmine for JS testing... well, Jest extends that so the syntax is the same. Here's a barebone minimal example:
如果您熟悉Jasmine进行JS测试...那么,Jest对此进行了扩展,因此语法是相同的。 这是一个准系统的最小示例:
describe('someName', function() {
it('does stuff', function() {
// ...
expect(true).toBeTruthy();
});
});
Put this in your app's __tests__
directory so Jest knows where to find and run:
将其放在应用程序的__tests__
目录中,以便Jest知道在哪里查找和运行:
$ npm test
> @ test ~/apps/app/jester
> jest
Found 1 matching tests...
PASS __tests__/example.js (0.016s)
0/1 tests failed
Run time: 1.305s
Or how about making the test fail, just for kicks:
或者如何使测试失败,只是为了踢一下:
describe('someName', function() {
it('does stuff', function() {
// ...
expect(true).toBe(1);
});
});
Running...
跑步...
$ npm test
> @ test ~/apps/app/jester
> jest
Found 1 matching tests...
FAIL __tests__/example.js (0.017s)
● someName › it does stuff
- Expected: true toBe: 1
at Spec.
(~/apps/app/jester/__tests__/example.js:4:18)
at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
1/1 tests failed
Run time: 1.405s
Not bad. Now let's do a real example.
不错。 现在让我们做一个真实的例子。
测试香草 (Testing the vanilla)
The thing about Jest is that it mocks everything. Which is priceless for unit testing. But it also means you need to declare when you don't want something mocked. Starting the new test with:
关于Jest的事情是它模拟了一切。 对于单元测试而言,这是无价的。 但这也意味着您需要在不希望嘲笑的时候声明。 使用以下命令启动新测试:
jest
.dontMock('fs')
.dontMock('jquery');
"Huh?!" you say. jQuery? Yup, I used jQuery to do the DOM-y stuff in the test. Like submit the form and check for class names, fill out the form, and... no, that's about it. You, of course, can use any library that JSDOM can handle.
“ Hu ?!” 你说。 jQuery的? 是的,我在测试中使用jQuery完成了DOM-y的工作。 就像提交表单并检查类名一样,填写表单,然后……不,仅此而已。 您当然可以使用JSDOM可以处理的任何库。
The magic of Jest is in its use of require()
for all the mocking. Read more here. So any module you require will be mercilessly mocked unless you say dontMock()
.
Jest的魔力在于它对所有模拟都使用require()
。 在这里。 因此,除非您不说dontMock()
否则将无情地嘲笑您需要的任何模块。
Moving on.
继续。
I'll fetch the markup (that includes the inline JavaScript) so I can test it later. Oh, and require jQuery:
我将获取标记(包括内联JavaScript),以便稍后进行测试。 哦,需要jQuery:
var $ = require('jquery');
var html = require('fs').readFileSync('./app.html').toString();
Now, you know the "template" for a new test. Let's have two of these:
现在,您知道了新测试的“模板”。 让我们有两个:
describe('validateSubmits', function() {
it('shows/hides error banner', function() {
// ... test here
});
it('adds/removes error classes to labels', function() {
// ... test here
});
});
测试#1 (test #1)
First set the content of the empty document that the framework has created with the contents of the app read from disk:
首先使用从磁盘读取的应用程序的内容来设置框架已创建的空文档的内容:
document.documentElement.innerHTML = html;
Next, checking the initial state. In the initial state the error message is hidden with a CSS class name .hidden
since there are no errors. So here comes the jQuery magic combined with Jasmine's:
接下来,检查初始状态。 在初始状态下,错误消息被隐藏为CSS类名.hidden
因为没有错误。 因此,这是结合了Jasmine的jQuery魔术:
// initial state
expect($('#err').hasClass('hidden')).toBeTruthy();
Next, submit the form without filling it out. Error state ensues. The error message paragraph is now displayed because our app removed the .hidden
class:
接下来,提交表单而不填写。 错误状态随之而来。 现在显示错误消息段落,因为我们的应用程序删除了.hidden
类:
// submit blank form, get an error
$('form').submit();
expect($('#err').hasClass('hidden')).toBeFalsy();
Finally, test that the error message is again hidden after the form is filled out and submitted:
最后,测试并填写表单并提交后,错误消息是否再次被隐藏:
// fill out completely, error gone
$('#username').val('Bob');
$('#password').val('123456');
$('form').submit();
expect($('#err').hasClass('hidden')).toBeTruthy();
测试#2 (Test #2)
The second test is similar, only this time we're checking if the form labels have .error
class which makes 'em all red. Here goes:
第二个测试是类似的,只是这次我们检查表单标签是否具有.error
类,从而使它们全部.error
红色。 开始:
document.documentElement.innerHTML = html;
// initially - no errors
expect($('#username-label').hasClass('error')).toBe(false);
expect($('#password-label').hasClass('error')).toBe(false);
// errors
$('form').submit();
expect($('#username-label').hasClass('error')).toBe(true);
expect($('#password-label').hasClass('error')).toBe(true);
// fill out username, missing password still causes an error
$('#username').val('Bob');
$('form').submit();
expect($('#username-label').hasClass('error')).toBe(false);
expect($('#password-label').hasClass('error')).toBe(true);
// add the password already
$('#password').val('123456');
$('form').submit();
expect($('#username-label').hasClass('error')).toBe(false);
expect($('#password-label').hasClass('error')).toBe(false);
The full source is here
完整的源代码在这里
谢谢!(Thanks!)
Thanks for reading! Now, I'm sorry to inform you, you have no excuse not to write tests. Even this old school page can be tested, imagine what you can do with your awesome fancy JS modules!
谢谢阅读! 现在,很抱歉通知您,您没有理由不编写测试。 甚至可以测试这个古老的页面,想象一下如何使用出色的精美JS模块可以做什么!
Tell your friends about this post on Facebook and Twitter
在Facebook和Twitter上告诉您的朋友有关此帖子的信息
翻译自: https://www.phpied.com/jest-jquery-testing-vanilla-app/
jest单元测试