Здравствуйте, записался на курс. При этом ставил галочку на "обучаться с тьютором". На email пришло письмо, о том, что записался на самостоятельное изучение курса. Как выбрать тьютора? |
В основном статические страницы
Автоматизируем тесты с Guard
Одно из неудобств связанных с использованием команды rspec это необходимость переключаться на командную строку и запускать тесты вручную. (Второе неудобство - медленный запуск набора тестов рассматривается в Разделе 3.6.3.) В этом разделе мы покажем как использовать Guard для автоматизации запуска тестов. Guard отслеживает изменения в файловой системе так что, например, когда мы изменяем файл static_pages_spec.rb запустится только этот тест. Более того, мы можем настроить Guard таким образом, что при, скажем, изменении файла home.html.erb автоматически запустится static_pages_spec.rb.
Вначале мы добавим guard-rspec в Gemfile (Листинг 3.34).
source 'https://rubygems.org' ruby '2.0.0' #ruby-gemset=railstutorial_rails_4_0 gem 'rails', '4.0.2' group :development, :test do gem 'sqlite3', '1.3.8' gem 'rspec-rails', '2.13.1' gem 'guard-rspec', '2.5.0' end group :test do gem 'selenium-webdriver', '2.35.1' gem 'capybara', '2.1.0' # OS X: раскомментируйте эти строки. # gem 'growl', '1.0.3' # Linux: раскомментируйте эти строки. # gem 'libnotify', '0.8.0' # Windows: раскомментируйте эти строки. # gem 'rb-notifu', '0.0.4' # gem 'win32console', '1.3.2' # gem 'wdm', '0.1.0' end gem 'sass-rails', '4.0.1' gem 'uglifier', '2.1.1' gem 'coffee-rails', '4.0.1' gem 'jquery-rails', '3.0.4' gem 'turbolinks', '1.1.1' gem 'jbuilder', '1.0.2' group :doc do gem 'sdoc', '0.3.20', require: false end group :production do gem 'pg', '0.15.1' gem 'rails_12factor', '0.0.2' endЛистинг 3.34. Gemfile включающий Guard для примера приложения.
Убедитесь в том что вы раскомментировали строки соответствующие вашей системе в тестовой группе. (Обратите внимание - если вы хотите использовать уведомления Growl, вам придется приобрести Growl, который доступен в Apple App Store по весьма скромной цене.)
Затем мы устанавливаем гемы запустив bundle install:
$ bundle install
Затем инициализируем Guard для работы с RSpec:
$ bundle exec guard init rspec Writing new Guardfile to /Users/mhartl/rails_projects/sample_app/Guardfile rspec guard added to Guardfile, feel free to edit it
Теперь отредактируем сгенерированный Guardfile так чтобы Guard запускал правильные тесты после обновления интеграционных тестов и представлений (Листинг 3.35).
require 'active_support/inflector' guard 'rspec', all_after_pass: false do . . . watch('config/routes.rb') # Custom Rails Tutorial specs watch(%r{^app/controllers/(.+)_(controller)\.rb$}) do |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb", (m[1][/_pages/] ? "spec/requests/#{m[1]}_spec.rb" : "spec/requests/#{m[1].singularize}_pages_spec.rb")] end watch(%r{^app/views/(.+)/}) do |m| (m[1][/_pages/] ? "spec/requests/#{m[1]}_spec.rb" : "spec/requests/#{m[1].singularize}_pages_spec.rb") end watch(%r{^app/controllers/sessions_controller\.rb$}) do |m| "spec/requests/authentication_pages_spec.rb" end . . . endЛистинг 3.35. Дополнения к дефолтному Guardfile. Обратите внимание на добавленный require.
Здесь строка
guard 'rspec', all_after_pass: false do
обеспечивает незапуск полного набора тестов после прохождения провальных тестов (для ускорения цикла Красный-Зеленый-Реорганизация).
Теперь мы можем запустить guard следующим образом:
$ bundle exec guard
Для того чтобы избавиться от необходимости запускать команду с префиксом bundle exec, повторите шаги из Раздела 3.6.1.
Кстати, если Guard будет жаловаться на отсутствие директории spec/routing, вы можете исправить ситуацию создав пустую директорию с соответствующим названием:
$ mkdir spec/routing
Ускоряем тесты с помощью Spork
При запуске bundle exec rspec вы могли заметить что перед началом запуска тестов проходит несколько секунд, тогда как выполнение самих тестов происходит довольно быстро. Это связано с тем, что при каждом запуске тестов RSpec должен перезагрузить все Рельсовое окружение. Тестовый сервер Spork 13Spork это комбинация spoon-fork (ложка-вилка). Название проекта обыгрывает использование Spork-ом форков POSIX-а. предназначен для решения этой проблемы. Spork загружает окружение однократно, а затем поддерживает пул процессов для запуска следующих тестов. Spork особенно полезен в комбинации с Guard (Раздел 3.6.2).
Первый шаг это добавление spork гем зависимости в Gemfile (Листинга 3.36).
source 'https://rubygems.org' ruby '2.0.0' #ruby-gemset=railstutorial_rails_4_0 gem 'rails', '4.0.2' group :development, :test do . . . gem 'spork-rails', '4.0.0' gem 'guard-spork', '1.5.0' gem 'childprocess', '0.3.6' end . . .Листинг 3.36. Gemfile для примера приложения.
Затем установите Spork используя bundle install:
$ bundle install
Затем сделайте начальную загрузку конфигурации Spork:
$ bundle exec spork --bootstrap
Теперь нам необходимо отредактировать конфигурационный файл RSpec spec/spec_helper.rb таким образом, чтобы окружение загружалось в блоке prefork который обеспечит его однократную загрузку (Листинга 3.37).
require 'rubygems' require 'spork' Spork.prefork do ENV["RAILS_ENV"] ||= 'test' require File.expand_path("../../config/environment", __FILE__) require 'rspec/rails' require 'rspec/autorun' # Requires supporting ruby files with custom matchers and macros, etc, # in spec/support/ and its subdirectories. Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} # Checks for pending migrations before tests are run. # If you are not using ActiveRecord, you can remove this line. ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration) RSpec.configure do |config| # ## Mock Framework # # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: # # config.mock_with :mocha # config.mock_with :flexmock # config.mock_with :rr # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures config.fixture_path = "#{::Rails.root}/spec/fixtures" # If you're not using ActiveRecord, or you'd prefer not to run each of your # examples within a transaction, remove the following line or assign false # instead of true. config.use_transactional_fixtures = true # If true, the base class of anonymous controllers will be inferred # automatically. This will be the default behavior in future versions of # rspec-rails. config.infer_base_class_for_anonymous_controllers = false # Run specs in random order to surface order dependencies. If you find an # order dependency and want to debug it, you can fix the order by providing # the seed, which is printed after each run. # --seed 1234 config.order = "random" config.include Capybara::DSL end end Spork.each_run do # This code will be run each time you run your specs. endЛистинг 3.37. Добавление загрузки окружения в блок Spork.prefork. spec/spec_helper.rb
Перед запуском Spork мы можем сделать контрольный замер времени необходимого на прохождения тестов следующим образом:
$ time bundle exec rspec spec/requests/static_pages_spec.rb ...... 6 examples, 0 failures real 0m8.633s user 0m7.240s sys 0m1.068s
Здесь набор тестов занимает более семи секунд, даже при том, что фактически тесты отрабатывают менее чем за одну десятую секунды. Чтобы ускорить это мы можем открыть отдельное окно терминала, переместиться в корневой Rails каталог, а затем запустить сервер Spork:
$ bundle exec spork Using RSpec Loading Spork.prefork block... Spork is ready and listening on 8989!
(Для того чтобы избавиться от необходимости запускать команду с префиксом bundle exec, повторите шаги из Раздела 3.6.1.) В другом терминальном окне, мы теперь можем запустить наш набор тестов с --drb опцией ("распределенный Ruby") и проверить что издержки, связанные с постоянной перезагрузкой окружения значительно сократились:
$ time bundle exec rspec spec/requests/static_pages_spec.rb --drb ...... 6 examples, 0 failures real 0m2.649s user 0m1.259s sys 0m0.258s
Включать опцию --drb при каждом запуске rspec довольно неудобно, поэтому я рекомендую добавить ее в .rspec файл расположенный в корневой директории проекта, как это показано в Листинге 3.38.
--colour --drbЛистинг 3.38. Конфигурирование Rspec для автоматического использования Spork. .rspec
Небольшой совет касательно использования Spork: если ваши тесты провальны, а вы думаете, что они должны проходить, проблема может быть связана со Spork, который иногда может не перегружать необходимые файлы. (Например, это часто происходит при изменении конфигурационных файлов, таких как routes.rb.) При возникновении подобных сомнений, отключите Spork сервер командой Ctrl-C и рестартуйте его:
$ bundle exec spork Using RSpec Loading Spork.prefork block... Spork is ready and listening on 8989! ^C $ bundle exec spork
Guard и Spork
Спорк особенно полезен в комбинации с Guard, мы можем подружить их следующим образом:
$ bundle exec guard init spork
Затем нам необходимо изменить Guardfile как в Листинге 3.39.
require 'active_support/inflector' guard 'spork', :cucumber_env => { 'RAILS_ENV' => 'test' }, :rspec_env => { 'RAILS_ENV' => 'test' } do watch('config/application.rb') watch('config/environment.rb') watch('config/environments/test.rb') watch(%r{^config/initializers/.+\.rb$}) watch('Gemfile') watch('Gemfile.lock') watch('spec/spec_helper.rb') { :rspec } watch('test/test_helper.rb') { :test_unit } watch(%r{features/support/}) { :cucumber } end guard 'rspec', all_after_pass: false, cli: '--drb' do . . . endЛистинг 3.39. Guardfile обновленный для использования Spork. Guardfile
Обратите внимание что мы обновили аргументы guard включив cli: '--drb', которая обеспечивает использование Guard-ом интерфейса командной строки (cli) для Spork сервера. Мы также добавили команду для слежения за директорией features/support/, которую мы начнем менять начиная с Главы 5.
Закончив с конфигурацией, мы можем одновременно стартовать Guard и Spork командой guard:
$ bundle exec guard
Guard автоматически стартует Spork сервер, кардинально уменьшая издержки при запуске тестов.
Хорошо сконфигурированное тестовое окружение с Guard, Spork и (опционально) уведомлениями вызывают привыкание к разработке через тестирование. См. более подробно об этом в скринкастах Rails Tutorial14http://railstutorial.org/screencasts.
Запускаем тесты внутри Sublime Text
Если вы используете Sublime Text, то у вас есть большое количество вспомогательных команд для запуска тестов непосредственно в редакторе. Для того чтобы научиться пользоваться ими, следуйте инструкциям для своей платформы на Sublime Text 2 Ruby Tests.15https://github.com/maltize/sublime-text-2-ruby-tests На моей платформе (Macintosh OS X), я могу установить команды следующим образом:
$ cd ~/Library/Application\ Support/Sublime\ Text\ 2/Packages $ git clone https://github.com/maltize/sublime-text-2-ruby-tests.git RubyTest
Вы также можете пока использовать инструкции по настройке для Rails Tutorial Sublime Text.16https://github.com/mhartl/rails_tutorial_sublime_text
После перезапуска Sublime Text, пакет RubyTest предоставляет следующие команды:
- Command-Shift-R:запуск одного теста (если запускается на it блоке) или группы тестов (если выполняется на describe блоке)
- Command-Shift-E:запуск последнего теста(-ов)
- Command-Shift-T:запуск всех тестов в текущем файле
Поскольку набор тестов может стать довольно медленным даже для относительно небольших проектов, возможность запускать один тест (или небольшую группу тестов) за раз может сильно упростить жизнь разработчика. Даже один единственный тест требует загрузки Rails окружения, вот почему эти команды отлично работают вместе со Spork: запуск одного теста устраняет необходимость выполнения всего файла с тестами, в то время как Spork устраняет издержки связанные с рестартом тестового окружения. Вот последовательность команд которую я рекомендую:
- Стартовать Spork в терминале.
- Написать один тест или небольшую группу тестов.
- Выполнить Command-Shift-R чтобы убедиться что тест или группа тестов в красном.
- Написать соответствующий код приложения.
- Выполнить Command-Shift-E для повторного запуска того же теста/группы тестов для проверки того что они позеленели.
- Повторить шаги 2 – 5 при необходимости.
- По достижении естественной точки остановки (например, перед коммитом), запустить rspec spec/ в командной строке для того, чтобы убедиться что полный набор тестов по-прежнему в зеленом.
Даже с возможностью запуска тестов внутри Sublime Text, я по-прежнему предпочитаю использовать Guard, но в настоящий момент меня кормит TDD техника описанная выше.