Ðалее Ñ Ð½Ð°Ñ Ð±ÑдÑÑ Ð·Ð°Ð´Ð°Ñи, Ð´Ð»Ñ Ð¿ÑовеÑки коÑоÑÑÑ Ð¸ÑполÑзÑеÑÑÑ Ð°Ð²ÑомаÑиÑеÑкое ÑеÑÑиÑование. Также его ÑаÑÑо пÑименÑÑÑ Ð² ÑеалÑнÑÑ Ð¿ÑоекÑÐ°Ñ .
ÐаÑем нам нÑÐ¶Ð½Ñ ÑеÑÑÑ?
ÐбÑÑно, когда Ð¼Ñ Ð¿Ð¸Ñем ÑÑнкÑиÑ, Ð¼Ñ Ð»ÐµÐ³ÐºÐ¾ можем пÑедÑÑавиÑÑ, ÑÑо она должна делаÑÑ, и как она бÑÐ´ÐµÑ Ð²ÐµÑÑи ÑÐµÐ±Ñ Ð² завиÑимоÑÑи Ð¾Ñ Ð¿ÐµÑеданнÑÑ Ð¿Ð°ÑамеÑÑов.
Ðо вÑÐµÐ¼Ñ ÑазÑабоÑки Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ пÑовеÑиÑÑ Ð¿ÑавилÑноÑÑÑ ÑабоÑÑ ÑÑнкÑии, пÑоÑÑо вÑзвав еÑ, напÑимеÑ, из конÑоли и ÑÑавнив полÑÑеннÑй ÑезÑлÑÑÐ°Ñ Ñ Ð¾Ð¶Ð¸Ð´Ð°ÐµÐ¼Ñм.
ÐÑли ÑÑнкÑÐ¸Ñ ÑабоÑÐ°ÐµÑ Ð½Ðµ Ñак, как Ð¼Ñ Ð¾Ð¶Ð¸Ð´Ð°ÐµÐ¼, Ñо можно внеÑÑи иÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð² код и запÑÑÑиÑÑ ÐµÑ ÐµÑÑ Ñаз. Так можно повÑоÑÑÑÑ Ð´Ð¾ ÑÐµÑ Ð¿Ð¾Ñ, пока ÑÑнкÑÐ¸Ñ Ð½Ðµ ÑÑÐ°Ð½ÐµÑ ÑабоÑаÑÑ Ñак, как нам нÑжно.
Ðднако, Ñакие «ÑÑÑнÑе пеÑезапÑÑки» â не лÑÑÑее ÑеÑение.
ÐÑи ÑеÑÑиÑовании кода ÑÑÑнÑми пеÑезапÑÑками легко ÑпÑÑÑиÑÑ ÑÑо-нибÑÐ´Ñ Ð²Ð°Ð¶Ð½Ð¾Ðµ.
ÐапÑимеÑ, Ð¼Ñ ÑабоÑаем над ÑÑнкÑией f. ÐапиÑали ÑаÑÑÑ ÐºÐ¾Ð´Ð° и ÑеÑили пÑоÑеÑÑиÑоваÑÑ. ÐÑÑÑнÑеÑÑÑ, ÑÑо f(1) ÑабоÑÐ°ÐµÑ Ð¿ÑавилÑно, в Ñо вÑÐµÐ¼Ñ ÐºÐ°Ðº f(2) â неÑ. ÐÑ Ð²Ð½Ð¾Ñим в код иÑпÑавлениÑ, и ÑепеÑÑ f(2) ÑабоÑÐ°ÐµÑ Ð¿ÑавилÑно. ÐÑоде бÑ, вÑÑ Ñ
оÑоÑо, не Ñак ли? Ðднако, Ð¼Ñ Ð·Ð°Ð±Ñли заново пÑоÑеÑÑиÑоваÑÑ f(1). Ðозможно, поÑле внеÑÐµÐ½Ð¸Ñ Ð¿Ñавок f(1) ÑÑала ÑабоÑаÑÑ Ð½ÐµÐ¿ÑавилÑно.
ÐÑо â ÑипиÑÐ½Ð°Ñ ÑиÑÑаÑиÑ. Ðо вÑÐµÐ¼Ñ ÑазÑабоÑки Ð¼Ñ ÑÑиÑÑваем множеÑÑво ÑазлиÑнÑÑ ÑÑенаÑиев иÑполÑзованиÑ. Ðо Ñложно ожидаÑÑ, ÑÑо пÑогÑаммиÑÑ ÑÑÐ°Ð½ÐµÑ Ð²ÑÑÑнÑÑ Ð¿ÑовеÑÑÑÑ ÐºÐ°Ð¶Ð´Ñй из Ð½Ð¸Ñ Ð¿Ð¾Ñле лÑбого Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÐºÐ¾Ð´Ð°. ÐоÑÑÐ¾Ð¼Ñ Ð»ÐµÐ³ÐºÐ¾ иÑпÑавиÑÑ ÑÑо-Ñо одно и пÑи ÑÑом ÑломаÑÑ ÑÑо-Ñо дÑÑгое.
ÐвÑомаÑиÑеÑкое ÑеÑÑиÑование ознаÑаеÑ, ÑÑо ÑеÑÑÑ Ð¿Ð¸ÑÑÑÑÑ Ð¾ÑделÑно, в дополнение к кодÑ. Ðни по-ÑÐ°Ð·Ð½Ð¾Ð¼Ñ Ð·Ð°Ð¿ÑÑкаÑÑ Ð½Ð°Ñи ÑÑнкÑии и ÑÑавниваÑÑ ÑезÑлÑÑÐ°Ñ Ñ Ð¾Ð¶Ð¸Ð´Ð°ÐµÐ¼Ñм.
Behavior Driven Development (BDD)
ÐавайÑе наÑнÑм Ñ ÑÐµÑ Ð½Ð¸ÐºÐ¸ под названием Behavior Driven Development или, коÑоÑко, BDD.
BDD â ÑÑо ÑÑи в одном: и ÑеÑÑÑ, и докÑменÑаÑиÑ, и пÑимеÑÑ Ð¸ÑполÑзованиÑ.
ЧÑÐ¾Ð±Ñ Ð¿Ð¾Ð½ÑÑÑ BDD â ÑаÑÑмоÑÑим пÑакÑиÑеÑкий пÑÐ¸Ð¼ÐµÑ ÑазÑабоÑки.
РазÑабоÑка ÑÑнкÑии Ð²Ð¾Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð² ÑÑÐµÐ¿ÐµÐ½Ñ â «pow»: ÑпеÑиÑикаÑиÑ
ÐопÑÑÑим, Ð¼Ñ Ñ
оÑим напиÑаÑÑ ÑÑнкÑÐ¸Ñ pow(x, n), коÑоÑÐ°Ñ Ð²Ð¾Ð·Ð²Ð¾Ð´Ð¸Ñ x в ÑелоÑиÑленнÑÑ ÑÑÐµÐ¿ÐµÐ½Ñ n. ÐÑ Ð¿Ñедполагаем, ÑÑо nâ¥0.
ÐÑа задаÑа взÑÑа в каÑеÑÑве пÑимеÑа. Ð JavaScript еÑÑÑ Ð¾Ð¿ÐµÑаÑÐ¾Ñ **, коÑоÑÑй ÑлÑÐ¶Ð¸Ñ Ð´Ð»Ñ Ð²Ð¾Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð² ÑÑепенÑ. ÐÑ ÑоÑÑедоÑоÑимÑÑ Ð½Ð° пÑоÑеÑÑе ÑазÑабоÑки, коÑоÑÑй Ñакже можно пÑименÑÑÑ Ð¸ Ð´Ð»Ñ Ð±Ð¾Ð»ÐµÐµ ÑложнÑÑ
задаÑ.
ÐеÑед Ñем, как наÑаÑÑ Ð¿Ð¸ÑаÑÑ ÐºÐ¾Ð´ ÑÑнкÑии pow, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ пÑедÑÑавиÑÑ Ñебе, ÑÑо она должна делаÑÑ, и опиÑаÑÑ ÐµÑ.
Такое опиÑание назÑваеÑÑÑ ÑпеÑиÑикаÑией (specification). Ðна ÑодеÑÐ¶Ð¸Ñ Ð¾Ð¿Ð¸ÑÐ°Ð½Ð¸Ñ ÑазлиÑнÑÑ ÑпоÑобов иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ ÑеÑÑÑ Ð´Ð»Ñ Ð½Ð¸Ñ , напÑимеÑ:
describe("pow", function() {
it("Ð²Ð¾Ð·Ð²Ð¾Ð´Ð¸Ñ Ð² ÑÑÐµÐ¿ÐµÐ½Ñ n", function() {
assert.equal(pow(2, 3), 8);
});
});
СпеÑиÑикаÑÐ¸Ñ ÑоÑÑÐ¾Ð¸Ñ Ð¸Ð· ÑÑÑÑ Ð¾ÑновнÑÑ Ð±Ð»Ð¾ÐºÐ¾Ð²:
describe("заголовок", function() { ... })-
ÐакÑÑ ÑÑнкÑионалÑноÑÑÑ Ð¼Ñ Ð¾Ð¿Ð¸ÑÑваем. РнаÑем ÑлÑÑае Ð¼Ñ Ð¾Ð¿Ð¸ÑÑваем ÑÑнкÑиÑ
pow. ÐÑполÑзÑеÑÑÑ Ð´Ð»Ñ Ð³ÑÑппиÑовки ÑабоÑÐ¸Ñ Ð»Ð¾Ñадок â блоковit. it("опиÑание", function() { ... })-
РпеÑвом аÑгÑменÑе блока
itÐ¼Ñ ÑеловеÑеÑким ÑзÑком опиÑÑваем конкÑеÑнÑй ÑпоÑоб иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑÑнкÑии, а во вÑоÑом â пиÑем ÑÑнкÑиÑ, коÑоÑÐ°Ñ ÑеÑÑиÑÑÐµÑ Ð´Ð°Ð½Ð½Ñй ÑлÑÑай. assert.equal(value1, value2)-
Ðод внÑÑÑи блока
it, еÑли ÑÑнкÑÐ¸Ñ ÑабоÑÐ°ÐµÑ Ð²ÐµÑно, должен вÑполнÑÑÑÑÑ Ð±ÐµÐ· оÑибок.ФÑнкÑии вида
assert.*иÑполÑзÑÑÑÑÑ Ð´Ð»Ñ Ð¿ÑовеÑки Ñого, ÑÑо ÑÑнкÑиÑpowÑабоÑÐ°ÐµÑ Ñак, как Ð¼Ñ Ð¾Ð¶Ð¸Ð´Ð°ÐµÐ¼. Ð ÑÑом пÑимеÑе Ð¼Ñ Ð¸ÑполÑзÑем Ð¾Ð´Ð½Ñ Ð¸Ð· Ð½Ð¸Ñ âassert.equal, коÑоÑÐ°Ñ ÑÑÐ°Ð²Ð½Ð¸Ð²Ð°ÐµÑ Ð¿ÐµÑеданнÑе знаÑÐµÐ½Ð¸Ñ Ð¸ вÑбÑаÑÑÐ²Ð°ÐµÑ Ð¾ÑибкÑ, еÑли они не ÑÐ°Ð²Ð½Ñ Ð´ÑÑг дÑÑгÑ. СÑÑеÑÑвÑÑÑ Ð¸ дÑÑгие ÑÐ¸Ð¿Ñ ÑÑавнений и пÑовеÑок, коÑоÑÑе Ð¼Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸Ð¼ позже.
СпеÑиÑикаÑÐ¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð·Ð°Ð¿ÑÑена, и пÑи ÑÑом бÑÐ´ÐµÑ Ð²Ñполнена пÑовеÑка, ÑÐºÐ°Ð·Ð°Ð½Ð½Ð°Ñ Ð² блоке it, Ð¼Ñ Ñвидим ÑÑо позднее.
ÐÑоÑеÑÑ ÑазÑабоÑки
ÐÑоÑеÑÑ ÑазÑабоÑки обÑÑно вÑглÑÐ´Ð¸Ñ ÑледÑÑÑим обÑазом:
- ÐиÑеÑÑÑ Ð½Ð°ÑалÑÐ½Ð°Ñ ÑпеÑиÑикаÑÐ¸Ñ Ñ ÑеÑÑами, пÑовеÑÑÑÑими оÑновнÑÑ ÑÑнкÑионалÑноÑÑÑ.
- СоздаÑÑÑÑ Ð½Ð°ÑалÑÐ½Ð°Ñ ÑеализаÑиÑ.
- ÐÐ»Ñ Ð·Ð°Ð¿ÑÑка ÑеÑÑов Ð¼Ñ Ð¸ÑполÑзÑем ÑÑеймвоÑк Mocha (подÑобнее о нÑм ÑÑÑÑ Ð¿Ð¾Ð·Ð¶Ðµ). Ðока ÑÑнкÑÐ¸Ñ Ð½Ðµ гоÑова, бÑдÑÑ Ð¾Ñибки. ÐноÑим Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð´Ð¾ ÑÐµÑ Ð¿Ð¾Ñ, пока вÑÑ Ð½Ðµ наÑнÑÑ ÑабоÑаÑÑ Ñак, как нам нÑжно.
- ТепеÑÑ Ñ Ð½Ð°Ñ ÐµÑÑÑ Ð¿ÑавилÑно ÑабоÑаÑÑÐ°Ñ Ð½Ð°ÑалÑÐ½Ð°Ñ ÑеализаÑÐ¸Ñ Ð¸ ÑеÑÑÑ.
- ÐÑ Ð´Ð¾Ð±Ð°Ð²Ð»Ñем новÑе ÑпоÑÐ¾Ð±Ñ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð² ÑпеÑиÑикаÑиÑ, возможно, еÑÑ Ð½Ðµ ÑеализованнÑе в ÑеÑÑиÑÑемом коде. ТеÑÑÑ Ð½Ð°ÑинаÑÑ Â«Ð¿Ð°Ð´Ð°ÑÑ» (вÑдаваÑÑ Ð¾Ñибки).
- ÐозвÑаÑаемÑÑ Ð½Ð° Ñаг 3, допиÑÑваем ÑеализаÑÐ¸Ñ Ð´Ð¾ ÑÐµÑ Ð¿Ð¾Ñ, пока ÑеÑÑÑ Ð½Ðµ наÑнÑÑ Ð·Ð°Ð²ÐµÑÑаÑÑÑÑ Ð±ÐµÐ· оÑибок.
- ÐовÑоÑÑем Ñаги 3-6, пока ÑÑебÑÐµÐ¼Ð°Ñ ÑÑнкÑионалÑноÑÑÑ Ð½Ðµ бÑÐ´ÐµÑ Ð³Ð¾Ñова.
Таким обÑазом, ÑазÑабоÑка пÑÐ¾Ñ Ð¾Ð´Ð¸Ñ Ð¸ÑеÑаÑивно. ÐÑ Ð¿Ð¸Ñем ÑпеÑиÑикаÑиÑ, ÑеализÑем еÑ, пÑовеÑÑем, ÑÑо ÑеÑÑÑ Ð²ÑполнÑÑÑÑÑ Ð±ÐµÐ· оÑибок, пиÑем еÑÑ ÑеÑÑÑ, Ñнова пÑовеÑÑем, ÑÑо они пÑÐ¾Ñ Ð¾Ð´ÑÑ Ð¸ Ñ.д.
ÐавайÑе поÑмоÑÑим ÑÑÐ¾Ñ Ð¿Ð¾Ñок ÑазÑабоÑки на наÑем пÑимеÑе.
ÐеÑвÑй Ñаг Ñже завеÑÑÑн. У Ð½Ð°Ñ ÐµÑÑÑ ÑпеÑиÑикаÑÐ¸Ñ Ð´Ð»Ñ ÑÑнкÑии pow. ТепеÑÑ, пеÑед Ñем, как пиÑаÑÑ ÑеализаÑиÑ, давайÑе подклÑÑим библиоÑеки Ð´Ð»Ñ Ð¿Ñобного запÑÑка ÑеÑÑов, пÑоÑÑо ÑÑÐ¾Ð±Ñ ÑбедиÑÑÑÑ, ÑÑо ÑеÑÑÑ ÑабоÑаÑÑ (ÑазÑмееÑÑÑ, они завеÑÑаÑÑÑ Ð¾Ñибками).
СпеÑиÑикаÑÐ¸Ñ Ð² дейÑÑвии
Ð ÑÑой главе Ð¼Ñ Ð±Ñдем полÑзоваÑÑÑÑ ÑледÑÑÑими JavaScript-библиоÑеками Ð´Ð»Ñ ÑеÑÑов:
- Mocha â оÑновной ÑÑеймвоÑк. Ðн пÑедоÑÑавлÑÐµÑ Ð¾Ð±Ñие ÑÑнкÑии ÑеÑÑиÑованиÑ, Ñакие как
describeиit, а Ñакже ÑÑнкÑÐ¸Ñ Ð·Ð°Ð¿ÑÑка ÑеÑÑов. - Chai â библиоÑека, пÑедоÑÑавлÑÑÑÐ°Ñ Ð¼Ð½Ð¾Ð¶ÐµÑÑво ÑÑнкÑий пÑовеÑки ÑÑвеÑждений. Ðока Ð¼Ñ Ð±Ñдем иÑполÑзоваÑÑ ÑолÑко
assert.equal. - Sinon â библиоÑека, позволÑÑÑÐ°Ñ Ð½Ð°Ð±Ð»ÑдаÑÑ Ð·Ð° ÑÑнкÑиÑми, ÑмÑлиÑоваÑÑ Ð²ÑÑÑоеннÑе ÑÑнкÑии и многое дÑÑгое. Ðам она пÑигодиÑÑÑ Ð¿Ð¾Ð·Ð´Ð½ÐµÐµ.
ÐÑи библиоÑеки Ð¿Ð¾Ð´Ñ Ð¾Ð´ÑÑ ÐºÐ°Ðº Ð´Ð»Ñ ÑеÑÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð²Ð½ÑÑÑи бÑаÑзеÑа, Ñак и на ÑÑоÑоне ÑеÑвеÑа. ÐÑ ÑаÑÑмоÑÑим ваÑÐ¸Ð°Ð½Ñ Ñ Ð±ÑаÑзеÑом.
ÐÐ¾Ð»Ð½Ð°Ñ HTML-ÑÑÑаниÑа Ñ ÑÑими библиоÑеками и ÑпеÑиÑикаÑией ÑÑнкÑии pow:
<!DOCTYPE html>
<html>
<head>
<!-- добавим ÑÑили mocha Ð´Ð»Ñ Ð¾ÑобÑÐ°Ð¶ÐµÐ½Ð¸Ñ ÑезÑлÑÑаÑов -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mocha/3.2.0/mocha.css">
<!-- добавлÑем Ñам ÑÑеймвоÑк mocha -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/3.2.0/mocha.js"></script>
<script>
// вклÑÑаем Ñежим ÑеÑÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð² ÑÑиле BDD
mocha.setup('bdd');
</script>
<!-- добавим chai -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.5.0/chai.js"></script>
<script>
// chai пÑедоÑÑавлÑÐµÑ Ð±Ð¾Ð»ÑÑое колиÑеÑÑво ÑÑнкÑий. ÐбÑÑвим assert глобалÑно
let assert = chai.assert;
</script>
</head>
<body>
<script>
function pow(x, n) {
/* ÐдеÑÑ Ð±ÑÐ´ÐµÑ ÑеализаÑÐ¸Ñ ÑÑнкÑии, пока пÑÑÑо */
}
</script>
<!-- ÑкÑÐ¸Ð¿Ñ Ñо ÑпеÑиÑикаÑией (describe, it...) -->
<script src="test.js"></script>
<!-- ÑÐ»ÐµÐ¼ÐµÐ½Ñ Ñ id="mocha" бÑÐ´ÐµÑ ÑодеÑжаÑÑ ÑезÑлÑÑаÑÑ ÑеÑÑов -->
<div id="mocha"></div>
<!-- запÑÑкаем ÑеÑÑÑ! -->
<script>
mocha.run();
</script>
</body>
</html>
УÑловно ÑÑÑаниÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ ÑазделиÑÑ Ð½Ð° пÑÑÑ ÑаÑÑей:
- Тег
<head>ÑодеÑÐ¶Ð¸Ñ ÑÑоÑонние библиоÑеки и ÑÑили Ð´Ð»Ñ ÑеÑÑов. - Тег
<script>ÑодеÑÐ¶Ð¸Ñ ÑеÑÑиÑÑемÑÑ ÑÑнкÑиÑ, в наÑем ÑлÑÑае âpow. - ТеÑÑÑ â в наÑем ÑлÑÑае внеÑний ÑкÑипÑ
test.js, коÑоÑÑй ÑодеÑÐ¶Ð¸Ñ ÑпеÑиÑикаÑиÑdescribe("pow", ...), пÑедÑÑавленнÑÑ Ð²ÑÑе. - HTML-ÑлеменÑ
<div id="mocha">бÑÐ´ÐµÑ Ð¸ÑполÑзован ÑÑеймвоÑком Mocha Ð´Ð»Ñ Ð²Ñвода ÑезÑлÑÑаÑов ÑеÑÑиÑованиÑ. - ÐапÑÑк ÑеÑÑов пÑоизводиÑÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾Ð¹
mocha.run().
РезÑлÑÑаÑÑ:
Ðока ÑÑо ÑеÑÑ Ð·Ð°Ð²ÐµÑÑаеÑÑÑ Ð¾Ñибкой. ÐÑо логиÑно, поÑÐ¾Ð¼Ñ ÑÑо Ñ Ð½Ð°Ñ Ð¿ÑÑÑÐ°Ñ ÑÑнкÑÐ¸Ñ pow, Ñак ÑÑо pow(2,3) возвÑаÑÐ°ÐµÑ undefined вмеÑÑо 8.
Ðа бÑдÑÑее оÑмеÑим, ÑÑо ÑÑÑеÑÑвÑÑÑ Ð±Ð¾Ð»ÐµÐµ вÑÑокоÑÑовневÑе ÑÑеймвоÑки Ð´Ð»Ñ ÑеÑÑиÑованиÑ, Ñакие как karma и дÑÑгие. С Ð¸Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð»ÐµÐ³ÐºÐ¾ ÑделаÑÑ Ð°Ð²ÑозапÑÑк множеÑÑва ÑеÑÑов.
ÐаÑалÑÐ½Ð°Ñ ÑеализаÑиÑ
ÐавайÑе напиÑем пÑоÑÑÑÑ ÑеализаÑÐ¸Ñ ÑÑнкÑии pow, ÑÑÐ¾Ð±Ñ Ð¿ÑойÑи ÑеÑÑÑ.
function pow(x, n) {
return 8; // :) ÑжÑлÑниÑаем!
}
ÐаÑ, ÑепеÑÑ Ð²ÑÑ ÑабоÑаеÑ!
УлÑÑÑаем ÑпеÑиÑикаÑиÑ
ÐонеÑно, Ð¼Ñ ÑжÑлÑниÑали. ФÑнкÑÐ¸Ñ Ð½Ðµ ÑабоÑаеÑ. ÐопÑÑка поÑÑиÑаÑÑ pow(3, 3) даÑÑ Ð½ÐµÐºÐ¾ÑÑекÑнÑй ÑезÑлÑÑаÑ, однако ÑеÑÑÑ Ð¿ÑоÑ
одÑÑ.
â¦Ð¢Ð°ÐºÐ°Ñ ÑиÑÑаÑÐ¸Ñ Ð²Ð¿Ð¾Ð»Ð½Ðµ ÑипиÑна, она ÑлÑÑаеÑÑÑ Ð½Ð° пÑакÑике. ТеÑÑÑ Ð¿ÑÐ¾Ñ Ð¾Ð´ÑÑ, но ÑÑнкÑÐ¸Ñ ÑабоÑÐ°ÐµÑ Ð½ÐµÐ¿ÑавилÑно. ÐаÑа ÑпеÑиÑикаÑÐ¸Ñ Ð½Ðµ идеалÑна. ÐÑжно дополниÑÑ ÐµÑ ÑеÑÑами.
ÐавайÑе добавим еÑÑ Ð¾Ð´Ð¸Ð½ ÑеÑÑ, ÑÑÐ¾Ð±Ñ Ð¿Ð¾ÑмоÑÑеÑÑ, ÑÑо pow(3, 3) = 27.
У Ð½Ð°Ñ ÐµÑÑÑ Ð´Ð²Ð° пÑÑи оÑганизаÑии ÑеÑÑов:
-
ÐеÑвÑй â добавиÑÑ ÐµÑÑ Ð¾Ð´Ð¸Ð½
assertв ÑÑÑеÑÑвÑÑÑийit:describe("pow", function() { it("Ð²Ð¾Ð·Ð²Ð¾Ð´Ð¸Ñ ÑиÑло в ÑÑÐµÐ¿ÐµÐ½Ñ n", function() { assert.equal(pow(2, 3), 8); assert.equal(pow(3, 3), 27); }); }); -
ÐÑоÑой â напиÑаÑÑ Ð´Ð²Ð° ÑеÑÑа:
describe("pow", function() { it("2 в ÑÑепени 3 бÑÐ´ÐµÑ 8", function() { assert.equal(pow(2, 3), 8); }); it("3 в ÑÑепени 3 бÑÐ´ÐµÑ 27", function() { assert.equal(pow(3, 3), 27); }); });
ÐÑинÑипиалÑÐ½Ð°Ñ ÑазниÑа в Ñом, ÑÑо когда один из assert вÑбÑаÑÑÐ²Ð°ÐµÑ Ð¾ÑибкÑ, Ñо вÑполнение it блока ÑÑÑ Ð¶Ðµ пÑекÑаÑаеÑÑÑ. Таким обÑазом, еÑли пеÑвÑй assert вÑбÑоÑÐ¸Ñ Ð¾ÑибкÑ, ÑезÑлÑÑÐ°Ñ ÑабоÑÑ Ð²ÑоÑого assert Ð¼Ñ Ñже не Ñзнаем.
РазделÑÑÑ ÑеÑÑÑ Ð¿ÑедпоÑÑиÑелÑнее, Ñак как Ð¼Ñ Ð¿Ð¾Ð»ÑÑаем болÑÑе инÑоÑмаÑии о Ñом, ÑÑо конкÑеÑно поÑло не Ñак.
Ðомимо ÑÑого еÑÑÑ Ð¾Ð´Ð½Ð¾ Ñ Ð¾ÑоÑее пÑавило, коÑоÑÐ¾Ð¼Ñ ÑÑÐ¾Ð¸Ñ ÑледоваÑÑ.
Ðдин ÑеÑÑ Ð¿ÑовеÑÑÐµÑ Ð¾Ð´Ð½Ñ Ð²ÐµÑÑ.
ÐÑли Ð²Ñ Ð¿Ð¾ÑмоÑÑиÑе на ÑеÑÑ Ð¸ ÑвидиÑе в нÑм две незавиÑимÑе пÑовеÑки, Ñо Ñакой ÑеÑÑ Ð»ÑÑÑе ÑазделиÑÑ Ð½Ð° два более пÑоÑÑÑÑ .
ÐавайÑе пÑодолжим Ñо вÑоÑÑм ваÑианÑом.
РезÑлÑÑаÑÑ:
Ðак Ð¼Ñ Ð¸ ожидали, вÑоÑой ÑеÑÑ Ð¿ÑовалилÑÑ. ÐÑÑеÑÑвенно, наÑа ÑÑнкÑÐ¸Ñ Ð²Ñегда возвÑаÑÐ°ÐµÑ 8, в Ñо вÑÐµÐ¼Ñ ÐºÐ°Ðº assert Ð¾Ð¶Ð¸Ð´Ð°ÐµÑ 27.
УлÑÑÑаем ÑеализаÑиÑ
ÐавайÑе напиÑем ÑÑо-Ñо более Ð¿Ð¾Ñ Ð¾Ð¶ÐµÐµ на ÑÑнкÑÐ¸Ñ Ð²Ð¾Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð² ÑÑепенÑ, ÑÑÐ¾Ð±Ñ Ð·Ð°ÑÑавиÑÑ ÑеÑÑÑ Ð¿ÑÐ¾Ñ Ð¾Ð´Ð¸ÑÑ.
function pow(x, n) {
let result = 1;
for (let i = 0; i < n; i++) {
result *= x;
}
return result;
}
ЧÑÐ¾Ð±Ñ ÑбедиÑÑÑÑ, ÑÑо ÑÑа ÑеализаÑÐ¸Ñ ÑабоÑÐ°ÐµÑ Ð½Ð¾ÑмалÑно, давайÑе пÑоÑеÑÑиÑÑем ÐµÑ Ð½Ð° болÑÑем колиÑеÑÑве знаÑений. ЧÑÐ¾Ð±Ñ Ð½Ðµ пиÑаÑÑ Ð²ÑÑÑнÑÑ ÐºÐ°Ð¶Ð´Ñй блок it, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ генеÑиÑоваÑÑ Ð¸Ñ
в Ñикле for:
describe("pow", function() {
function makeTest(x) {
let expected = x * x * x;
it(`${x} в ÑÑепени 3 бÑÐ´ÐµÑ ${expected}`, function() {
assert.equal(pow(x, 3), expected);
});
}
for (let x = 1; x <= 5; x++) {
makeTest(x);
}
});
РезÑлÑÑаÑ:
ÐложеннÑе блоки describe
ÐÑ ÑобиÑаемÑÑ Ð´Ð¾Ð±Ð°Ð²Ð¸ÑÑ Ð±Ð¾Ð»ÑÑе ÑеÑÑов. Ðднако, пеÑед ÑÑим ÑÑÐ¾Ð¸Ñ ÑгÑÑппиÑоваÑÑ Ð²ÑпомогаÑелÑнÑÑ ÑÑнкÑÐ¸Ñ makeTest и Ñикл for. Ðам не нÑжна ÑÑнкÑÐ¸Ñ makeTest в дÑÑгиÑ
ÑеÑÑаÑ
, она нÑжна ÑолÑко в Ñикле for. ÐÑ Ð¿ÑедназнаÑение â пÑовеÑиÑÑ, ÑÑо pow пÑавилÑно Ð²Ð¾Ð·Ð²Ð¾Ð´Ð¸Ñ ÑиÑло в заданнÑÑ ÑÑепенÑ.
ÐÑÑппиÑовка пÑоизводиÑÑÑ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð½Ñми блоками describe:
describe("pow", function() {
describe("Ð²Ð¾Ð·Ð²Ð¾Ð´Ð¸Ñ x в ÑÑÐµÐ¿ÐµÐ½Ñ 3", function() {
function makeTest(x) {
let expected = x * x * x;
it(`${x} в ÑÑепени 3 бÑÐ´ÐµÑ ${expected}`, function() {
assert.equal(pow(x, 3), expected);
});
}
for (let x = 1; x <= 5; x++) {
makeTest(x);
}
});
// ... дÑÑгие ÑеÑÑÑ. Ðожно пиÑаÑÑ Ð¸ describe, и it блоки.
});
ÐложеннÑе describe обÑазÑÑÑ Ð½Ð¾Ð²ÑÑ Ð¿Ð¾Ð´Ð³ÑÑÐ¿Ð¿Ñ ÑеÑÑов. Ð ÑезÑлÑÑаÑаÑ
Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ видеÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе оÑÑÑÑÐ¿Ñ Ð² названиÑÑ
.
РбÑдÑÑем Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ напиÑаÑÑ Ð½Ð¾Ð²Ñе it и describe блоки на веÑÑ
нем ÑÑовне Ñо Ñвоими ÑобÑÑвеннÑми вÑпомогаÑелÑнÑми ÑÑнкÑиÑми. Ðм не бÑÐ´ÐµÑ Ð´Ð¾ÑÑÑпна ÑÑнкÑÐ¸Ñ makeTest из пÑимеÑа вÑÑе.
before/after и beforeEach/afterEachÐÑ Ð¼Ð¾Ð¶ÐµÐ¼ задаÑÑ before/after ÑÑнкÑии, коÑоÑÑе бÑдÑÑ Ð²ÑполнÑÑÑÑÑ Ð´Ð¾/поÑле ÑеÑÑов, а Ñакже ÑÑнкÑии beforeEach/afterEach, вÑполнÑемÑе до/поÑле каждого it.
ÐапÑимеÑ:
describe("ÑеÑÑ", function() {
before(() => alert("ТеÑÑиÑование наÑалоÑÑ â пеÑед ÑеÑÑами"));
after(() => alert("ТеÑÑиÑование законÑилоÑÑ â поÑле вÑеÑ
ÑеÑÑов"));
beforeEach(() => alert("ÐеÑед ÑеÑÑом â наÑинаем вÑполнÑÑÑ ÑеÑÑ"));
afterEach(() => alert("ÐоÑле ÑеÑÑа â заканÑиваем вÑполнение ÑеÑÑа"));
it('ÑеÑÑ 1', () => alert(1));
it('ÑеÑÑ 2', () => alert(2));
});
ÐоÑÑдок вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð±ÑÐ´ÐµÑ Ñаким:
ТеÑÑиÑование наÑалоÑÑ â пеÑед ÑеÑÑами (before)
ÐеÑед ÑеÑÑом â наÑинаем вÑполнÑÑÑ ÑеÑÑ (beforeEach)
1
ÐоÑле ÑеÑÑа â заканÑиваем вÑполнение ÑеÑÑа (afterEach)
ÐеÑед ÑеÑÑом â наÑинаем вÑполнÑÑÑ ÑеÑÑ (beforeEach)
2
ÐоÑле ÑеÑÑа â заканÑиваем вÑполнение ÑеÑÑа (afterEach)
ТеÑÑиÑование законÑилоÑÑ â поÑле вÑеÑ
ÑеÑÑов (after)
ÐбÑÑно beforeEach/afterEach и before/after иÑполÑзÑÑÑÑÑ Ð´Ð»Ñ Ð¸Ð½Ð¸ÑиализаÑии, обнÑÐ»ÐµÐ½Ð¸Ñ ÑÑÑÑÑиков или Ñего-нибÑÐ´Ñ ÐµÑÑ Ð¼ÐµÐ¶Ð´Ñ ÑеÑÑами (или гÑÑппами ÑеÑÑов).
РаÑÑиÑение ÑпеÑиÑикаÑии
ÐÑÐ½Ð¾Ð²Ð½Ð°Ñ ÑÑнкÑионалÑноÑÑÑ pow Ñеализована. ÐеÑÐ²Ð°Ñ Ð¸ÑеÑаÑÐ¸Ñ ÑазÑабоÑки завеÑÑена. Ðогда Ð¼Ñ Ð·Ð°ÐºÐ¾Ð½Ñим оÑмеÑаÑÑ Ð¸ пиÑÑ ÑампанÑкое, давайÑе пÑодолжим ÑабоÑÑ Ð¸ ÑлÑÑÑим pow.
Ðак бÑло Ñказано, ÑÑнкÑÐ¸Ñ pow(x, n) пÑедназнаÑена Ð´Ð»Ñ ÑабоÑÑ Ñ ÑелÑми положиÑелÑнÑми знаÑениÑми n.
ÐÐ»Ñ Ð¾Ð±Ð¾Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð¼Ð°ÑемаÑиÑеÑкиÑ
оÑибок ÑÑнкÑии JavaScript обÑÑно возвÑаÑаÑÑ NaN. ÐавайÑе делаÑÑ Ñакже Ð´Ð»Ñ Ð½ÐµÐºÐ¾ÑÑекÑнÑÑ
знаÑений n.
СнаÑала давайÑе опиÑем ÑÑо поведение в ÑпеÑиÑикаÑии.
describe("pow", function() {
// ...
it("Ð´Ð»Ñ Ð¾ÑÑиÑаÑелÑнÑÑ
n возвÑаÑÐ°ÐµÑ NaN", function() {
assert.isNaN(pow(2, -1));
});
it("Ð´Ð»Ñ Ð´ÑобнÑÑ
n возвÑаÑÐ°ÐµÑ NaN", function() {
assert.isNaN(pow(2, 1.5));
});
});
РезÑлÑÑаÑÑ Ñ Ð½Ð¾Ð²Ñми ÑеÑÑами:
ÐовÑе ÑеÑÑÑ Ð¿Ð°Ð´Ð°ÑÑ, поÑÐ¾Ð¼Ñ ÑÑо наÑа ÑеализаÑÐ¸Ñ Ð½Ðµ поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð¸Ñ . Так ÑабоÑÐ°ÐµÑ BDD. СнаÑала Ð¼Ñ Ð´Ð¾Ð±Ð°Ð²Ð»Ñем ÑеÑÑÑ, коÑоÑÑе падаÑÑ, а Ñже поÑом пиÑем под Ð½Ð¸Ñ ÑеализаÑиÑ.
ÐбÑаÑиÑе внимание на assert.isNaN. ÐÑо пÑовеÑка Ñого, ÑÑо пеÑеданное знаÑение Ñавно NaN.
ÐиблиоÑека Chai ÑодеÑÐ¶Ð¸Ñ Ð¼Ð½Ð¾Ð¶ÐµÑÑво дÑÑÐ³Ð¸Ñ Ð¿Ð¾Ð´Ð¾Ð±Ð½ÑÑ ÑÑнкÑий, напÑимеÑ:
assert.equal(value1, value2)â пÑовеÑÑÐµÑ ÑавенÑÑвоvalue1 == value2.assert.strictEqual(value1, value2)â пÑовеÑÑÐµÑ ÑÑÑогое ÑавенÑÑвоvalue1 === value2.assert.notEqual,assert.notStrictEqualâ пÑовеÑÑÐµÑ Ð½ÐµÑавенÑÑво и ÑÑÑогое неÑавенÑÑво ÑооÑвеÑÑÑвенно.assert.isTrue(value)â пÑовеÑÑеÑ, ÑÑоvalue === trueassert.isFalse(value)â пÑовеÑÑеÑ, ÑÑоvalue === false- â¦Ñ полнÑм ÑпиÑком можно ознакомиÑÑÑÑ Ð² докÑменÑаÑии
ÐÑак, нам нÑжно добавиÑÑ Ð¿Ð°ÑÑ ÑÑÑоÑек в ÑÑнкÑÐ¸Ñ pow:
function pow(x, n) {
if (n < 0) return NaN;
if (Math.round(n) != n) return NaN;
let result = 1;
for (let i = 0; i < n; i++) {
result *= x;
}
return result;
}
ТепеÑÑ ÑабоÑаеÑ, вÑе ÑеÑÑÑ Ð¿ÑÐ¾Ñ Ð¾Ð´ÑÑ:
ÐÑого
Ð BDD ÑнаÑала пиÑÑÑ ÑпеÑиÑикаÑиÑ, а поÑом ÑеализаÑиÑ. РконÑе Ñ Ð½Ð°Ñ ÐµÑÑÑ Ð¸ Ñо, и дÑÑгое.
СпеÑиÑикаÑÐ¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ иÑполÑзоваÑÑ ÑÑÐµÐ¼Ñ ÑпоÑобами:
- Ðак ТеÑÑÑ â они гаÑанÑиÑÑÑÑ, ÑÑо ÑÑнкÑÐ¸Ñ ÑабоÑÐ°ÐµÑ Ð¿ÑавилÑно.
- Ðак ÐокÑменÑаÑÐ¸Ñ â заголовки блоков
describeиitопиÑÑваÑÑ Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ðµ ÑÑнкÑии. - Ðак ÐÑимеÑÑ â ÑеÑÑÑ, по ÑÑÑи, ÑвлÑÑÑÑÑ Ð³Ð¾ÑовÑми пÑимеÑами иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑÑнкÑии.
ÐÐ¼ÐµÑ ÑпеÑиÑикаÑиÑ, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ ÑлÑÑÑиÑÑ, измениÑÑ Ð¸ даже пеÑепиÑаÑÑ ÑÑнкÑÐ¸Ñ Ñ Ð½ÑлÑ, и пÑи ÑÑом Ð¼Ñ Ð±Ñдем ÑвеÑенÑ, ÑÑо она пÑÐ¾Ð´Ð¾Ð»Ð¶Ð°ÐµÑ ÑабоÑаÑÑ Ð¿ÑавилÑно.
ÐÑо оÑобенно важно в болÑÑÐ¸Ñ Ð¿ÑоекÑÐ°Ñ , когда одна ÑÑнкÑÐ¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¸ÑполÑзована во множеÑÑве меÑÑ. Ðогда Ð¼Ñ Ð²Ð½Ð¾Ñим в ÑакÑÑ ÑÑнкÑÐ¸Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ, Ñ Ð½Ð°Ñ Ð½ÐµÑ Ð½Ð¸ÐºÐ°ÐºÐ¾Ð¹ возможноÑÑи вÑÑÑнÑÑ Ð¿ÑовеÑиÑÑ, ÑÑо она пÑÐ¾Ð´Ð¾Ð»Ð¶Ð°ÐµÑ ÑабоÑаÑÑ Ð¿ÑавилÑно во вÑÐµÑ Ð¼ÐµÑÑÐ°Ñ , где ÐµÑ Ð¸ÑполÑзÑÑÑ.
Ðе Ð¸Ð¼ÐµÑ ÑеÑÑов, лÑдÑм пÑÐ¸Ñ Ð¾Ð´Ð¸ÑÑÑ Ð²ÑбиÑаÑÑ Ð¾Ð´Ð¸Ð½ из двÑÑ Ð¿ÑÑей:
- ÐнеÑÑи изменениÑ, и неважно, ÑÑо бÑдеÑ. ÐоÑом Ñ Ð½Ð°ÑÐ¸Ñ Ð¿Ð¾Ð»ÑзоваÑелей ÑÑанÑÑ Ð¿ÑоÑвлÑÑÑÑÑ Ð¾Ñибки, Ð²ÐµÐ´Ñ Ð¼Ñ Ð½Ð°Ð²ÐµÑнÑка ÑÑо-Ñо забÑдем пÑовеÑиÑÑ Ð²ÑÑÑнÑÑ.
- Ðли же, еÑли наказание за оÑибки в коде ÑеÑÑÑзное, Ñо лÑди пÑоÑÑо побоÑÑÑÑ Ð²Ð½Ð¾ÑиÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² Ñакие ÑÑнкÑии. Ðод бÑÐ´ÐµÑ ÑÑаÑеÑÑ, «заÑаÑÑаÑÑ Ð¿Ð°ÑÑиной», и никÑо не Ð·Ð°Ñ Ð¾ÑÐµÑ Ð² него лезÑÑ. ÐÑо Ð½ÐµÑ Ð¾ÑоÑо Ð´Ð»Ñ ÑазÑабоÑки.
ÐвÑомаÑиÑеÑкое ÑеÑÑиÑование кода позволÑÐµÑ Ð¸Ð·Ð±ÐµÐ¶Ð°ÑÑ ÑÑÐ¸Ñ Ð¿Ñоблем!
ÐÑли пÑÐ¾ÐµÐºÑ Ð¿Ð¾ÐºÑÑÑ ÑеÑÑами, Ñо вÑÑеÑпомÑнÑÑÑе пÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ð½Ðµ возникаÑÑ. ÐоÑле лÑбÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹ Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ запÑÑÑиÑÑ ÑеÑÑÑ Ð¸ ÑвидеÑÑ ÑезÑлÑÑаÑÑ Ð¾Ð³Ñомного колиÑеÑÑва пÑовеÑок, ÑделаннÑÑ Ð·Ð° ÑекÑндÑ.
ÐÑоме Ñого, код, Ñ Ð¾ÑоÑо покÑÑÑÑй ÑеÑÑами, как пÑавило, Ð¸Ð¼ÐµÐµÑ Ð»ÑÑÑÑÑ Ð°ÑÑ Ð¸ÑекÑÑÑÑ.
ÐÑо еÑÑеÑÑвенно, Ð²ÐµÐ´Ñ Ñакой код легÑе менÑÑÑ Ð¸ ÑлÑÑÑаÑÑ. Ðо не ÑолÑко по ÑÑой пÑиÑине.
ÐÐ»Ñ Ð½Ð°Ð¿Ð¸ÑÐ°Ð½Ð¸Ñ ÑеÑÑов нÑжно оÑганизоваÑÑ ÐºÐ¾Ð´ Ñаким обÑазом, ÑÑÐ¾Ð±Ñ Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ ÑÑнкÑии бÑла ÑÑно поÑÑÐ°Ð²Ð»ÐµÐ½Ð½Ð°Ñ Ð·Ð°Ð´Ð°Ñа и ÑоÑно опÑÐµÐ´ÐµÐ»ÐµÐ½Ñ ÐµÑ Ð°ÑгÑменÑÑ Ð¸ возвÑаÑаемое знаÑение. Ð ÑÑо ознаÑаеÑ, ÑÑо Ð¼Ñ Ð¿Ð¾Ð»ÑÑаем Ñ Ð¾ÑоÑÑÑ Ð°ÑÑ Ð¸ÑекÑÑÑÑ Ñ Ñамого наÑала.
Ð ÑеалÑноÑÑи ÑÑо не вÑегда Ñак пÑоÑÑо. Ðногда Ñложно напиÑаÑÑ ÑпеÑиÑикаÑÐ¸Ñ Ð´Ð¾ Ñого, как бÑÐ´ÐµÑ Ð½Ð°Ð¿Ð¸Ñана ÑеализаÑиÑ, поÑÐ¾Ð¼Ñ ÑÑо не вÑегда ÑÑÑко понÑÑно, как Ñа или Ð¸Ð½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ð° ÑÐµÐ±Ñ Ð²ÐµÑÑи. Ðо в обÑем и Ñелом напиÑание ÑеÑÑов Ð´ÐµÐ»Ð°ÐµÑ ÑазÑабоÑÐºÑ Ð±ÑÑÑÑее, а иÑоговÑй пÑодÑÐºÑ Ð±Ð¾Ð»ÐµÐµ ÑÑабилÑнÑм.
Ðалее по книге Ð¼Ñ Ð²ÑÑÑеÑим много Ð·Ð°Ð´Ð°Ñ Ñ ÑеÑÑами, Ñак ÑÑо Ð²Ñ ÑвидиÑе много пÑакÑиÑеÑÐºÐ¸Ñ Ð¿ÑимеÑов.
ÐапиÑание ÑеÑÑов ÑÑебÑÐµÑ Ñ Ð¾ÑоÑего Ð·Ð½Ð°Ð½Ð¸Ñ JavaScript. Ðо Ð¼Ñ ÑолÑко наÑали ÑÑиÑÑ ÐµÐ³Ð¾. Ðе волнÑйÑеÑÑ. Ðока вам не нÑжно пиÑаÑÑ ÑеÑÑÑ, но Ð²Ñ Ñже ÑмееÑе Ð¸Ñ ÑиÑаÑÑ Ð¸ поймÑÑе даже более ÑложнÑе пÑимеÑÑ, Ñем Ñе, ÑÑо бÑли пÑедÑÑÐ°Ð²Ð»ÐµÐ½Ñ Ð² ÑÑой главе.
ÐомменÑаÑии
<code>, Ð´Ð»Ñ Ð½ÐµÑколÑÐºÐ¸Ñ ÑÑÑок кода — Ñег<pre>, еÑли болÑÑе 10 ÑÑÑок — ÑÑÑÐ»ÐºÑ Ð½Ð° пеÑоÑниÑÑ (plnkr, JSBin, codepenâ¦)