Проект: Начинаем создавать

Не забывайте использовать Git для фиксации изменений в ваших проектах!

Подготовка: RestClient

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

Использование Rest Client может оказаться полезным, если вам понадобится общаться с другим веб-сервисом, не имеющим API-библиотеки (хотя это довольно редкая ситуация в наши дни). Или если вы обнаружите склонность тестировать ваш собственный API из командной строки.

Ваша задача

  1. Убедитесь, что Rest Client установлен, выполнив команду $ gem install rest-client
  2. Запустите IRB ($ irb)
  3. require 'rest-client'
  4. Теперь вы можете использовать гем. Прочтите его документацию в репозитории на Github. Вы узнаете, что гем предоставляет довольно широкие возможности.
  5. Используйте Rest Client, чтобы попробовать поискать что-то в Google и исследуйте полученные результаты (вы можете найти параметры, необходимые Google для поиски в URL, просто поискав в обычном браузере. Обратите внимание на параметр q=).

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

Решения студентов

Проект: Руководство по Ruby on Rails

В этом проекте вы начнете выполнение руководства, создав статические страницы для сайта. Во второй главе вы освежите в памяти основные концепции Ruby, которые могут оказаться полезными по мере прохождения руководства. Даже если вы уже уверенно чувствуете себя с Ruby (например, полностью завершили курс по Ruby), глава будет полезной, поскольку покажет, как некоторые из этих концепций применяются в Rails.

Обратите внимание: Тестирование

Одна из особенностей руководства Хартла, о которой мы не говорили, это тестирование. Вы получили краткое введение в курсе по Основам веб-разработки и попробовали тестирование на практике в курсе по Ruby, но есть несколько нюансов, появляющихся, когда дело доходит до тестирования в Rails.

Майкл Хартл проделал отличную работу, объясняя, что происходит в Rails Tutorial. Если вы следовали нашему учебному курсу до текущего момента, вы должны обнаружить, что переход на тестирование в Rails довольно естественен после тестирования простого кода на Ruby (и несколько более интересен, поскольку вы тестируете страницы).

Если вы еще не чувствуете себя комфортно при работе с тестами, может сложиться ощущение, что вы учите одновременно два языка. Не расстраивайтесь, если что-то не понимаете. Нужно время, чтобы все встало на свои места.

Руководство в большей степени показывает подход "Разработка через тестирование" (или TDD), где вы сначала пишете тесты, и затем код, которые удовлетворяет условиям тестов. Это полезно по множеству причин, не последней из которых является то, что вы точно будете знать, что тест проваливается, если ваш код не работает. Так же такой подход подразумевает, что вы пишете ровно столько кода, сколько необходимо для прохождения тестов (и ваш код, таким образом, остается чистым и красивым). Опять же, вы не сразу сможете чувствовать себя комфортно при работе через TDD, но это очень ценный и важный опыт.

90% из вас необходимо будет изучить тестирование в Rails, и это лучший способ это сделать. Эти 90% включают в себя всех, кто будет искать работу веб-разработчика или хочет создавать сайты более сложные, чем страничка с регистраций. Для остальных 10% допустимо пропустить разделы о тестировании, но мы рекомендуем ознакомиться всем без исключения. В противном случае вы просто не будете иметь представления о том, правильно ли работает ваше приложение, или нет.

Простой пример теста

Это пример теста из руководства:

    # spec/requests/static_pages_spec.rb
    require 'spec_helper'

    describe "Static pages" do

      describe "Home page" do

        it "should have the content 'Sample App'" do
          visit '/static_pages/home'
          expect(page).to have_content('Sample App')
        end
      end

      describe "Help page" do

        it "should have the content 'Help'" do
          visit '/static_pages/help'
          expect(page).to have_content('Help')
        end
      end

      describe "About page" do

        it "should have the content 'About Us'" do
          visit '/static_pages/about'
          expect(page).to have_content('About Us')
        end
      end
    end

Если вы прочитали его, и даже если вы никогда раньше не видели код, вы должны понять, что здесь происходит. Это "интеграционный" или "фича"-спек ("спек" == "спецификация" == "тест"), в котором мы убеждаемся, что взаимодействие пользователя со страницами происходит как задумано. Так же вы будете писать "юнит-тесты", которые предназначены для тестирования узких мест приложений, вроде методов моделей. Все они одинаково важны.

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

Во-первых, это файл - просто Ruby-код (обратите внимание на .rb). Он использует некоторые новые методы, которые доступны благодаря включению в gemfile гема rspec, но и они тоже написаны на старом добром Ruby. require 'spec_helper' на первой строке - это то, что добавляет в этот файл теста (spec/requests/static_pages_spec.rb) все методы и установки, необходимые для корректного запуска теста через RSpec, когда вы запускаете ваши тесты (например, введя команду rspec в командной строке).

Когда вы запускаете файл теста, RSpec отделяет каждый блок #it в отдельный тест и затем запускает их в случайном порядке (поэтому важно быть уверенным, что ваши тесты выполняются независимо друг от друга). Таким образом, все содержимое блока #it - это то, что непосредственно заставляет ваш тест "проходить" или проваливаться при запуске.

Блоки #describe лишь помогают отделить одни тесты от других, разделить их по смыслу. Обратите внимание, #describe является синонимом метода #context, с которым вы можете однажды повстречаться. Люди просто используют тот, который им нравится больше.

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

Пока вы с ним не встречались, но позднее вы так же познакомитесь с методом #before. Он позволяет выполнять какие-либо действия прежде, чем начнется выполнение тестов, например создать переменные (при помощи метода #let) или объекты моделей.

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

Теперь вы понимаете, почему важно вкладывать тесты в метод #describe и использовать метод #before для создания начальных условий - RSpec будет перезапускать этот "пре-код" для каждого отдельного теста, который вложен в тот же блок describe (context). Если вы создаете объект, например, нового пользователя, внутри блока #it, он перестанет существовать к моменту запуска следующего теста.

Возвращаясь к тестам выше, первый тест (внутри блока #it) состоит всего из двух строк. Первая, visit '/static_pages/home', лишь шаг, необходимый для перехода в позицию, где будет выполнен тест. Поскольку это очень простой тест, эта строка находится внутри блока #it. Если вам необходимо запустить несколько тестов, в каждом из которых сначала нужно перейти на одну и ту же страницу, разумнее будет вынести эту строку в блок before, расположенный перед всеми тестами, где будет совершаться такой переход.

Вторая строка (expect(page).to have_content('Help'), или, со всеми скобками expect(page).to(have_content('Help'))) выполняет нужное действие. expect(page) берет страницу, на которой мы "находимся" и ожидает некоторый определенный ответ, чтобы определить, проходит тест успешно или нет. .to(have_content('Help')) берет эту страницу (обратите внимание, что он "сцеплен" с методом #expect) и ищет (при помощи метода #have_content) HTML-тег, которые содержит слово "Help". Если он не может его найти, это скажет RSpec, что тест должен провалиться. Пока вам нет необходимости знать в деталях, что происходит "за кулисами" этих действий, просто поймите, как их применять.

Если вы уже растерялись, не беспокойтесь (как мы уже сказали, существуют и лучшие объяснения). По мере продвижения вперед руководство расскажет о тестировании. Надеемся, вы уже разогрелись и не будете шокированы внезапной встречей с ним.

Задачи

  1. Если вы все еще мало что понимаете, посмотрите Введение в RSpec от Treehouse.
  2. Пройдите Главу 3 из Ruby on Rails Tutorial, чтобы начать создавать приложение.
  3. Пройдите Главу 4 руководства, чтобы увидеть, как Ruby используется в Rails.
  4. Вернитесь к уроку о деплое, если у вас остались вопросы о процессе развертывания приложения.

Дополнительные ресурсы

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

Поделиться уроком: