Модульное тестирование JavaScript с помощью Mocha и Chai

  1. Что такое юнит-тестирование
  2. Тестирование на Node.js против тестирования в браузере
  3. Настройка структуры каталогов
  4. Настройка Test Runner
  5. Основные тестовые блоки
  6. Написание тестового кода
  7. Выполнение теста
  8. Результаты теста
  9. Положить его вместе
  10. Запуск тестов в браузере
  11. Выполнение тестов на узле
  12. Что дальше?

Эта статья была рецензирована Панайотис «пвгр» Велисаракос , Марк Браун а также Том Греко , Спасибо всем рецензентам SitePoint за то, что сделали контент SitePoint как можно лучше!

Вы когда-нибудь вносили какие-то изменения в свой код, а потом обнаружили, что он вызвал что-то еще?

Я уверен, что большинство из нас есть. Это почти неизбежно, особенно когда у вас больше кода. Одна вещь зависит от другой, и тогда ее изменение нарушает что-то другое.

Но что, если этого не произошло? Что если бы у вас был способ узнать, когда что-то сломалось в результате какого-то изменения? Это было бы здорово. Вы можете изменить свой код, не беспокоясь о том, что что-то может сломаться, у вас будет меньше ошибок и вы будете тратить меньше времени на отладку.

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

В этой статье я покажу вам, как начать модульное тестирование кода JavaScript. Примеры и методы, показанные в этой статье, могут применяться как к браузерному коду, так и к коду Node.js.

Код для этого урока доступен с нашего GitHub репо ,

Что такое юнит-тестирование

Когда вы тестируете свою кодовую базу, вы берете кусок кода - обычно функцию - и проверяете, что он работает правильно в конкретной ситуации. Модульное тестирование - это структурированный и автоматизированный способ сделать это. В результате, чем больше тестов вы пишете, тем больше вы получаете выгоды. Вы также будете более уверенно доверять своей кодовой базе, продолжая ее развивать.

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

// Заданы 1 и 10 в качестве входных данных ... var result = Math.max (1, 10); // ... мы должны получить 10 в качестве результата if (result! == 10) {throw new Error ('Failed'); }

На практике тесты иногда могут быть более сложными. Например, если ваша функция отправляет запрос Ajax, тесту необходимо настроить больше, но все же применяется тот же принцип «при определенных входных данных, мы ожидаем определенного результата».

Для этой статьи мы будем использовать Мокко. С ним легко начать работу, его можно использовать как для тестирования на основе браузера, так и для тестирования Node.js, и он прекрасно сочетается с другими инструментами тестирования.

Самый простой способ установить Mocha - через npm (для которого нам также нужно установить Node.js ). Если вы не знаете, как установить npm или Node в своей системе, обратитесь к нашему руководству: Руководство для начинающих по npm - менеджер пакетов Node

С установленным Node откройте терминал или командную строку в каталоге вашего проекта.

  • Если вы хотите проверить код в браузере, запустите npm install mocha chai --save-dev
  • Если вы хотите протестировать код Node.js, в дополнение к вышеупомянутому запустите npm install -g mocha

Это устанавливает пакеты мокко и чай. кофе мокко это библиотека, которая позволяет нам запускать тесты, и Chai содержит некоторые полезные функции, которые мы будем использовать для проверки результатов нашего теста.

Тестирование на Node.js против тестирования в браузере

Следующие примеры предназначены для работы при запуске тестов в браузере. Если вы хотите выполнить модульное тестирование приложения Node.js, выполните следующие действия.

  • Для Node вам не нужен файл запуска теста.
  • Чтобы включить Chai, добавьте var chai = require ('chai'); в верхней части тестового файла.
  • Запустите тесты с помощью команды mocha вместо открытия браузера.

Настройка структуры каталогов

Вы должны поместить свои тесты в отдельный каталог из файлов основного кода. Это облегчает их структурирование, например, если вы хотите добавить другие типы тестов в будущем (например, интеграционные тесты или же функциональные тесты ).

Самая популярная практика с JavaScript-кодом - иметь каталог с именем test / в корневом каталоге вашего проекта. Затем каждый тестовый файл помещается в test / someModuleTest.js. При желании вы также можете использовать каталоги внутри test /, но я рекомендую сделать вещи простыми - вы всегда можете изменить их позже, если это необходимо.

Настройка Test Runner

Чтобы запустить наши тесты в браузере, нам нужно настроить простую HTML-страницу, которая будет нашей страницей. Страница загружает Mocha, тестовые библиотеки и наши актуальные тестовые файлы. Чтобы запустить тесты, мы просто откроем бегуна в браузере.

Если вы используете Node.js, вы можете пропустить этот шаг. Модульные тесты Node.js можно запустить с помощью команды mocha, если вы следовали рекомендуемой структуре каталогов.

Ниже приведен код, который мы будем использовать для тестового бегуна. Я сохраню этот файл как testrunner.html.

<! DOCTYPE html> <html> <head> <title> Тесты Mocha </ title> <link rel = "stylesheet" href = "node_modules / mocha / mocha.css"> </ head> <body> <div id = "mocha"> </ div> <script src = "node_modules / mocha / mocha.js"> </ script> <script src = "node_modules / chai / chai.js"> </ script> <script> mocha.setup ('bdd') </ script> <! - загрузить код, который вы хотите протестировать здесь -> <! - загрузить ваши тестовые файлы здесь -> <script> mocha.run (); </ script> </ body> </ html>

Важные биты в тесте бегуна:

  • Мы загружаем стили Mocha CSS, чтобы дать нашим результатам тестов хорошее форматирование.
  • Мы создаем div с идентификатором мокко. Здесь вставляются результаты теста.
  • Мы загружаем мокко и чай. Они находятся в подпапках папки node_modules, так как мы установили их через npm.
  • Вызывая mocha.setup, мы предоставляем помощников по тестированию Mocha.
  • Затем мы загружаем код, который мы хотим проверить, и тестовые файлы. У нас здесь пока ничего нет.
  • Наконец, мы вызываем mocha.run для запуска тестов. Убедитесь, что вы вызываете это после загрузки исходного и тестового файлов.

Основные тестовые блоки

Теперь, когда мы можем запускать тесты, давайте начнем писать.

Начнем с создания нового файла test / arrayTest.js. Отдельный файл теста, такой как этот, известен как тестовый пример . Я называю это arrayTest.js, потому что для этого примера мы будем тестировать некоторые базовые функциональные возможности массива.

Каждый файл теста соответствует одному и тому же базовому шаблону. Во-первых, у вас есть блок описания:

description ('Array', function () {// Дополнительный код для тестов приведен здесь});

Описание используется для группировки отдельных тестов. Первый параметр должен указывать то, что мы тестируем - в этом случае, так как мы собираемся протестировать функции массива, я передал строку «Массив».

Во-вторых, внутри описания у нас будут блоки:

description ('Array', function () {it ('должен начинаться с нуля', function () {// Тестовая реализация идет здесь}); // Здесь мы можем получить больше}};

он используется для создания реальных тестов. Первый параметр к нему должен предоставить удобочитаемое описание теста. Например, мы можем прочитать вышеизложенное как «оно должно начинаться с пустого», что является хорошим описанием того, как должны вести себя массивы. Код для реализации теста затем пишется внутри переданной ему функции.

Все тесты Mocha построены из этих же строительных блоков, и они следуют той же базовой схеме.

  • Во-первых, мы используем описание, чтобы сказать, что мы тестируем - например, «опишите, как должен работать массив».
  • Затем мы используем ряд его функций для создания отдельных тестов - каждый из них должен объяснять одно конкретное поведение, такое как «оно должно начинаться с пустого» для нашего случая массива выше.

Написание тестового кода

Теперь, когда мы знаем, как структурировать тестовый пример, давайте перейдем к забавной части - реализации теста.

Поскольку мы проверяем, что массив должен начинаться с пустого места, нам нужно создать массив, а затем убедиться, что он пуст. Реализация этого теста довольно проста:

var assert = chai.assert; description ('Array', function () {it ('должно начинаться с пустого', function () {var arr = []; assert.equal (arr.length, 0);});});

Обратите внимание, что в первой строке мы устанавливаем переменную assert. Это просто так, что нам не нужно постоянно вводить chai.assert везде.

В функции it мы создаем массив и проверяем его длину. Несмотря на простоту, это хороший пример того, как работают тесты.

Во-первых, у вас есть что-то, что вы тестируете - это называется тестируемой системой или SUT . Затем, если необходимо, вы делаете что-то с SUT. В этом тесте мы ничего не делаем, так как проверяем, что массив начинается как пустой.

Последним в тесте должна быть проверка - утверждение, проверяющее результат. Здесь мы используем assert.equal для этого. Большинство функций утверждений принимают параметры в том же порядке: сначала «фактическое» значение, а затем «ожидаемое» значение.

  • Фактическое значение является результатом вашего тестового кода, поэтому в этом случае arr.length
  • Ожидаемое значение - это то, каким должен быть результат. Поскольку массив должен начинаться с пустого значения, ожидаемое значение в этом тесте равно 0

Чай также предлагает два разных стиля написания утверждений, но мы используем утверждать чтобы все было просто пока. Когда вы станете более опытным в написании тестов, вы можете использовать ожидать утверждений вместо этого, поскольку они обеспечивают некоторую большую гибкость.

Выполнение теста

Чтобы запустить этот тест, нам нужно добавить его в файл, созданный ранее.

Если вы используете Node.js, вы можете пропустить этот шаг и использовать команду mocha для запуска теста. Вы увидите результаты теста в терминале.

В противном случае, чтобы добавить этот тест для бегуна, просто добавьте:

<script src = "test / arrayTest.js"> </ script>

Ниже:

<! - загрузите свои тестовые файлы здесь ->

После того, как вы добавили скрипт, вы можете загрузить страницу бегуна теста в выбранном вами браузере.

Результаты теста

Когда вы запустите свои тесты, результаты теста будут выглядеть примерно так:

Обратите внимание, что то, что мы ввели в описание, и его функции отображаются в выходных данных - тесты сгруппированы под описанием. Обратите внимание, что также возможно вложить блоки описания для создания дополнительных подгрупп.

Давайте посмотрим, как выглядит провальный тест.

На строке в тесте, которая говорит:

assert.equal (arr.length, 0);

Замените число 0 на 1. Это делает тест неудачным, так как длина массива больше не соответствует ожидаемому значению.

Если вы снова запустите тесты, вы увидите красный тест с ошибкой и описанием того, что пошло не так.

Если вы снова запустите тесты, вы увидите красный тест с ошибкой и описанием того, что пошло не так

Одним из преимуществ тестов является то, что они помогают быстрее находить ошибки, однако эта ошибка не очень полезна в этом отношении. Мы можем это исправить, хотя.

Большинство функций подтверждения также могут принимать необязательный параметр сообщения. Это сообщение отображается при сбое подтверждения. Рекомендуется использовать этот параметр, чтобы облегчить понимание сообщения об ошибке.

Мы можем добавить сообщение к нашему утверждению следующим образом:

assert.equal (arr.length, 1, 'Длина массива не была 0');

Если вы повторно запустите тесты, вместо сообщения по умолчанию появится пользовательское сообщение.

Давайте переключим утверждение обратно на прежнее состояние - заменим 1 на 0 и снова запустим тесты, чтобы убедиться, что они пройдены.

Положить его вместе

До сих пор мы рассматривали довольно простые примеры. Давайте применим на практике то, что мы узнали, и посмотрим, как мы будем тестировать более реалистичный фрагмент кода.

Вот функция, которая добавляет класс CSS к элементу. Это должно войти в новый файл js / className.js.

function addClass (el, newClass) {if (el.className.indexOf (newClass) === -1) {el.className + = newClass; }}

Чтобы сделать его немного интереснее, я сделал так, чтобы он добавлял новый класс только тогда, когда этот класс не существует в свойстве className элемента - кто хочет увидеть <div class = "hello hello hello hello"> в конце концов?

В лучшем случае мы написали бы тесты для этой функции, прежде чем писать код. Но разработка через тестирование это сложная тема, и сейчас мы просто хотим сосредоточиться на написании тестов.

Чтобы начать, давайте вспомним основную идею модульных тестов: мы даем функции определенные входные данные, а затем проверяем, что функция ведет себя как ожидалось. Итак, каковы входы и поведение для этой функции?

Учитывая элемент и имя класса:

  • если свойство className элемента не содержит имя класса, его следует добавить.
  • если свойство className элемента содержит имя класса, его не следует добавлять.

Давайте переведем эти случаи в два теста. В тестовом каталоге создайте новый файл classNameTest.js и добавьте следующее:

description ('addClass', function () {it ('должен добавить класс к элементу'); it ('не должен добавлять класс, который уже существует');});

Мы немного изменили формулировку на форму «она должна делать X», используемую в тестах. Это означает, что он читается немного лучше, но по сути остается той же читабельной формой, которую мы перечислили выше. Обычно не намного сложнее, чем перейти от идеи к тесту.

Но подождите, где тестовые функции? Что ж, когда мы опускаем второй параметр, Mocha помечает эти тесты как ожидающие в результатах теста. Это удобный способ настроить ряд тестов - что-то вроде списка задач, которые вы собираетесь написать.

Давайте продолжим реализацию первого теста.

description ('addClass', function () {it ('должен добавить класс к элементу', function () {var element = {className: ''}; addClass (element, 'test-class'); assert.equal (element .className, 'test-class');}); it ('не следует добавлять класс, который уже существует');});

В этом тесте мы создаем переменную элемента и передаем ее в качестве параметра функции addClass вместе со строкой test-class (новый класс для добавления). Затем мы проверяем, что класс включен в значение, используя утверждение.

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

Хотя эта функция предназначена для работы с элементами DOM, здесь мы используем простой объект JS. Иногда мы можем использовать динамическую природу JavaScript таким образом, чтобы упростить наши тесты. Если бы мы этого не делали, нам нужно было бы создать фактический элемент, и это усложнило бы наш тестовый код. В качестве дополнительного преимущества, поскольку мы не используем DOM, мы также можем запустить этот тест в Node.js, если мы того пожелаем.

Запуск тестов в браузере

Чтобы запустить тест в браузере, вам нужно добавить className.js и classNameTest.js к исполнителю:

<! - загрузить код, который вы хотите протестировать, здесь -> <script src = "js / className.js"> </ script> <! - загрузить тестовые файлы здесь -> <script src = "test / classNameTest .js "> </ скрипт>

Теперь вы должны увидеть, что один тестовый проход и другой тест отображаются как ожидающие, как показано в следующем CodePen. Обратите внимание, что код немного отличается от примера, чтобы код работал в среде CodePen.

Увидеть перо Модульное тестирование с Мокко (1) по SitePoint ( @SitePoint ) на CodePen ,

Далее давайте реализуем второй тест ...

it ('не следует добавлять класс, который уже существует'), function () {var element = {className: 'exist'}; addClass (element, 'exist'); var numClasses = element.className.split (''). длина; assert.equal (numClasses, 1);});

Это хорошая привычка часто запускать ваши тесты, поэтому давайте проверим, что произойдет, если мы запустим тесты сейчас. Как и следовало ожидать, они должны пройти.

Вот еще один CodePen со вторым реализованным тестом.

Увидеть перо Модульное тестирование с Мокко (2) по SitePoint ( @SitePoint ) на CodePen ,

Но держись! Я на самом деле немного тебя обманул. Для этой функции существует третье поведение, которое мы не рассмотрели. В функции также есть ошибка - довольно серьезная. Это только трехстрочная функция, но вы заметили это?

Давайте напишем еще один тест для третьего поведения, который выставляет ошибку в качестве бонуса.

it ('должен добавить новый класс после существующего'), function () {var element = {className: 'exist'}; addClass (element, 'new-class'); var classes = element.className.split ('') ; assert.equal (classes [1], 'new-class');});

На этот раз тест не пройден. Вы можете увидеть это в действии в следующем CodePen. Проблема здесь проста: имена классов CSS в элементах должны быть разделены пробелом. Тем не менее, наша текущая реализация addClass не добавляет пробел!

Увидеть перо Модульное тестирование с Mocha (3) по SitePoint ( @SitePoint ) на CodePen ,

Давайте исправим функцию и сделаем тест пройден.

function addClass (el, newClass) {if (el.className.indexOf (newClass)! == -1) {return; } if (el.className! == '') {// убедитесь, что имена классов разделены пробелом newClass = '' + newClass; } el.className + = newClass; }

И вот последний CodePen с фиксированной функцией и прохождением тестов.

Увидеть перо Модульное тестирование с Мокко (4) по SitePoint ( @SitePoint ) на CodePen ,

Выполнение тестов на узле

В Node вещи видны только другим вещам в том же файле. Так как className.js и classNameTest.js находятся в разных файлах, нам нужно найти способ показать один другому. Стандартный способ сделать это - использовать module.exports. Если вам нужен освежающий напиток, вы можете прочитать все об этом здесь: Понимание module.exports и экспорта в Node.js

Код по существу остается тем же самым, но структурирован немного по-другому:

// className.js module.exports = {addClass: function (el, newClass) {if (el.className.indexOf (newClass)! == -1) {return; } if (el.className! == '') {// убедитесь, что имена классов разделены пробелом newClass = '' + newClass; } el.className + = newClass; }} // classNameTest.js var chai = require ('chai'); var assert = chai.assert; var className = require ('../ js / className.js'); var addClass = className.addClass; // Остальная часть файла остается той же самой описанием ('addClass', function () {...});

И, как видите, тесты пройдены.

И, как видите, тесты пройдены

Что дальше?

Как видите, тестирование не должно быть сложным или сложным. Как и в случае с другими аспектами написания приложений на JavaScript, у вас есть несколько базовых шаблонов, которые повторяются. Как только вы ознакомитесь с ними, вы можете продолжать использовать их снова и снова.

Но это всего лишь царапина на поверхности. Есть много чего узнать о модульном тестировании.

  • Тестирование более сложных систем
  • Как работать с Ajax, базами данных и другими «внешними» вещами?
  • Разработка через тестирование

Если вы хотите продолжить изучать это и многое другое, я создал бесплатный модуль быстрого запуска JavaScript , Если вы нашли эту статью полезной, вы должны определенно проверить это здесь ,

В качестве альтернативы, если видео больше подходит вашему стилю, вас может заинтересовать курс SitePoint Premium: Разработка через тестирование в Node.js ,

Похожие

YouTube & Co.: Что мне разрешено, а что нет?
... видео - загружать, смотреть, захватывать, вставлять? Мы попробуем несколько ответов. Что мне разрешено загружать? Решающим фактором является то, кто сделал фильм или владеет правами на него. Человек тогда имеет авторское право на часть и может использовать часть в любой форме. Загрузка на YouTube также является способом восстановления.
Что нужно саду после зимы?
После нескольких месяцев заморозков и колебаний температуры наш сад ждет весну с тоской. Чтобы помочь садовой растительности, подготовиться к новому сезону, давайте начнем до того, как в нем наступит весна. Давайте помнить - забота требуется не только для цветочных уступов или газонов, но также и для поверхностей заднего двора.
Руководство для начинающих по тестированию функционального JavaScript - SitePoint
... теста становится красным. Красный! Наш мозг чувствует, что есть проблема. Есть конечно. Теперь было продемонстрировано, что наша простая функция isPalindrome, которая просто возвращает true, не работает эффективно с этим новым тестом. Итак, давайте обновим isPalindrome, добавив возможность сравнивать строку, переданную вперед и назад. const isPalindrome = (str) => {return str .split ("") .reverse () .join ("") === str; }; Тестирование
Tor - что это такое и как им пользоваться?
... наиболее важные вопросы, связанные с использованием сети Tor. Что это такое и как работает сеть Tor? Термин «Tor» является аббревиатурой английских слов «Лукового маршрутизатора» , которые определяют основную идею способа работы этой технологии. Сеть Tor основана на луковой маршрутизации . Это позволяет анонимный доступ к интернет-ресурсам, избегая цензуры и сетевых блокад. Как с
Как PS Vita будет работать с PS4: все, что вам нужно знать
... что вам нужно знать ниже. Итак, наступит день запуска, все, что вам нужно сделать, - это разорвать свой новый PS4, убедиться, что он и PS Vita обновлены, и вы все будете готовы воспользоваться многими новыми функциями, такими как удаленное воспроизведение и возможности второго экрана.
... всех? Не беспокойтесь: у Насы есть план. Американские космические ученые разработали официальные...
... всех? Не беспокойтесь: у Насы есть план. Американские космические ученые разработали официальные планы относительно того, как бороться с поступающими астероидами, которые могут разрушить нашу планету.
Что такое рынок Форекс?
Из статьи вы узнаете: - Что такое рынок Forex - Что такое торговля на Форекс? Что такое рынок Форекс? Форекс - это международный валютный рынок, основой которого является межбанковский рынок - рынок, на котором банки обменивают валюту между собой. Индивидуальные инвесторы , такие как вы или я, могут быть подключены к этому рынку благодаря посредническим
Intel Ivy Bridge: все, что вам нужно знать
Весной этого года Intel собирается выпустить процессоры последнего поколения, несмотря на небольшую неудачу, затронувшую модели со сверхнизким напряжением, предназначенные для сверхтонких ноутбуков. По обычным стандартам запуск должен отметить новую «галочку» в линейке продуктов компании, но Intel выходит за рамки простого сокращения текущего 32-нм процессора Sandy Bridge, представив некоторые фундаментальные усовершенствования вместе с его новым 22-нм процессом. Для тех, кто незнаком,
Замечательный Портфель WebWave, часть 4 - позиционирование сайта
... нали, как создать полностью адаптивный (адаптированный для всех мобильных устройств) веб-сайт, на котором вы представите свое фотографическое портфолио. Вы также узнали много функций WebWave, которые были созданы специально для фотографов. Поэтому мы предполагаем, что ваш сайт уже готов и опубликован в Интернете. Следующий шаг к успешному представлению вашего портфолио в сети - это охват как можно большего числа пользователей. Именно поэтому сегодняшнее руководство будет посвящено позиционированию
Смартфон Xiaomi имеет скрытый ярлык для проверки его оборудования
... что, вероятно, вызывает сбой - аппаратное обеспечение или конкретное приложение. Ну так что ты делаешь? Скачать сторонние приложения для тестирования оборудования? Ну, нет приложения, которое позволит вам проверить каждую аппаратную область на всех телефонах. Либо они позволят вам выполнить базовый общий тест на дисплее, камере и динамике, либо в итоге вы загрузите несколько приложений для проверки всех зон. Что касается смартфонов Xiaomi, разработчики достаточно любезны, чтобы разместить
Microsoft запустила магазин Xbox Official Gear. Мы проверяем его предложение
... вая информация просочилась в сеть Xbox Official Gear Shop Фан-магазин, предлагающий фанатам различные виды игровых гаджетов. Как и ожидалось, после стационарного дебюта на E3 активировался gear.xbox.com, где мы можем просмотреть весь ассортимент. И этот не заканчивается с брендом Xbox. Для любителей игр это рай на земле, но, к сожалению, недоступный для покупателей

Комментарии

Вы пытаетесь пойти по доступным ценам, потому что вы должны, потому что вы хотите, или потому что вы действительно думаете, что получите хороший дизайн?
Вы пытаетесь пойти по доступным ценам, потому что вы должны, потому что вы хотите, или потому что вы действительно думаете, что получите хороший дизайн? Здесь нет правильного ответа, но вы должны точно знать, что предлагает 99designs. Для многих людей это именно то, что им нужно. Это приносит дизайн в рамках бюджета. Для других не так уж и много. Это целенаправленное мошенничество с 99designs , но не все равно.
Какую серию автоспорта вы думаете, что они должны добавить дальше?
Какую серию автоспорта вы думаете, что они должны добавить дальше? Помогло ли вам наше руководство по загрузке и установке? Мы всегда рады услышать ваши мысли и мнения, так почему бы не поделиться ими с нами, используя поле для комментариев ниже?
Что нужно для настройки сети?
Что нужно для настройки сети? В зависимости от потребностей пользователя локальная сеть может состоять из нескольких устройств, а также нескольких тысяч машин. Независимо от того, насколько большой будет сеть, она должна иметь : Оборудование Важным элементом каждого из них является сетевая карта. Позволяет подключить компьютер к сети. Это может быть проводная или беспроводная сеть. Чтобы подключить более двух компьютеров, вам также потребуется концентратор
Отлично, что дальше?
Отлично, что дальше? К сожалению, в iOS отсутствуют более богатые опции создания PDF, поэтому вы не сможете выбрать формат страницы, настроить сжатие изображений или защитить документ паролем. Самым классным в этом методе является то, что его можно использовать для быстрого превращения чего угодно - от фотографий и электронных писем до документов Office и iWork на веб-страницы и т. Д. - в удобный PDF-файл везде, где документ можно распечатать на вашем iPhone или iPad. РУКОВОДСТВО:
Что такое Stick PC?
Что такое Stick PC? В концепции Stick PC нет ничего нового. Однако они стали довольно популярными, когда Intel анонсировала Compute Stick еще в 2015 году. Идея проста. Они немного похожи на флешку, очень похожую на флешку. Однако, как и в оригинальном ChromeCast, они подключаются к порту HDMI, а не к USB. Это означает, что они маленькие, они легко помещаются в вашем кармане, а главное, они легко переносимы. Тем не менее, большинству из них нужен источник питания (порт micro USB для
Что дальше?
Что дальше? У меня есть обновление функции, над которым я планирую поработать этим летом, но я также подожду на Minecraft v1.12.x, чтобы посмотреть, что там нужно сделать. Кажется, что это должно быть прямо за углом. Благодаря обновлению BiblioCraft и обновлению до лета, я смогу обновить BiblioCraft до новой версии Minecraft вскоре после того, как forge выпустит обновление для Minecraft 1.12. По крайней мере, таков план. Кроме того, я знаю, что форумы на этом сайте переполнены спамом, и это
Что делает функциональный код простым для тестирования?
Что делает функциональный код простым для тестирования? Если вы думаете о концепциях, которые мы только что обсудили, вы, вероятно, уже понимаете, почему функциональный код легче тестировать. Написание тестов для чистой функции тривиально, потому что каждый вход имеет согласованный вывод. Все, что вам нужно сделать, это установить ожидания и запустить их против кода. Нет контекста, который нужно устанавливать, нет никаких функциональных зависимостей, которые нужно отслеживать, нет изменяющегося
Я подумал: как заставить меня вспомнить, что я действительно пишу вместе?
Я подумал: как заставить меня вспомнить, что я действительно пишу вместе? И тут, совершенно спонтанно, я увидел! Я видел в слове ДЕЙСТВИТЕЛЬНО кучу пиара или пиара. Я пометил пиар фиолетовым цветом. В рамках консолидации знаний я думал, что для пиара, чтобы быть пиаром, его всегда нужно писать вместе. Пиаристы. Всегда вместе Мы пишем пиар вместе, как NA PR AWDĘ.
Что такое рынок Форекс?
Что такое рынок Форекс? Форекс - это международный валютный рынок, основой которого является межбанковский рынок - рынок, на котором банки обменивают валюту между собой. Индивидуальные инвесторы , такие как вы или я, могут быть подключены к этому рынку благодаря посредническим учреждениям - брокерам . Те, в зависимости от операционной модели, используют котировки на банковском рынке или отправляют наши заказы непосредственно на этот рынок.
Что это такое и как работает сеть Tor?
Что это такое и как работает сеть Tor? Термин «Tor» является аббревиатурой английских слов «Лукового маршрутизатора» , которые определяют основную идею способа работы этой технологии. Сеть Tor основана на луковой маршрутизации . Это позволяет анонимный доступ к интернет-ресурсам, избегая цензуры и сетевых блокад. Как с VPN Люди обычно используют жителей стран, в которых Интернет подвергается
Что такое подготовка статьи или реализация другого контента?
Что такое подготовка статьи или реализация другого контента? К.М .: В моем случае тема выбрана первой. Я по профессии журналист, поэтому долгое время рассматривал Википедию как способ проверить свои навыки. Затем наступает время для чтения. Статьи Википедии должны быть как можно более полными, описывать тему всесторонне, освещать все основные темы истории. На практике это означает часы, потраченные на источники. Для Википедии рецензируемые научные журналы и

Вы когда-нибудь вносили какие-то изменения в свой код, а потом обнаружили, что он вызвал что-то еще?
Но что, если этого не произошло?
Что если бы у вас был способ узнать, когда что-то сломалось в результате какого-то изменения?
Итак, каковы входы и поведение для этой функции?
Но подождите, где тестовые функции?
Это только трехстрочная функция, но вы заметили это?
Что дальше?
Что мне разрешено, а что нет?
Видео - загружать, смотреть, захватывать, вставлять?
Что мне разрешено загружать?