diff --git a/1-js/02-first-steps/14-function-basics/article.md b/1-js/02-first-steps/14-function-basics/article.md index c1c6bd3b..fadffb17 100644 --- a/1-js/02-first-steps/14-function-basics/article.md +++ b/1-js/02-first-steps/14-function-basics/article.md @@ -457,6 +457,6 @@ Function naming: - A name should clearly describe what the function does. When we see a function call in the code, a good name instantly gives us an understanding what it does and returns. - A function is an action, so function names are usually verbal. -- There is a bunch of commonly adapted verbal prefixes like `create…`, `show…`, `get…`, `check…` etc which can help. The main point is to be consistent about their meaning. +- There exist many widespread function prefixes like `create…`, `show…`, `get…`, `check…` and so on. Use them to hint what a function does. Functions are the main building blocks of scripts. Now we covered the basics, so we actually can start creating and using them. But that's only the beginning of the path. We are going to return to them many times, going more deeply in their advanced features. diff --git a/1-js/03-code-quality/05-testing/article.md b/1-js/03-code-quality/05-testing/article.md index 5e3517cd..c875cf6c 100644 --- a/1-js/03-code-quality/05-testing/article.md +++ b/1-js/03-code-quality/05-testing/article.md @@ -1,147 +1,146 @@ -# TODO: Автоматические тесты при помощи chai и mocha +# Automated testing with mocha -В этой главе мы разберём основы автоматического тестирования. Оно будет применяться далее в задачах, и вообще, входит в "образовательный минимум" программиста. +Automated testing will be used further on in tasks. It's actually a part of the "educational minimum" of a developer. [cut] -## Зачем нужны тесты? +## Why we need tests? -При написании функции мы обычно представляем, что она должна делать, какое значение -- на каких аргументах выдавать. +When we write a function, we usually can imagine what it should do, which parameters yield which results. -В процессе разработки мы, время от времени, проверяем, правильно ли работает функция. Самый простой способ проверить -- это запустить её, например, в консоли, и посмотреть результат. +During the development, we can check the function by running it and comparing the outcome with the expected one. For instance, we can do it in the console. -Если что-то не так -- поправить, опять запустить -- посмотреть результат... И так -- "до победного конца". +If something's wrong -- then fix the code, run again, check the result -- and so on till it works. -Но такие ручные запуски -- очень несовершенное средство проверки. +But such manual "re-runs" are rather imperfect. -**Когда проверяешь работу кода вручную -- легко его "недотестировать".** +**When testing a code manually -- it's easy to miss something.** -Например, пишем функцию `f`. Написали, тестируем с разными аргументами. Вызов функции `f(a)` -- работает, а вот `f(b)` -- не работает. Поправили код -- стало работать `f(b)`, вроде закончили. Но при этом забыли заново протестировать `f(a)` -- упс, вот и возможная ошибка в коде. +For instance, we're composing a function `f`. Wrote some code, testing: `f(1)` works, but `f(2)` doesn't work. We fix the code and now `f(2)` works. Looks complete? But we forgot to re-test `f(1)`. That may lead to an error. -**Автоматизированное тестирование -- это когда тесты написаны отдельно от кода, и можно в любой момент запустить их и проверить все важные случаи использования.** +That's actually fair. When we develop something, we keep a lot of possible use cases and mind. But it's hard to expect from programmer to check all of them manually after every change. So it becomes easy to fix one thing and break another one. -## BDD -- поведенческие тесты кода +**Automated testing means that tests are written separately, in addition to the code. They can be executed easily and check all the main use cases.** -Мы рассмотрим методику тестирования, которая входит в [BDD](http://en.wikipedia.org/wiki/Behavior-driven_development) -- Behavior Driven Development. Подход BDD давно и с успехом используется во многих проектах. +## Behavior Driven Development (BDD) -BDD -- это не просто тесты. Это гораздо больше. +Let's get down to a technique named [Behavior Driven Development](http://en.wikipedia.org/wiki/Behavior-driven_development) or, in short, BDD. That approach is used among many projects. -**Тесты BDD -- это три в одном: И тесты И документация И примеры использования одновременно.** +BDD is not just about testing. That's more. -Впрочем, хватит слов. Рассмотрим примеры. +**BDD is three things in one: tests AND documentation AND examples.** -## Разработка pow: спецификация +Enough words. Let's see the example. -Допустим, мы хотим разработать функцию `pow(x, n)`, которая возводит `x` в целую степень `n`, для простоты `n≥0`. +## Development of "pow": the spec -Ещё до разработки мы можем представить себе, что эта функция будет делать и описать это по методике BDD. +Let's say we want to make a function `pow(x, n)` that raises `x` to an integer power `n`. We assume that `n≥0`. -Это описание называется *спецификация* (или, как говорят в обиходе, "спека") и выглядит так: +That task is quite simple, there's even a `**` operator in Javascript that can do that, but here we concentrate not on the function itself, but on the development flow, that can be applied to more complex tasks as well. + +Before creating the code of `pow`, we can imagine what the function should do and describe it using BDD. + +Such description is called a *specification* or, in short, a spec, and looks like this: ```js describe("pow", function() { - it("возводит в n-ю степень", function() { + it("raises to n-th power", function() { assert.equal(pow(2, 3), 8); }); }); ``` -У спецификации есть три основных строительных блока, которые вы видите в примере выше: +A spec has three main building blocks that you can see above: -`describe(название, function() { ... })` -: Задаёт, что именно мы описываем, используется для группировки "рабочих лошадок" -- блоков `it`. В данном случае мы описываем функцию `pow`. +`describe("title", function() { ... })` +: What functionality we're describing. Uses to group "working horses" -- the `it` blocks. In our case we're describing the function `pow`. -`it(название, function() { ... })` -: В названии блока `it` *человеческим языком* описывается, что должна делать функция, далее следует *тест*, который проверяет это. +`it("title", function() { ... })` +: In the title of `it` we *in a human-readable way* describe the particular use case, and then goes a function that tests it. `assert.equal(value1, value2)` -: Код внутри `it`, если реализация верна, должен выполняться без ошибок. +: The code inside `it` block, if the implementation is correct, should execute without errors. - Различные функции вида `assert.*` используются, чтобы проверить, делает ли `pow` то, что задумано. Пока что нас интересует только одна из них -- `assert.equal`, она сравнивает свой первый аргумент со вторым и выдаёт ошибку в случае, когда они не равны. В данном случае она проверяет, что результат `pow(2, 3)` равен `8`. + Functions `assert.*` are used to check whether `pow` works as expected. Right here we're using one of them -- `assert.equal`, it compares arguments and yields an error if they are not equal. Here it checks that the result of `pow(2, 3)` equals `8`. - Есть и другие виды сравнений и проверок, которые мы увидим далее. + There are other types of comparisons and checks that we'll see further. -## Поток разработки +## The development flow -Как правило, поток разработки таков: +The flow of development usually looks like this: -1. Пишется спецификация, которая описывает самый базовый функционал. -2. Делается начальная реализация. -3. Для проверки соответствия спецификации мы задействуем одновременно фреймворк, в нашем случае [Mocha](http://mochajs.org/) вместе со спецификацией и реализацией. Фреймворк запускает все тесты `it` и выводит ошибки, если они возникнут. При ошибках вносятся исправления. -4. Спецификация расширяется, в неё добавляются возможности, которые пока, возможно, не поддерживаются реализацией. -5. Идём на пункт 3, делаем реализацию, и так далее, до победного конца. +1. An initial spec is written, with tests for the most basic functionality. +2. An initial implementation is created. +3. To check whether it works, we run the testing framework [Mocha](http://mochajs.org/) together with assertion framework (we'll pick [Chai](http://chaijs.com/)), the spec and the implementation. Functions `describe` and `it` actually belong to Mocha and `assert.*` come from Chai. If there are errors, we make corrections till everything works. +4. Now we have a working initial implementation with tests. +5. We add more use cases to the spec, probably not yet supported by the implementations. Tests start to fail. +6. Go to 3, alter the implementation till everything works, and repeat the same till the functionality is ready. -Разработка ведётся *итеративно*, один проход за другим, пока спецификация и реализация не будут завершены. +So, the development is *iterative*. We write the spec, implement it, then write more tests, make sure they work etc. At the end we have both a working implementation and tests for it. -В нашем случае первый шаг уже завершён, начальная спецификация готова, хорошо бы приступить к реализации. Но перед этим проведём "нулевой" запуск спецификации, просто чтобы увидеть, что уже в таком виде, даже без реализации -- тесты работают. +In our case, the first step is complete: we have an initial spec. So let's make an implementation. But before that let's make a "zero" run of the spec, just to see that tests are working (they will all fail). -## Пример в действии +## The spec in action -Для запуска тестов нужны соответствующие JavaScript-библиотеки. +Here in the tutorial we'll be using the following JavaScript libraries for tests: -Мы будем использовать: +- [Mocha](http://mochajs.org/) -- the main framework with common testing functions including `describe` and `it`. +- [Chai](http://chaijs.com) -- the library with many assertions. It allows to use a lot of different assertions, for now we need only `assert.equal`. +- [Sinon](http://sinonjs.org/) -- to emulate built-in functions, to spy over functions and more, we'll need it much later. -- [Mocha](http://mochajs.org/) -- эта библиотека содержит общие функции для тестирования, включая `describe` и `it`. -- [Chai](http://chaijs.com) -- библиотека поддерживает разнообразные функции для проверок. Есть разные "стили" проверки результатов, с которыми мы познакомимся позже, на текущий момент мы будем использовать лишь `assert.equal`. -- [Sinon](http://sinonjs.org/) -- для эмуляции и хитрой подмены функций "заглушками", понадобится позднее. +These libraries are suitable for both in-browser and server-side testing. Here we'll consider the browser variant. -Эти библиотеки позволяют тестировать JS не только в браузере, но и на сервере Node.JS. Здесь мы рассмотрим браузерный вариант, серверный использует те же функции. +```html src="index.html" +``` -Пример HTML-страницы для тестов: +The page can be divided into four parts: -[html src="index.html"] +1. The `
` -- add third-party libraries and styles for tests. +2. The ` + + + + - + + - + - + - + -