Skip to content

Commit

Permalink
Fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Roman Ponomarev committed Nov 8, 2017
1 parent 2472028 commit 322fe1e
Showing 1 changed file with 25 additions and 24 deletions.
49 changes: 25 additions & 24 deletions node-hero/chapter9/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
# Модульное тестирование
*Перевод книги [Node Hero](https://risingstack.com/resources/node-hero) от [RisingStack](https://risingstack.com/). Переведено с разрешения правообладателей.*

В этой главе вы узнаете, что такое модульное тестирование (*или юнит-тестирование*) в Node.js, и как правильно тестировать ваши приложения.
В этой главе вы узнаете, что такое модульное тестирование (*юнит-тестирование*) в Node.js и как правильно тестировать ваши приложения.

## Тестирование Node.js-приложений

Вы можете думать о тестах как о гарантиях надёжности для приложений, которые вы пишите. Они будут запускаться не только на вашей локальной машине, но также и на CI-сервисах, чтобы сбойные сборки не попадали в продакшен.
Вы можете рассматривать тесты как гарантии надёжности ваших приложений. Они будут запускаться не только на вашей локальной машине, но и на CI-сервисах, чтобы сломанные сборки не попадали в продакшен.

>*«Тесты - это больше, чем просто гарантии, они обеспечивают живую документацию для вашей кодовой базы».*
Вы можете спросить: *что я должен протестировать в своём приложении? Сколько тестов у меня должно быть?*

Ответ варьируется в разных случаях, но, как правило, вы можете следовать рекомендациям, установленным **пирамидой тестирования**.
Ответ варьируется, но, как правило, вы можете следовать рекомендациям, установленным **пирамидой тестирования**.

![](NodeHeroEbook-TheComplete-012.png)

Expand All @@ -20,32 +21,32 @@

*Обратите внимание, что здесь мы не собираемся говорить об интеграционных и e2e тестах, поскольку они выходят далеко за рамки этого учебника.*

## Модульное тестирование Node.js приложений
## Модульное тестирование Node.js-приложений

Мы пишем модульные тесты для того, чтобы увидеть, работает ли данный модуль (юнит). Все зависимости обрезаны, что означает, что мы предоставляем поддельные зависимости (фейки) для модуля.
Мы пишем модульные тесты для того, чтобы проверить, работает ли данный модуль (*юнит*). Все зависимости исключаются, что означает, что мы предоставляем поддельные зависимости (*фейки*) для модуля.

**Вы должны написать тесты для публичных методов, а не для внутренней реализации данного модуля.**
**Вы должны писать тесты для публичных методов, а не для внутренней реализации данного модуля.**

### Анатомия модульного теста

Каждый модульный тест имеет следующую структуру:
Каждый модульный тест имеет следующую структуру:

1. Настройка теста
2. Вызов тестируемого метода
3. Утверждение

**В каждом модульном тесте должны проверяться только одна проблема.** *(Конечно, это не означает, что вы можете добавить только одно утверждение).*
**В каждом модульном тесте должна проверяться только одна проблема.** *(Конечно, это не означает, что вы можете добавить только одно утверждение).*

### Библиотеки, используемые для тестирования в Node.js

Для модульного тестирования мы собираемся использовать следующие библиотеки:
**запуск тестов**: [mocha](https://www.npmjs.com/package/mocha), альтернативно [tape](https://www.npmjs.com/package/tape)
**библиотека утверждений**: [chai](http://chaijs.com/), альтернативно [assert](https://www.npmjs.com/package/assert)
**библиотека утверждений**: [chai](http://chaijs.com/), альтернативно [assert](https://www.npmjs.com/package/assert)
**шпионы, стабы и моки**: [sinon](http://sinonjs.org/) *(для настройки тестов)*.

### Шпионы, стабы и моки - что использовать и когда?

Прежде чем приступить к практике модульного тестирования, давайте разберёмся, что такое шпионы, заглушки и моки!
Прежде чем приступить к практике модульного тестирования, давайте разберёмся, что такое шпионы, стабы (*заглушки*) и моки!

### Шпионы

Expand All @@ -55,7 +56,7 @@
it('calls subscribers on publish', function () {
var callback = sinon.spy()
PubSub.subscribe('message', callback)

PubSub.publishSync('message')
assertTrue(callback.called)
})
Expand All @@ -64,7 +65,7 @@ it('calls subscribers on publish', function () {

### Стабы

Стабы *(или заглушки)* похожи на шпионов, но они заменяют целевую функцию. Вы можете использовать заглушки для управления поведением метода, чтобы форсировать какие-то события в коде (например, выброс ошибки) или предотвратить вызовы внешних ресурсов (таких как HTTP API).
Стабы похожи на шпионов, но они заменяют целевую функцию. Вы можете использовать стабы для управления поведением метода, чтобы форсировать какие-то события в коде (например, выброс ошибки) или предотвратить вызовы внешних ресурсов (таких как HTTP API).

```javascript
it('calls all subscribers, even if there are exceptions', function (){
Expand All @@ -73,13 +74,13 @@ it('calls all subscribers, even if there are exceptions', function (){
var stub = sinon.stub().throws()
var spy1 = sinon.spy()
var spy2 = sinon.spy()

PubSub.subscribe(message, stub)
PubSub.subscribe(message, spy1)
PubSub.subscribe(message, spy2)

PubSub.publishSync(message, undefined)

assert(spy1.called)
assert(spy2.called)
assert(stub.calledBefore(spy1))
Expand Down Expand Up @@ -130,7 +131,7 @@ function getWebpage (url) {
if (err) {
return reject(err)
}

resolve(body)
})
})
Expand All @@ -155,7 +156,7 @@ module.exports = {

Этот модуль делает одну вещь: он сохраняет веб-страницу (основываясь на переданном URL) в файл на локальном компьютере. Чтобы протестировать этот модуль, мы должны «застабить» как модуль `fs`, так и модуль `request`.

Прежде чем начинать писать модульные тесты, в RisingStack обычно мы добавляем файл `test-setup.spec.js` для создания базовой настройки тестов, например создания песочниц Sinon. Это избавит вас от написания `sinon.sandbox.create()` и `sinon.sandbox.restore()` после каждого теста.
Прежде чем начинать писать модульные тесты, в RisingStack мы обычно добавляем файл `test-setup.spec.js` для создания базовой настройки тестов, например создания песочниц Sinon. Это избавит вас от написания `sinon.sandbox.create()` и `sinon.sandbox.restore()` после каждого теста.

```javascript
// test-setup.spec.js
Expand Down Expand Up @@ -196,21 +197,21 @@ describe('The webpage module', function () {
const writeFileStub = this.sandbox.stub(fs, 'writeFile', function ( filePath, fileContent, cb) {
cb(null)
})

const requestStub = this.sandbox.stub(request, 'get', function (url, cb) {
cb(null, null, content)
})

const result = yield webpage.saveWebpage(url)

expect(writeFileStub).to.be.calledWith()
expect(requestStub).to.be.calledWith(url)
expect(result).to.eql('page')
})
})
```

Полные исходники примера вы можете найти здесь: [](https://github.com/RisingStack/nodehero-testing)
Полные исходники примера вы можете найти [здесь](https://github.com/RisingStack/nodehero-testing).

## Покрытие кода

Expand All @@ -229,15 +230,15 @@ describe('The webpage module', function () {
istanbul cover _mocha $(find ./lib -name \"*.spec.js\" -not -path \"./node_modules/*\")
```

Как только вы это сделаете, вы получите что-то вроде этого:
Как только вы это сделаете, вы получите что-то вроде:

![](NodeHeroEbook-TheComplete-013.png)

Вы можете кликнуть мышью, и на самом деле увидеть, что ваш исходный код аннотирован: какая часть протестирована, а какая — нет.
Вы можете кликнуть мышью и на самом деле увидеть, что ваш исходный код аннотирован: какая часть протестирована, а какая — нет.

---

Тестирование может уберечь вас от множества неприятностей — тем не менее, неизбежно наступает время отладки. В следующей главе Node Hero вы узнаете, **как отлаживать Node.js-приложения**.
Тестирование может уберечь вас от множества неприятностей. Тем не менее, неизбежно наступает время отладки. В следующей главе Node Hero вы узнаете, **как отлаживать Node.js-приложения**.

---

Expand Down

0 comments on commit 322fe1e

Please sign in to comment.