Сквозное системное тестирование тем и компонентов тем

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

В настоящее время Discourse поддерживает два способа написания регрессионных тестов для тем. Первый в основном следует подходу EmberJS и касается только тестирования клиентского кода. Второй способ — это написание Rails system tests, которые позволяют тестировать одновременно серверный и клиентский код. Данный документ посвящен написанию Rails system tests для тем, и мы рекомендуем авторам тем сосредоточиться именно на этом подходе при тестировании своих тем.

Rails System tests для тем

В основе Discourse лежат фреймворки RSpec и Capybara для запуска Rails system tests. Для начала работы необходимы базовые знания о RSpec и Capybara. Мы рекомендуем сначала ознакомиться со следующими ссылками:

Руководящие принципы и советы по написанию системных тестов для тем

При написании системных тестов следует придерживаться следующих рекомендаций:

  • Системные тесты должны располагаться в директории spec/system внутри директории темы.

  • Каждый файл в директории spec/system должен следовать формату <описание_системного_теста>_spec.rb.

  • Блок describe верхнего уровня в RSpec должен содержать метаданные system: true. Пример:

    RSpec.describe "Тестирование темы или компонента темы", system: true do
      it "отображает компонент" do
        ...
      end
    end
    
  • Доступны вспомогательные методы upload_theme и upload_theme_component, которые необходимо вызывать перед запуском тестов. Пример:

    RSpec.describe "Тестирование темы или компонента темы", system: true do
      let!(:theme) do
        upload_theme
      end
    
      # или `upload_theme_component`, если ваша тема является компонентом
      #
      # let!(:theme_component) do
      #   upload_theme_component
      # end
    
      it "отображает компонент" do
        ...
      end
    end
    
  • Настройки темы можно изменить в системном тесте, вызвав метод update_setting у объекта theme, а затем сохранив тему.

    Пример:

    RSpec.describe "Тестирование темы", system: true do
      let!(:theme) do
        upload_theme
      end
    
      it "не отображает тему, когда настройка темы `should_render` равна false" do
        theme.update_setting(:should_render, false)
        theme.save!
    
        expect(page).not_to have_css("#some-identifier")
      end
    end
    
  • Discourse использует gem fabrication, который позволяет легко создавать тестовые данные, необходимые для каждого теста. Полный список фабрикаторов, доступных в ядре Discourse, также можно использовать в системных тестах темы.

    Пример:

    RSpec.describe "Тестирование темы", system: true do
      let!(:theme) do
        upload_theme
      end
    
      it "отображает тему" do
        user = Fabricate(:user)
        category = Fabricate(:category)
        topic = Fabricate(:topic)
        topic_2 = Fabricate(:topic, title: "Это тема номер 2")
    
        ...
      end
    end
    
  • Используйте вспомогательный метод sign_in для тестирования с разными профилями пользователей.

    Пример:

    RSpec.describe "Тестирование темы", system: true do
      let!(:theme) do
        upload_theme
      end
    
      it "не отображает тему для обычного пользователя" do
        user = Fabricate(:user)
        sign_in(user)
    
        ...
      end
    
      it "отображает тему для пользователя с правами администратора" do
        admin = Fabricate(:admin)
        sign_in(admin)
    
        ...
      end
    end
    
  • Иногда вам может потребоваться упростить запрос и инспекцию частей страницы для ваших системных тестов, сделав их более переиспользуемыми. Для этого можно использовать концепцию PageObjects, которую часто применяют в ядре.

    Пример:

    # frozen_string_literal: true
    
    module PageObjects
      module Components
        class MyCustomComponent < PageObjects::Components::Base
          COMPONENT_SELECTOR = ".my-custom-component"
    
          def click_action_button
            find("#{COMPONENT_SELECTOR} .action-button").click
          end
    
          def has_content?(content)
            has_css?("#{COMPONENT_SELECTOR} .content", text: content)
          end
        end
      end
    end
    

    Затем вы можете использовать его, импортировав с помощью встроенного в Ruby метода require_relative в начале файла системного теста.

    require_relative "page_objects/components/my_custom_component"
    

Запуск системных тестов темы

Системные тесты темы можно запустить с помощью CLI-пакета discourse_theme, который можно установить согласно этим инструкциям.

После установки CLI discourse_theme вы можете запустить все системные тесты в директории вашей темы, выполнив следующую команду:

discourse_theme rspec .

При первом запуске команды rspec для новой темы вам будет предложено выбрать, запускать ли системные тесты в локальной среде разработки Discourse или в контейнере Docker, который будет автоматически настроен для среды разработки. Если вы не являетесь опытным разработчиком плагинов или тем Discourse, мы рекомендуем выбрать n и запустить тесты в контейнере Docker, так как в этом случае всё заработает из коробки.

Команда discourse_theme rspec также поддерживает запуск отдельной директории спецификаций, файла или файла с указанием номера строки.

discourse_theme rspec /path/to/theme/spec/system
discourse_theme rspec /path/to/theme/spec/system/my_system_spec.rb
discourse_theme rspec /path/to/theme/spec/system/my_system_spec.rb:12

Режим с отображением (Headful mode)

По умолчанию системные тесты темы запускаются в Google Chrome в режиме headless. В этом режиме браузер не отображает ничего на экране, что позволяет тестам выполняться быстрее. Однако часто полезно видеть, что именно делает написанный вами системный тест, запустив Google Chrome в режиме headful. Вы можете включить этот режим, передав опцию --headful команде discourse_theme rspec.

discourse_theme rspec . --headful

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

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

Пример:

RSpec.describe "Тестирование темы", system: true do
  let!(:theme) do
    upload_theme
  end

  it "отображает тему" do
    visit("/")
    click("#some-button")
    pause_test
    # ...
  end
end

Этот документ находится под контролем версий — предлагайте изменения на GitHub.

18 лайков

I noticed that usually in the tests for components, let!(:theme) is used instead of let!(:theme_component). For example, in this test:

However the guide suggests using let!(:theme_component) for theme components:

Is there a reason why I should use theme_component as it’s described in this guide?

2 лайка