Ð ÑÑой главе Ð¼Ñ ÑазбеÑÑм оÑÐ½Ð¾Ð²Ñ Ð°Ð²ÑомаÑиÑеÑкого ÑеÑÑиÑованиÑ. Ðно бÑÐ´ÐµÑ Ð¿ÑименÑÑÑÑÑ Ð´Ð°Ð»ÐµÐµ в задаÑÐ°Ñ , и вообÑе, Ð²Ñ Ð¾Ð´Ð¸Ñ Ð² «обÑазоваÑелÑнÑй минимÑм» пÑогÑаммиÑÑа.
ÐаÑем нÑÐ¶Ð½Ñ ÑеÑÑÑ?
ÐÑи напиÑании ÑÑнкÑии Ð¼Ñ Ð¾Ð±ÑÑно пÑедÑÑавлÑем, ÑÑо она должна делаÑÑ, какое знаÑение на ÐºÐ°ÐºÐ¸Ñ Ð°ÑгÑменÑÐ°Ñ Ð²ÑдаваÑÑ.
РпÑоÑеÑÑе ÑазÑабоÑки Ð¼Ñ Ð²ÑÐµÐ¼Ñ Ð¾Ñ Ð²Ñемени пÑовеÑÑем, пÑавилÑно ли ÑабоÑÐ°ÐµÑ ÑÑнкÑиÑ. СамÑй пÑоÑÑой ÑпоÑоб пÑовеÑиÑÑ â ÑÑо запÑÑÑиÑÑ ÐµÑ, напÑÐ¸Ð¼ÐµÑ Ð² конÑоли, и поÑмоÑÑеÑÑ ÑезÑлÑÑаÑ.
ÐÑли ÑÑо-Ñо не Ñак, попÑавиÑÑ, опÑÑÑ Ð·Ð°Ð¿ÑÑÑиÑÑ â поÑмоÑÑеÑÑ ÑезÑлÑÑаÑ⦠РÑак «до победного конÑа».
Ðо Ñакие ÑÑÑнÑе запÑÑки â оÑÐµÐ½Ñ Ð½ÐµÑовеÑÑенное ÑÑедÑÑво пÑовеÑки.
Ðогда пÑовеÑÑеÑÑ ÑабоÑÑ ÐºÐ¾Ð´Ð° вÑÑÑнÑÑ â легко его «недоÑеÑÑиÑоваÑÑ».
ÐапÑимеÑ, пиÑем ÑÑнкÑÐ¸Ñ f. ÐапиÑали, ÑеÑÑиÑÑем Ñ ÑазнÑми аÑгÑменÑами. ÐÑзов ÑÑнкÑии f(a) ÑабоÑаеÑ, а Ð²Ð¾Ñ f(b) не ÑабоÑаеÑ. ÐопÑавили код â ÑÑало ÑабоÑаÑÑ f(b), вÑоде законÑили. Ðо пÑи ÑÑом забÑли заново пÑоÑеÑÑиÑоваÑÑ f(a) â ÑпÑ, Ð²Ð¾Ñ Ð¸ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð°Ñ Ð¾Ñибка в коде.
ÐвÑомаÑизиÑованное ÑеÑÑиÑование â ÑÑо когда ÑеÑÑÑ Ð½Ð°Ð¿Ð¸ÑÐ°Ð½Ñ Ð¾ÑделÑно Ð¾Ñ ÐºÐ¾Ð´Ð°, и можно в лÑбой Ð¼Ð¾Ð¼ÐµÐ½Ñ Ð·Ð°Ð¿ÑÑÑиÑÑ Ð¸Ñ Ð¸ пÑовеÑиÑÑ Ð²Ñе важнÑе ÑлÑÑаи иÑполÑзованиÑ.
BDD â поведенÑеÑкие ÑеÑÑÑ ÐºÐ¾Ð´Ð°
ÐÑ ÑаÑÑмоÑÑим меÑÐ¾Ð´Ð¸ÐºÑ ÑеÑÑиÑованиÑ, коÑоÑÐ°Ñ Ð²Ñ Ð¾Ð´Ð¸Ñ Ð² BDD â Behavior Driven Development. ÐÐ¾Ð´Ñ Ð¾Ð´ BDD давно и Ñ ÑÑÐ¿ÐµÑ Ð¾Ð¼ иÑполÑзÑеÑÑÑ Ð²Ð¾ Ð¼Ð½Ð¾Ð³Ð¸Ñ Ð¿ÑоекÑÐ°Ñ .
BDD â ÑÑо не пÑоÑÑо ÑеÑÑÑ. ÐÑо гоÑаздо болÑÑе.
ТеÑÑÑ BDD â ÑÑо ÑÑи в одном: Ð ÑеÑÑÑ, РдокÑменÑаÑиÑ, РпÑимеÑÑ Ð¸ÑполÑзованиÑ.
ÐпÑоÑем, Ñ Ð²Ð°ÑÐ¸Ñ Ñлов. РаÑÑмоÑÑим пÑимеÑÑ.
РазÑабоÑка pow: ÑпеÑиÑикаÑиÑ
ÐопÑÑÑим, Ð¼Ñ Ñ
оÑим ÑазÑабоÑаÑÑ ÑÑнкÑÐ¸Ñ pow(x, n), коÑоÑÐ°Ñ Ð²Ð¾Ð·Ð²Ð¾Ð´Ð¸Ñ x в ÑелÑÑ ÑÑÐµÐ¿ÐµÐ½Ñ n, Ð´Ð»Ñ Ð¿ÑоÑÑоÑÑ nâ¥0.
ÐÑÑ Ð´Ð¾ ÑазÑабоÑки Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ пÑедÑÑавиÑÑ Ñебе, ÑÑо ÑÑа ÑÑнкÑÐ¸Ñ Ð±ÑÐ´ÐµÑ Ð´ÐµÐ»Ð°ÑÑ, и опиÑаÑÑ ÑÑо по меÑодике BDD.
ÐÑо опиÑание назÑваеÑÑÑ ÑпеÑиÑикаÑÐ¸Ñ (или, как говоÑÑÑ Ð² Ð¾Ð±Ð¸Ñ Ð¾Ð´Ðµ, «Ñпека») и вÑглÑÐ´Ð¸Ñ Ñак:
describe("pow", function() {
it("Ð²Ð¾Ð·Ð²Ð¾Ð´Ð¸Ñ Ð² n-Ñ ÑÑепенÑ", function() {
assert.equal(pow(2, 3), 8);
});
});
У ÑпеÑиÑикаÑии еÑÑÑ ÑÑи оÑновнÑÑ ÑÑÑоиÑелÑнÑÑ Ð±Ð»Ð¾ÐºÐ°, коÑоÑÑе Ð²Ñ Ð²Ð¸Ð´Ð¸Ñе в пÑимеÑе вÑÑе:
describe(название, function() { ... })-
ÐадаÑÑ, ÑÑо именно Ð¼Ñ Ð¾Ð¿Ð¸ÑÑваем, иÑполÑзÑеÑÑÑ Ð´Ð»Ñ Ð³ÑÑппиÑовки «ÑабоÑÐ¸Ñ Ð»Ð¾Ñадок» â блоков
it. Рданном ÑлÑÑае Ð¼Ñ Ð¾Ð¿Ð¸ÑÑваем ÑÑнкÑиÑpow. it(название, function() { ... })-
Рназвании блока
itÑеловеÑеÑким ÑзÑком опиÑÑваеÑÑÑ, ÑÑо должна делаÑÑ ÑÑнкÑиÑ, далее ÑледÑÐµÑ ÑеÑÑ, коÑоÑÑй пÑовеÑÑÐµÑ ÑÑо. assert.equal(value1, value2)-
Ðод внÑÑÑи
it, еÑли ÑеализаÑÐ¸Ñ Ð²ÐµÑна, должен вÑполнÑÑÑÑÑ Ð±ÐµÐ· оÑибок.РазлиÑнÑе ÑÑнкÑии вида
assert.*иÑполÑзÑÑÑÑÑ, ÑÑÐ¾Ð±Ñ Ð¿ÑовеÑиÑÑ, Ð´ÐµÐ»Ð°ÐµÑ Ð»Ð¸powÑо, ÑÑо задÑмано. Ðока ÑÑо Ð½Ð°Ñ Ð¸Ð½ÑеÑеÑÑÐµÑ ÑолÑко одна из Ð½Ð¸Ñ âassert.equal, она ÑÑÐ°Ð²Ð½Ð¸Ð²Ð°ÐµÑ Ñвой пеÑвÑй аÑгÑÐ¼ÐµÐ½Ñ Ñо вÑоÑÑм и вÑдаÑÑ Ð¾ÑÐ¸Ð±ÐºÑ Ð² ÑлÑÑае, когда они не ÑавнÑ. Рданном ÑлÑÑае она пÑовеÑÑеÑ, ÑÑо ÑезÑлÑÑаÑpow(2, 3)Ñавен8.ÐÑÑÑ Ð¸ дÑÑгие Ð²Ð¸Ð´Ñ ÑÑавнений и пÑовеÑок, коÑоÑÑе Ð¼Ñ Ñвидим далее.
ÐоÑок ÑазÑабоÑки
Ðак пÑавило, поÑок ÑазÑабоÑки Ñаков:
- ÐиÑеÑÑÑ ÑпеÑиÑикаÑиÑ, коÑоÑÐ°Ñ Ð¾Ð¿Ð¸ÑÑÐ²Ð°ÐµÑ ÑамÑÑ Ð±Ð°Ð·Ð¾Ð²ÑÑ ÑÑнкÑионалÑноÑÑÑ.
- ÐелаеÑÑÑ Ð½Ð°ÑалÑÐ½Ð°Ñ ÑеализаÑиÑ.
- ÐÐ»Ñ Ð¿ÑовеÑки ÑооÑвеÑÑÑÐ²Ð¸Ñ ÑпеÑиÑикаÑии Ð¼Ñ Ð·Ð°Ð´ÐµÐ¹ÑÑвÑем ÑÑеймвоÑк (в наÑем ÑлÑÑае Mocha). ФÑеймвоÑк запÑÑÐºÐ°ÐµÑ Ð²Ñе ÑеÑÑÑ
itи вÑÐ²Ð¾Ð´Ð¸Ñ Ð¾Ñибки, еÑли они возникнÑÑ. ÐÑи оÑÐ¸Ð±ÐºÐ°Ñ Ð²Ð½Ð¾ÑÑÑÑÑ Ð¸ÑпÑавлениÑ. - СпеÑиÑикаÑÐ¸Ñ ÑаÑÑиÑÑеÑÑÑ, в Ð½ÐµÑ Ð´Ð¾Ð±Ð°Ð²Ð»ÑÑÑÑÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ÑÑи, коÑоÑÑе пока, возможно, не поддеÑживаÑÑÑÑ ÑеализаÑией.
- ÐдÑм на пÑÐ½ÐºÑ 2, делаем ÑеализаÑиÑ. Ð Ñак «до победного конÑа».
РазÑабоÑка ведÑÑÑÑ Ð¸ÑеÑаÑивно: один пÑÐ¾Ñ Ð¾Ð´ за дÑÑгим, пока ÑпеÑиÑикаÑÐ¸Ñ Ð¸ ÑеализаÑÐ¸Ñ Ð½Ðµ бÑдÑÑ Ð·Ð°Ð²ÐµÑÑенÑ.
РнаÑем ÑлÑÑае пеÑвÑй Ñаг Ñже завеÑÑÑн, наÑалÑÐ½Ð°Ñ ÑпеÑиÑикаÑÐ¸Ñ Ð³Ð¾Ñова, Ñ Ð¾ÑоÑо Ð±Ñ Ð¿ÑиÑÑÑпиÑÑ Ðº ÑеализаÑии. Ðо пеÑед ÑÑим пÑоведÑм «нÑлевой» запÑÑк ÑпеÑиÑикаÑии, пÑоÑÑо ÑÑÐ¾Ð±Ñ ÑвидеÑÑ, ÑÑо Ñже в Ñаком виде, даже без ÑеализаÑии â ÑеÑÑÑ ÑабоÑаÑÑ.
ÐÑÐ¸Ð¼ÐµÑ Ð² дейÑÑвии
ÐÐ»Ñ Ð·Ð°Ð¿ÑÑка ÑеÑÑов нÑÐ¶Ð½Ñ ÑооÑвеÑÑÑвÑÑÑие JavaScript-библиоÑеки.
ÐÑ Ð±Ñдем иÑполÑзоваÑÑ:
- Mocha â ÑÑа библиоÑека ÑодеÑÐ¶Ð¸Ñ Ð¾Ð±Ñие ÑÑнкÑии Ð´Ð»Ñ ÑеÑÑиÑованиÑ, вклÑÑаÑ
describeиit. - Chai â библиоÑека поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ ÑазнообÑазнÑе ÑÑнкÑии Ð´Ð»Ñ Ð¿ÑовеÑок. ÐÑÑÑ ÑазнÑе «ÑÑили» пÑовеÑки ÑезÑлÑÑаÑов, Ñ ÐºÐ¾ÑоÑÑми Ð¼Ñ Ð¿Ð¾Ð·Ð½Ð°ÐºÐ¾Ð¼Ð¸Ð¼ÑÑ Ð¿Ð¾Ð·Ð¶Ðµ, на ÑекÑÑий Ð¼Ð¾Ð¼ÐµÐ½Ñ Ð¼Ñ Ð±Ñдем иÑполÑзоваÑÑ Ð»Ð¸ÑÑ
assert.equal. - Sinon â Ð´Ð»Ñ ÑмÑлÑÑии и Ñ Ð¸ÑÑой Ð¿Ð¾Ð´Ð¼ÐµÐ½Ñ ÑÑнкÑий «заглÑÑками», понадобиÑÑÑ Ð¿Ð¾Ð·Ð´Ð½ÐµÐµ.
ÐÑи библиоÑеки позволÑÑÑ ÑеÑÑиÑоваÑÑ JS не ÑолÑко в бÑаÑзеÑе, но и на ÑеÑвеÑе Node.JS. ÐдеÑÑ Ð¼Ñ ÑаÑÑмоÑÑим бÑаÑзеÑнÑй ваÑианÑ, ÑеÑвеÑнÑй иÑполÑзÑÐµÑ Ñе же ÑÑнкÑии.
ÐÑÐ¸Ð¼ÐµÑ HTML-ÑÑÑаниÑÑ Ð´Ð»Ñ ÑеÑÑов:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- подклÑÑаем ÑÑили Mocha, Ð´Ð»Ñ Ð¾ÑобÑÐ°Ð¶ÐµÐ½Ð¸Ñ ÑезÑлÑÑаÑов -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.1.0/mocha.css">
<!-- подклÑÑаем библиоÑÐµÐºÑ Mocha -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/mocha/2.1.0/mocha.js"></script>
<!-- наÑÑÑаиваем Mocha: пÑедÑÑÐ¾Ð¸Ñ BDD-ÑеÑÑиÑование -->
<script>
mocha.setup('bdd');
</script>
<!-- подклÑÑаем chai -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/2.0.0/chai.js"></script>
<!-- в chai еÑÑÑ Ð¼Ð½Ð¾Ð³Ð¾ вÑего, вÑноÑим assert в глобалÑнÑÑ Ð¾Ð±Ð»Ð°ÑÑÑ -->
<script>
var assert = chai.assert;
</script>
</head>
<body>
<script>
function pow(x, n) {
/* код ÑÑнкÑии, пока ÑÑо пÑÑÑо */
}
</script>
<!-- в ÑÑом ÑкÑипÑе наÑ
одÑÑÑÑ Ñпеки -->
<script src="test.js"></script>
<!-- в ÑлеменÑе Ñ id="mocha" бÑдÑÑ ÑезÑлÑÑаÑÑ ÑеÑÑов -->
<div id="mocha"></div>
<!-- запÑÑÑиÑÑ ÑеÑÑÑ! -->
<script>
mocha.run();
</script>
</body>
</html>
ÐÑÑ ÑÑÑаниÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ ÑÑловно ÑазделиÑÑ Ð½Ð° ÑеÑÑÑе ÑаÑÑи:
- Ðлок
<head>â в нÑм Ð¼Ñ Ð¿Ð¾Ð´ÐºÐ»ÑÑаем библиоÑеки и ÑÑили Ð´Ð»Ñ ÑеÑÑиÑованиÑ, наÑего кода Ñам неÑ. - Ðлок
<script>Ñ ÑеализаÑией ÑпеÑиÑикаÑии, в наÑем ÑлÑÑае â Ñ ÐºÐ¾Ð´Ð¾Ð¼ длÑpow. - Ðалее подклÑÑаÑÑÑÑ ÑеÑÑÑ, Ñайл
test.jsÑодеÑжиÑdescribe("pow", ...), коÑоÑÑй бÑл опиÑан вÑÑе. ÐеÑодÑdescribeиitпÑÐ¸Ð½Ð°Ð´Ð»ÐµÐ¶Ð°Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñеке Mocha, Ñак ÑÑо важно, ÑÑо она бÑла подклÑÑена вÑÑе. - ÐлеменÑ
<div id="mocha">бÑÐ´ÐµÑ Ð¸ÑполÑзоваÑÑÑÑ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ñекой Mocha Ð´Ð»Ñ Ð²Ñвода ÑезÑлÑÑаÑов. ÐапÑÑк ÑеÑÑов иниÑииÑÑеÑÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾Ð¹mocha.run().
РезÑлÑÑÐ°Ñ ÑÑабаÑÑваниÑ:
Ðока ÑÑо ÑеÑÑÑ Ð½Ðµ пÑÐ¾Ñ Ð¾Ð´ÑÑ, но ÑÑо логиÑно â вмеÑÑо ÑÑнкÑии ÑÑÐ¾Ð¸Ñ Â«Ð·Ð°Ð³Ð»ÑÑка», пÑÑÑой код.
Ðока ÑÑо Ñ Ð½Ð°Ñ Ð¾Ð´Ð½Ð° ÑÑнкÑÐ¸Ñ Ð¸ одна ÑпеÑиÑикаÑиÑ, но на бÑдÑÑее замеÑим, ÑÑо еÑли ÑазлиÑнÑÑ
ÑÑнкÑий и ÑеÑÑов много â ÑÑо не пÑоблема, можно иÑ
вÑе подклÑÑиÑÑ Ð½Ð° одной ÑÑÑаниÑе. ÐонÑликÑа не бÑдеÑ, Ñак как каждой ÑаÑÑи кода ÑооÑвеÑÑÑвÑÐµÑ Ñвой блок describe("ÑÑо ÑеÑÑиÑÑем"...). Сами же ÑеÑÑÑ Ð¾Ð±ÑÑно пиÑÑÑÑÑ Ñак, ÑÑÐ¾Ð±Ñ Ð½Ðµ влиÑÑÑ Ð´ÑÑг на дÑÑга, не делаÑÑ Ð»Ð¸ÑниÑ
глобалÑнÑÑ
пеÑеменнÑÑ
.
ÐаÑалÑÐ½Ð°Ñ ÑеализаÑиÑ
Ðока ÑÑо, как видно, ÑеÑÑÑ Ð½Ðµ пÑоÑ
одÑÑ, оÑибка ÑÑÐ°Ð·Ñ Ð¶Ðµ. ÐавайÑе Ñделаем минималÑнÑÑ ÑеализаÑÐ¸Ñ pow, коÑоÑÐ°Ñ Ð±Ñ ÑабоÑала ноÑмалÑно:
function pow() {
return 8; // :) Ð¼Ñ - моÑенники!
}
Ð, Ð²Ð¾Ñ ÑепеÑÑ ÑабоÑаеÑ:
ÐÑпÑавление ÑпеÑиÑикаÑии
ФÑнкÑиÑ, конеÑно, еÑÑ Ð½Ðµ гоÑова, но ÑеÑÑÑ Ð¿ÑÐ¾Ñ Ð¾Ð´ÑÑ. ÐÑо ненадолго :)
ÐдеÑÑ Ð¼Ñ Ð²Ð¸Ð´Ð¸Ð¼ ÑиÑÑаÑиÑ, коÑоÑÐ°Ñ (и не обÑзаÑелÑно пÑи ленивом пÑогÑаммиÑÑе!) бÑÐ²Ð°ÐµÑ Ð½Ð° пÑакÑике â да, еÑÑÑ ÑеÑÑÑ, они пÑÐ¾Ñ Ð¾Ð´ÑÑ, но ÑÑнкÑÐ¸Ñ (ÑвÑ!) ÑабоÑÐ°ÐµÑ Ð½ÐµÐ¿ÑавилÑно.
С ÑоÑки зÑÐµÐ½Ð¸Ñ BDD, оÑибка пÑи пÑÐ¾Ñ Ð¾Ð´ÑÑÐ¸Ñ ÑеÑÑÐ°Ñ â вина ÑпеÑиÑикаÑии.
РпеÑвÑÑ Ð¾ÑеÑÐµÐ´Ñ Ð½Ðµ ÑеализаÑÐ¸Ñ Ð¸ÑпÑавлÑеÑÑÑ, а ÑÑоÑнÑеÑÑÑ ÑпеÑиÑикаÑиÑ, пиÑеÑÑÑ Ð¿Ð°Ð´Ð°ÑÑий ÑеÑÑ.
СейÑÐ°Ñ Ð¼Ñ ÑаÑÑиÑим ÑпеÑиÑикаÑиÑ, добавив пÑовеÑÐºÑ Ð½Ð° pow(3, 4) = 81.
ÐдеÑÑ ÐµÑÑÑ Ð´Ð²Ð° ваÑианÑа оÑганизаÑии кода:
-
ÐеÑвÑй ваÑÐ¸Ð°Ð½Ñ â добавиÑÑ
assertв ÑÐ¾Ñ Ð¶Ðµit:describe("pow", function() { it("Ð²Ð¾Ð·Ð²Ð¾Ð´Ð¸Ñ Ð² n-Ñ ÑÑепенÑ", function() { assert.equal(pow(2, 3), 8); assert.equal(pow(3, 4), 81); }); }); -
ÐÑоÑой ваÑÐ¸Ð°Ð½Ñ â ÑделаÑÑ Ð´Ð²Ð° ÑеÑÑа:
describe("pow", function() { it("пÑи возведении 2 в 3Ñ ÑÑÐµÐ¿ÐµÐ½Ñ ÑезÑлÑÑÐ°Ñ 8", function() { assert.equal(pow(2, 3), 8); }); it("пÑи возведении 3 в 4Ñ ÑÑÐµÐ¿ÐµÐ½Ñ Ñавен 81", function() { assert.equal(pow(3, 4), 81); }); });
ÐÑ
пÑинÑипиалÑное ÑазлиÑие в Ñом, ÑÑо еÑли assert обнаÑÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð¾ÑибкÑ, Ñо он ÑÑÑ Ð¶Ðµ пÑекÑаÑÐ°ÐµÑ Ð²Ñполнение блока it. ÐоÑÑÐ¾Ð¼Ñ Ð² пеÑвом ваÑианÑе, еÑли вдÑÑг пеÑвÑй assert «пÑовалилÑÑ», Ñо пÑо ÑезÑлÑÑÐ°Ñ Ð²ÑоÑого Ð¼Ñ Ð½Ð¸ÐºÐ¾Ð³Ð´Ð° не Ñзнаем.
Таким обÑазом, ÑазделиÑÑ ÑÑи ÑеÑÑÑ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿Ð¾Ð»ÐµÐ·Ð½Ð¾, ÑÑÐ¾Ð±Ñ Ð¼Ñ Ð¿Ð¾Ð»ÑÑили болÑÑе инÑоÑмаÑии о пÑоиÑÑ Ð¾Ð´ÑÑем.
ÐÑоме Ñого, еÑÑÑ ÐµÑÑ Ð¾Ð´Ð½Ð¾ пÑавило, коÑоÑое желаÑелÑно ÑоблÑдаÑÑ.
Ðдин ÑеÑÑ ÑеÑÑиÑÑÐµÑ Ñовно Ð¾Ð´Ð½Ñ Ð²ÐµÑÑ.
ÐÑли Ð¼Ñ Ñвно видим, ÑÑо ÑеÑÑ Ð²ÐºÐ»ÑÑÐ°ÐµÑ Ð² ÑÐµÐ±Ñ ÑовеÑÑенно незавиÑимÑе пÑовеÑки â лÑÑÑе ÑазбиÑÑ ÐµÐ³Ð¾ на два более пÑоÑÑÑÑ Ð¸ наглÑднÑÑ .
Ðо ÑÑим пÑиÑинам вÑоÑой ваÑÐ¸Ð°Ð½Ñ Ð·Ð´ÐµÑÑ Ð¿ÑедпоÑÑиÑелÑнее.
РезÑлÑÑаÑ:
Ðак и Ñледовало ожидаÑÑ, вÑоÑой ÑеÑÑ Ð½Ðµ пÑоÑ
одиÑ. ÐÑÑ Ð±Ñ, Ð²ÐµÐ´Ñ ÑÑнкÑÐ¸Ñ Ð²ÑÑ Ð²ÑÐµÐ¼Ñ Ð²Ð¾Ð·Ð²ÑаÑÐ°ÐµÑ 8.
УÑоÑнение ÑеализаÑии
ÐÑидÑÑÑÑ Ð½Ð°Ð¿Ð¸ÑаÑÑ Ð½ÐµÑÑо более ÑеалÑное, ÑÑÐ¾Ð±Ñ ÑеÑÑÑ Ð¿ÑÐ¾Ñ Ð¾Ð´Ð¸Ð»Ð¸:
function pow(x, n) {
var result = 1;
for (var i = 0; i < n; i++) {
result *= x;
}
return result;
}
ЧÑÐ¾Ð±Ñ Ð±ÑÑÑ ÑвеÑеннÑми, ÑÑо ÑÑнкÑÐ¸Ñ ÑабоÑÐ°ÐµÑ Ð²ÐµÑно, желаÑелÑно пÑоÑеÑÑиÑоваÑÑ ÐµÑ Ð½Ð° болÑÑем колиÑеÑÑве знаÑений. ÐмеÑÑо Ñого, ÑÑÐ¾Ð±Ñ Ð¿Ð¸ÑаÑÑ Ð±Ð»Ð¾ÐºÐ¸ it вÑÑÑнÑÑ, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ ÑгенеÑиÑоваÑÑ ÑеÑÑÑ Ð² Ñикле for:
describe("pow", function() {
function makeTest(x) {
var expected = x * x * x;
it("пÑи возведении " + x + " в ÑÑÐµÐ¿ÐµÐ½Ñ 3 ÑезÑлÑÑаÑ: " + expected, function() {
assert.equal(pow(x, 3), expected);
});
}
for (var x = 1; x <= 5; x++) {
makeTest(x);
}
});
РезÑлÑÑаÑ:
ÐложеннÑй describe
ФÑнкÑÐ¸Ñ makeTest и Ñикл for, оÑевидно, нÑÐ¶Ð½Ñ Ð´ÑÑг дÑÑгÑ, но не нÑÐ¶Ð½Ñ Ð´Ð»Ñ Ð´ÑÑгиÑ
ÑеÑÑов, коÑоÑÑе Ð¼Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸Ð¼ в далÑнейÑем. Ðни обÑазÑÑÑ ÐµÐ´Ð¸Ð½ÑÑ Ð³ÑÑппÑ, задаÑа коÑоÑой â пÑовеÑиÑÑ Ð²Ð¾Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ðµ в n-Ñ ÑÑепенÑ.
ÐÑÐ´ÐµÑ Ð¿ÑавилÑно вÑделиÑÑ Ð¸Ñ
, пÑи помоÑи вложенного блока describe:
describe("pow", function() {
describe("Ð²Ð¾Ð·Ð²Ð¾Ð´Ð¸Ñ x в ÑÑÐµÐ¿ÐµÐ½Ñ n", function() {
function makeTest(x) {
var expected = x * x * x;
it("пÑи возведении " + x + " в ÑÑÐµÐ¿ÐµÐ½Ñ 3 ÑезÑлÑÑаÑ: " + expected, function() {
assert.equal(pow(x, 3), expected);
});
}
for (var x = 1; x <= 5; x++) {
makeTest(x);
}
});
// ... далÑнейÑие ÑеÑÑÑ it и подблоки describe ...
});
ÐложеннÑй describe обÑÑÐ²Ð¸Ñ Ð½Ð¾Ð²ÑÑ Â«Ð¿Ð¾Ð´Ð³ÑÑппÑ» ÑеÑÑов, блоки it коÑоÑой запÑÑкаÑÑÑÑ Ñак же, как и обÑÑно, но вÑводÑÑÑÑ Ñ Ð¿Ð¾Ð´Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ¾Ð¼, Ð²Ð¾Ñ Ñак:
РбÑдÑÑем Ð¼Ñ Ñможем добавиÑÑ Ð´ÑÑгие ÑеÑÑÑ it и блоки describe Ñо Ñвоими вÑпомогаÑелÑнÑми ÑÑнкÑиÑми.
Ркаждом блоке describe можно Ñакже задаÑÑ ÑÑнкÑии before/after, коÑоÑÑе бÑдÑÑ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ñ Ð´Ð¾/поÑле запÑÑка ÑеÑÑов, а Ñакже beforeEach/afterEach, коÑоÑÑе вÑполнÑÑÑÑÑ Ð´Ð¾/поÑле каждого it.
ÐапÑимеÑ:
describe("ТеÑÑ", function() {
before(function() { alert("ÐаÑало ÑеÑÑов"); });
after(function() { alert("ÐÐ¾Ð½ÐµÑ ÑеÑÑов"); });
beforeEach(function() { alert("ÐÑ
од в ÑеÑÑ"); });
afterEach(function() { alert("ÐÑÑ
од из ÑеÑÑа"); });
it('ÑеÑÑ 1', function() { alert('1'); });
it('ÑеÑÑ 2', function() { alert('2'); });
});
ÐоÑледоваÑелÑноÑÑÑ Ð±ÑÐ´ÐµÑ Ñакой:
ÐаÑало ÑеÑÑов
ÐÑ
од в ÑеÑÑ
1
ÐÑÑ
од из ÑеÑÑа
ÐÑ
од в ÑеÑÑ
2
ÐÑÑ
од из ÑеÑÑа
ÐÐ¾Ð½ÐµÑ ÑеÑÑов
Ðак пÑавило, beforeEach/afterEach (before/after) иÑполÑзÑÑÑ, еÑли необÑ
одимо пÑоизвеÑÑи иниÑиализаÑиÑ, обнÑлиÑÑ ÑÑÑÑÑики или ÑделаÑÑ ÑÑо-Ñо еÑÑ Ð² Ñаком дÑÑ
е Ð¼ÐµÐ¶Ð´Ñ ÑеÑÑами (или иÑ
гÑÑппами).
РаÑÑиÑение ÑпеÑиÑикаÑии
ÐÐ°Ð·Ð¾Ð²Ð°Ñ ÑÑнкÑионалÑноÑÑÑ pow опиÑана и Ñеализована, пеÑÐ²Ð°Ñ Ð¸ÑеÑаÑÐ¸Ñ ÑазÑабоÑки завеÑÑена. ТепеÑÑ ÑаÑÑиÑим и ÑÑоÑним еÑ.
Ðак говоÑилоÑÑ Ñанее, ÑÑнкÑÐ¸Ñ pow(x, n) пÑедназнаÑена Ð´Ð»Ñ ÑабоÑÑ Ñ ÑелÑми неоÑÑиÑаÑелÑнÑми n.
Ð JavaScript Ð´Ð»Ñ Ð¾Ñибки вÑÑиÑлений ÑлÑÐ¶Ð¸Ñ ÑпеÑиалÑное знаÑение NaN, коÑоÑое ÑÑнкÑÐ¸Ñ Ð±ÑÐ´ÐµÑ Ð²Ð¾Ð·Ð²ÑаÑаÑÑ Ð¿Ñи некоÑÑекÑнÑÑ
n.
Ðобавим ÑÑо поведение в ÑпеÑиÑикаÑиÑ:
describe("pow", function() {
// ...
it("пÑи возведении в оÑÑиÑаÑелÑнÑÑ ÑÑÐµÐ¿ÐµÐ½Ñ ÑезÑлÑÑÐ°Ñ NaN", function() {
assert(isNaN(pow(2, -1)));
});
it("пÑи возведении в дÑобнÑÑ ÑÑÐµÐ¿ÐµÐ½Ñ ÑезÑлÑÑÐ°Ñ NaN", function() {
assert(isNaN(pow(2, 1.5)));
});
});
РезÑлÑÑÐ°Ñ Ñ Ð½Ð¾Ð²Ñми ÑеÑÑами:
ÐонеÑно, новÑе ÑеÑÑÑ Ð½Ðµ пÑÐ¾Ñ Ð¾Ð´ÑÑ, Ñак как наÑа ÑеализаÑÐ¸Ñ ÐµÑÑ Ð½Ðµ поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð¸Ñ . Так и задÑмано: ÑнаÑала напиÑали заведомо не ÑабоÑаÑÑие ÑеÑÑÑ, а заÑем пиÑем ÑеализаÑÐ¸Ñ Ð¿Ð¾Ð´ Ð½Ð¸Ñ .
ÐÑÑгие assert
ÐбÑаÑим внимание, в ÑпеÑиÑикаÑии вÑÑе иÑполÑзована пÑовеÑка не assert.equal, как ÑанÑÑе, а assert(вÑÑажение). Ð¢Ð°ÐºÐ°Ñ Ð¿ÑовеÑка вÑдаÑÑ Ð¾ÑибкÑ, еÑли знаÑение вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñи пÑиведении к логиÑеÑÐºÐ¾Ð¼Ñ ÑÐ¸Ð¿Ñ Ð½Ðµ true.
Ðна поÑÑебовалаÑÑ, поÑÐ¾Ð¼Ñ ÑÑо ÑÑавниваÑÑ Ñ NaN обÑÑнÑм ÑпоÑобом нелÑзÑ: NaN не Ñавно Ð½Ð¸ÐºÐ°ÐºÐ¾Ð¼Ñ Ð·Ð½Ð°ÑениÑ, даже ÑÐ°Ð¼Ð¾Ð¼Ñ Ñебе, поÑÑÐ¾Ð¼Ñ assert.equal(NaN, x) не подойдÑÑ.
ÐÑÑаÑи, Ð¼Ñ Ð¸ Ñанее могли Ð±Ñ Ð¸ÑполÑзоваÑÑ assert(value1 == value2) вмеÑÑо assert.equal(value1, value2). Ðба ÑÑиÑ
assert пÑовеÑÑÑÑ Ð¾Ð´Ð½Ð¾ и Ñоже.
Ðднако, Ð¼ÐµÐ¶Ð´Ñ ÑÑими вÑзовами еÑÑÑ Ð¾ÑлиÑие в деÑалÑÑ ÑообÑÐµÐ½Ð¸Ñ Ð¾Ð± оÑибке.
ÐÑи «ÑпавÑем» assert в пÑимеÑе вÑÑе Ð¼Ñ Ð²Ð¸Ð´Ð¸Ð¼ "Unspecified AssertionError", Ñо еÑÑÑ Ð¿ÑоÑÑо «ÑÑо-Ñо поÑло не Ñак», а пÑи assert.equal(value1, value2) бÑдÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑе подÑобноÑÑи: expected 8 to equal 81.
ÐоÑÑÐ¾Ð¼Ñ ÑекомендÑеÑÑÑ Ð¸ÑполÑзоваÑÑ Ð¸Ð¼ÐµÐ½Ð½Ð¾ ÑÑ Ð¿ÑовеÑкÑ, коÑоÑÐ°Ñ Ð¼Ð°ÐºÑималÑно ÑооÑвеÑÑÑвÑÐµÑ Ð·Ð°Ð´Ð°Ñе.
ÐÐ¾Ñ ÑамÑе воÑÑÑебованнÑе assert-пÑовеÑки, вÑÑÑоеннÑе в Chai:
assert(value)â пÑовеÑÑÐµÑ ÑÑоvalueÑвлÑеÑÑÑtrueв логиÑеÑком конÑекÑÑе.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- â¦Ð±Ð¾Ð»ÐµÐµ полнÑй ÑпиÑок â в докÑменÑаÑии
РнаÑем ÑлÑÑае Ñ
оÑоÑо Ð±Ñ Ð¸ÑполÑзоваÑÑ Ð¿ÑовеÑÐºÑ assert.isNaN, и Ñакой меÑод ÑÑÑеÑÑвÑеÑ, но ÑейÑÐ°Ñ Ð¼Ñ ÑаÑÑмаÑÑиваем ÑамÑй обÑий меÑод assert(...). Ð ÑÑом ÑлÑÑае Ð´Ð»Ñ Ñого, ÑÑÐ¾Ð±Ñ ÑделаÑÑ ÑообÑение об оÑибке понÑÑнее, желаÑелÑно добавиÑÑ Ðº assert опиÑание.
ÐÑе вÑÐ·Ð¾Ð²Ñ assert позволÑÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑм поÑледним аÑгÑменÑом ÑказаÑÑ ÑÑÑÐ¾ÐºÑ Ñ Ð¾Ð¿Ð¸Ñанием оÑибки, коÑоÑое вÑводиÑÑÑ, еÑли assert не пÑоÑ
одиÑ.
Ðобавим опиÑание оÑибки в ÐºÐ¾Ð½ÐµÑ Ð½Ð°ÑиÑ
assert'ов:
describe("pow", function() {
// ...
it("пÑи возведении в оÑÑиÑаÑелÑнÑÑ ÑÑÐµÐ¿ÐµÐ½Ñ ÑезÑлÑÑÐ°Ñ NaN", function() {
assert(isNaN(pow(2, -1)), "pow(2, -1) не NaN");
});
it("пÑи возведении в дÑобнÑÑ ÑÑÐµÐ¿ÐµÐ½Ñ ÑезÑлÑÑÐ°Ñ NaN", function() {
assert(isNaN(pow(2, 1.5)), "pow(2, 1.5) не NaN");
});
});
ТепеÑÑ ÑезÑлÑÑÐ°Ñ ÑеÑÑа гоÑаздо ÑÑнее говоÑÐ¸Ñ Ð¾ Ñом, ÑÑо не Ñак:
Ркоде ÑеÑÑов вÑÑе можно бÑло Ð±Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸ÑÑ Ð¾Ð¿Ð¸Ñание и к assert.equal, Ñказав в конÑе: assert.equal(value1, value2, "опиÑание"), но Ñ ÑавенÑÑвом обÑÑно и Ñак вÑÑ Ð¿Ð¾Ð½ÑÑно, поÑÑÐ¾Ð¼Ñ Ð¼Ñ Ñак делаÑÑ Ð½Ðµ бÑдем.
ÐÑого
ÐÑак, ÑазÑабоÑка завеÑÑена, Ð¼Ñ Ð¿Ð¾Ð»ÑÑили полноÑеннÑÑ ÑпеÑиÑикаÑÐ¸Ñ Ð¸ код, коÑоÑÑй ÐµÑ ÑеализÑеÑ.
ÐадаÑи вÑÑе позволÑÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑÑ ÐµÑ, и в ÑезÑлÑÑаÑе Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾Ð»ÑÑиÑÑÑÑ ÑÑо-Ñо в Ñаком дÑÑ Ðµ:
describe("pow", function() {
describe("Ð²Ð¾Ð·Ð²Ð¾Ð´Ð¸Ñ x в ÑÑÐµÐ¿ÐµÐ½Ñ n", function() {
function makeTest(x) {
var expected = x * x * x;
it("пÑи возведении " + x + " в ÑÑÐµÐ¿ÐµÐ½Ñ 3 ÑезÑлÑÑаÑ: " + expected, function() {
assert.equal(pow(x, 3), expected);
});
}
for (var x = 1; x <= 5; x++) {
makeTest(x);
}
});
it("пÑи возведении в оÑÑиÑаÑелÑнÑÑ ÑÑÐµÐ¿ÐµÐ½Ñ ÑезÑлÑÑÐ°Ñ NaN", function() {
assert(isNaN(pow(2, -1)), "pow(2, -1) не NaN");
});
it("пÑи возведении в дÑобнÑÑ ÑÑÐµÐ¿ÐµÐ½Ñ ÑезÑлÑÑÐ°Ñ NaN", function() {
assert(isNaN(pow(2, 1.5)), "pow(2, -1.5) не NaN");
});
describe("лÑбое ÑиÑло, кÑоме нÑлÑ, в ÑÑепени 0 Ñавно 1", function() {
function makeTest(x) {
it("пÑи возведении " + x + " в ÑÑÐµÐ¿ÐµÐ½Ñ 0 ÑезÑлÑÑаÑ: 1", function() {
assert.equal(pow(x, 0), 1);
});
}
for (var x = -5; x <= 5; x += 2) {
makeTest(x);
}
});
it("Ð½Ð¾Ð»Ñ Ð² нÑлевой ÑÑепени даÑÑ NaN", function() {
assert(isNaN(pow(0, 0)), "0 в ÑÑепени 0 не NaN");
});
});
ÐÑÑ ÑпеÑиÑикаÑÐ¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ иÑполÑзоваÑÑ ÐºÐ°Ðº:
- ТеÑÑÑ, коÑоÑÑе гаÑанÑиÑÑÑÑ Ð¿ÑавилÑноÑÑÑ ÑабоÑÑ ÐºÐ¾Ð´Ð°.
- ÐокÑменÑаÑÐ¸Ñ Ð¿Ð¾ ÑÑнкÑии, ÑÑо она конкÑеÑно делаеÑ.
- ÐÑимеÑÑ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑÑнкÑии, коÑоÑÑе демонÑÑÑиÑÑÑÑ ÐµÑ ÑабоÑÑ Ð²Ð½ÑÑÑи
it.
ÐÐ¼ÐµÑ ÑпеÑиÑикаÑиÑ, Ð¼Ñ Ð¼Ð¾Ð¶ÐµÐ¼ ÑлÑÑÑаÑÑ, менÑÑÑ, пеÑепиÑÑваÑÑ ÑÑнкÑÐ¸Ñ Ð¸ легко конÑÑолиÑоваÑÑ ÐµÑ ÑабоÑÑ, пÑоÑмаÑÑÐ¸Ð²Ð°Ñ ÑеÑÑÑ.
ÐÑобенно важно ÑÑо в болÑÑÐ¸Ñ Ð¿ÑоекÑÐ°Ñ .
ÐÑÐ²Ð°ÐµÑ Ñак, ÑÑо изменение в одной ÑаÑÑи кода Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾Ð²Ð»ÐµÑÑ Ð·Ð° Ñобой «падение» дÑÑгой ÑаÑÑи, коÑоÑÐ°Ñ ÐµÑ Ð¸ÑполÑзÑеÑ. Так как вÑÑ-вÑÑ Ð² болÑÑом пÑоекÑе ÑÑками не пеÑепÑовеÑиÑÑ, Ñо Ñакие оÑибки имеÑÑ Ð±Ð¾Ð»ÑÑой ÑÐ°Ð½Ñ Ð¾ÑÑаÑÑÑÑ Ð² пÑодÑкÑе и вÑлезÑи позже, когда пÑÐ¾ÐµÐºÑ ÑÐ²Ð¸Ð´Ð¸Ñ Ð¿Ð¾ÑеÑиÑÐµÐ»Ñ Ð¸Ð»Ð¸ заказÑик.
ЧÑÐ¾Ð±Ñ Ð¸Ð·Ð±ÐµÐ¶Ð°ÑÑ ÑÐ°ÐºÐ¸Ñ Ð¿Ñоблем, бÑваеÑ, ÑÑо вообÑе ÑÑаÑаÑÑÑÑ Ð½Ðµ ÑÑогаÑÑ ÐºÐ¾Ð´, Ð¾Ñ ÐºÐ¾ÑоÑого много ÑÑо завиÑиÑ, даже еÑли его Ð½Ñ Ð¾ÑÐµÐ½Ñ Ð½Ñжно пеÑепиÑаÑÑ. ÐÐ¸Ð·Ð½Ñ Ð¿ÑобиваеÑÑÑ Ñонкими ÑоÑÑоÑками Ñам, где должна ÑвеÑÑи и Ð¿Ð°Ñ Ð½ÑÑÑ Ð½Ð¾Ð²Ð°Ñ ÑÑнкÑионалÑноÑÑÑ.
Ðод, покÑÑÑÑй авÑоÑеÑÑами, ÑвлÑÐµÑ Ñобой полнÑÑ Ð¿ÑоÑивоположноÑÑÑ ÑÑомÑ!
Ðаже еÑли какое-Ñо изменение поÑенÑиалÑно Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾ÑÑÑиÑÑ Ð²ÑÑ â его ÑовеÑÑенно не ÑÑÑаÑно ÑделаÑÑ. ÐÐµÐ´Ñ ÐµÑÑÑ Ð¼Ð°ÑÑа ÑеÑÑов, коÑоÑÑе бÑÑÑÑо и в авÑомаÑиÑеÑком Ñежиме пÑовеÑÑÑ ÑабоÑÑ ÐºÐ¾Ð´Ð°. РеÑли ÑÑо-Ñо падаеÑ, Ñо ÑÑо можно бÑÐ´ÐµÑ Ð»ÐµÐ³ÐºÐ¾ локализоваÑÑ Ð¸ попÑавиÑÑ.
ÐÑоме Ñого, код, покÑÑÑÑй ÑеÑÑами, Ð¸Ð¼ÐµÐµÑ Ð»ÑÑÑÑÑ Ð°ÑÑ Ð¸ÑекÑÑÑÑ.
ÐонеÑно, ÑÑо еÑÑеÑÑвенное ÑледÑÑвие Ñого, ÑÑо его легÑе менÑÑÑ Ð¸ ÑлÑÑÑаÑÑ. Ðо не ÑолÑко.
ЧÑÐ¾Ð±Ñ Ð½Ð°Ð¿Ð¸ÑаÑÑ ÑеÑÑÑ, нÑжно ÑазбиÑÑ ÐºÐ¾Ð´ на ÑÑнкÑии Ñак, ÑÑÐ¾Ð±Ñ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ ÑÑнкÑии бÑло ÑÑÑко понÑÑно, ÑÑо она полÑÑÐ°ÐµÑ Ð½Ð° Ð²Ñ Ð¾Ð´, ÑÑо Ð´ÐµÐ»Ð°ÐµÑ Ñ ÑÑим и ÑÑо возвÑаÑаеÑ. ÐÑо ознаÑÐ°ÐµÑ ÑÑнÑÑ Ð¸ понÑÑнÑÑ ÑÑÑÑкÑÑÑÑ Ñ Ñамого наÑала.
ÐонеÑно, в ÑеалÑной жизни вÑÑ Ð½Ðµ Ñак пÑоÑÑо. ÐаÑаÑÑÑÑ Ð½Ð°Ð¿Ð¸ÑаÑÑ ÑеÑÑ Ñложно. Ðли Ñложно поддеÑживаÑÑ ÑеÑÑÑ, поÑколÑÐºÑ ÐºÐ¾Ð´ акÑивно менÑеÑÑÑ. Сами ÑеÑÑÑ Ñоже пиÑÑÑÑÑ Ð¿Ð¾-ÑазномÑ, пÑи помоÑи ÑазнÑÑ Ð¸Ð½ÑÑÑÑменÑов.
ЧÑо далÑÑе?
РдалÑнейÑем ÑÑÐ»Ð¾Ð²Ð¸Ñ ÑÑда Ð·Ð°Ð´Ð°Ñ Ð±ÑдÑÑ Ñже ÑодеÑжаÑÑ Ð² Ñебе ÑеÑÑÑ. Ðа Ð½Ð¸Ñ Ð²Ñ Ð¿Ð¾Ð·Ð½Ð°ÐºÐ¾Ð¼Ð¸ÑеÑÑ Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑми пÑимеÑами.
Ðак пÑавило, они бÑдÑÑ Ð²Ð¿Ð¾Ð»Ð½Ðµ понÑÑнÑ, даже еÑли немного вÑÑ Ð¾Ð´ÑÑ Ð·Ð° пÑÐµÐ´ÐµÐ»Ñ ÑÑой главÑ.
ÐомменÑаÑии
<code>, Ð´Ð»Ñ Ð½ÐµÑколÑÐºÐ¸Ñ ÑÑÑок кода — Ñег<pre>, еÑли болÑÑе 10 ÑÑÑок — ÑÑÑÐ»ÐºÑ Ð½Ð° пеÑоÑниÑÑ (plnkr, JSBin, codepenâ¦)