Познакомьтесь с Майки:

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

Лето уже в самый разгар, и Майки только что получил известие от родителей, что информация о расписании его занятий на следующий учебный год пришла по почте. Майки читает письмо и узнает, что его классным руководителем будет мистер Дженцен в комнате 211 вместе с 22 другими учениками. Майки звонит своему другу Томми, чтобы спросить, какой у него учитель, и узнает, что Томми будет через холл с мисс Роубл в комнате 212. Это заставляет Майки нервничать. Он только что переехал в новый город и не успел завести друзей. Майки надеялся, что он будет в одном классе с Томми, который поможет ему познакомиться со всеми крутыми ребятами. Как Майки может рассчитывать узнать всех в своем классе самостоятельно?

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

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

Что такое RSpec и зачем проводить тестирование?

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

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

Среда набора тестов

Майки готов начать. Он открывает свой терминал и создает новый каталог для своего проекта. В корневом каталоге проекта он создает папку для всех тестов с именем spec:

mkdir spec

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

touch student_spec.rb

Пока Майки находится в корне этого каталога, каждый раз, когда Майки вводит «rspec» в свой терминал, приложение будет искать папку с именем «spec» и запускать каждый из включенных в нее тестов. В данном случае Майки тестирует свой файл student.rb, содержащий всю логику того, как он будет следить за своими новыми одноклассниками.

Знакомство с синтаксисом RSpec

Майки пишет базовый метод для проверки работоспособности RSpec. В файле student.rb он определяет метод #return_name, который просто берет имя и возвращает его.

def return_name(name)
  name
end

В файл спецификации Майки включает тест для своего метода #return_name:

describe "initial test" do
  context "when testing the RSpec environment" do
    describe "#return_name" do
      it "should return the name passed to it as an argument" do
        expect(return_name("Mikey")).to eq("Mikey")
      end
    end
  end
end

Кратко рассмотрим синтаксис.

Описание «описать»

Если вы не можете описать свои действия как процесс, вы не знаете, что делаете. — У. Эдвардс Деминг

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

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

Все дело в контексте

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

В приведенном выше примере мы видим, что Майки использовал ключевое слово context, чтобы сообщить нам, что тест предназначен для подтверждения правильности настройки среды RSpec.

Он делает то, что ему говорят

Ключевое слово expect определяет ожидание, которое мы используем, чтобы определить, работает ли наше приложение так, как задумано. За каждым ключевым словом expect обычно следует ключевое слово to (или, в некоторых случаях, not_to). Значение всего, что содержится в нашем вызове expect, сравнивается с нашим ожиданием. Если результаты совпадают, тесты будут пройдены, в противном случае они не пройдут.

Быстрый взгляд на пример показывает, что Майки ожидал, что возвращаемое значение #return_name(“Mikey”) будет равно “Mikey”.

Тестирование наших тестов

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

Давайте посмотрим на фальшивую информацию об ученике Майки:

before(:all) do
  @tommy = Student.new({
    name: "Tommy",
    true_pal: true,
    clique: "cool kids",
    teacher: "Wroble",
    homeroom: 212,
    intelligence: 7
  })
  @danny = Student.new({
    name: "Danny",
    true_pal: false,
    clique: "smart kids",
    teacher: "Jentzen",
    homeroom: 211,
    intelligence: 10
  })
end

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

Что касается тестов, Майки знает, что для каждого ученика он захочет узнать их имя, являются ли они его друзьями, к какой клике они принадлежат, их классному руководителю, их номеру в классе и их интеллекту. Давайте взглянем на тест, который Майки написал для своего метода класса Student #initialize.

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

После определения метода Student #initialize Майки запускает RSpec и наблюдает за прохождением тестов. Теперь Майки хочет посмотреть, что произойдет, если он сдаст неправильно оформленного студента на тест:

before(:all) do
  @dummy = Student.new({
    “Name: = dumb”,
    true_pal: “true”,
    clique: "cool kids",
    teacher: "Wroble",
    homeroom: two-twelve,
    intelligence: 7
  })
end

Майки запускает RSpec и наблюдает за провалом тестов.

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

Дополнительные материалы

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

https://github.com/christopher-hague/rspec-student-testing