#ruby #rspec
#ruby #rspec
Вопрос:
Я поддерживаю автономный пакет автоматизации тестирования, написанный на Rspec amp; Capybara и SitePrism (без Rails).
Недавно я начал интегрировать его с Testrail для создания отчетов — для этого я использовал gem rspec-testrail, но мне пришлось немного изменить его, потому что я также хотел отправлять уведомления Slack с ходом тестирования и отчетом.
В любом случае, интеграция работает гладко, за исключением того факта, что обработка примера зависит от примера, имеющего исключение, а отсутствие исключения приводит к установке статуса теста как переданного в Testrail. Как представляется, after :each
nor after :example
в Rspec.configure
не гарантирует, что пример был завершен. Я также пробовал around :example
и around :each
, как описано здесь, но безрезультатно.
Я проверил содержимое example.metadata
, и похоже, что оно example.metadata[:execution_result]
содержит только started_at
переменную, но в готовом примере будут также переменные finished_at
и status
, согласно документам
Мое подозрение (после прочтения документов relish) заключается в том, что :aggregated_failures
является причиной разной структуры метаданных и нескольких ожиданий, выполняемых в потоках, которые позже объединяются в один обратный путь.
Вы знаете, как я могу дождаться завершения примера или как подключиться к состоянию, в котором он завершен? Или, может быть, мне следует создать пользовательский форматировщик, куда я подключался бы после того, как уведомления о примерах выводились на консоль (я хотел бы сохранить там трассировку стека).
Мой код выглядит следующим образом:
Тест (оба утверждения завершаются ошибкой):
require 'spec_helper'
feature 'Sign in' do
let(:login_page) { LoginPage.new }
let(:user) { { email: ENV['ADMIN_EMAIL'], password: ENV['ADMIN_PASSWORD'] } }
scenario 'is successful and user is redirected to dashboard for user with correct credentials', testrail_id: 5694 do
login_page.load
login_page.form.email.set(user[:email])
login_page.form.password.set(user[:password])
login_page.form.submit_btn.click
expect(login_page.sidebar).to have_jobs(text: "some_nonexistenttext")
login_page.logout
expect(current_url).to have_content "google.com"
end
end
Вывод на консоль из вышеупомянутого теста:
Failures:
1) Sign in is successful and user is redirected to dashboard for user with correct credentials
Got 2 failures:
1.1) Failure/Error: expect(login_page.sidebar).to have_jobs(text: "blala")
expected #has_jobs?({:text=>"some_nonexistenttext"}) to return true, got false
# ./spec/auth/login_spec.rb:13:in `block (3 levels) in <top (required)>'
1.2) Failure/Error: expect(current_url).to have_content "google.com"
expected to find text "google.com" in "https://example.com/"
# ./spec/auth/login_spec.rb:15:in `block (3 levels) in <top (required)>'
Finished in 53.91 seconds (files took 1.45 seconds to load)
4 examples, 1 failure
Failed examples:
rspec ./spec/auth/login_spec.rb:8 # Sign in is successful and user is redirected to dashboard for user with correct credentials
Помощник по спецификации:
require 'rubygems'
require 'capybara/rspec'
require 'selenium-webdriver'
require 'site_prism'
require 'slack-notifier'
require_relative '../config'
require_relative '../lib/testrail'
...
RSpec.configure do |config|
config.define_derived_metadata do |meta|
meta[:aggregate_failures] = true
end
config.example_status_persistence_file_path = 'examples.txt'
config.before :all do
testrail_initialize_test_run!
end
config.after :example, testrail_id: proc { |value| !value.nil? } do |example|
RSpec::Testrail.process(example)
end
end
метод обработки (слегка измененный по сравнению с оригинальным)
def process(example)
if example.exception
status = 5
message = example.exception.message
slack_notifier.publish(message_text "Failed")
elsif example.skipped? || example.pending?
puts 'Example skipped or pending'
status = 10
message = 'Pending or not implemented'
else
status = 1
message = ''
end
client.send_post("add_result_for_case/#{testrun['id']}/#{example.metadata[:testrail_id]}",
status_id: status,
comment: message)
end
Комментарии:
1. Проблема со связыванием GitHub,
rspec-core
которая проясняет процесс выполнения: github.com/rspec/rspec-core/issues/2289
Ответ №1:
Итак, в основном все, что мне нужно было, это использовать прослушиватель reporter и обрабатывать уведомления внутри него 🙂
config.reporter.register_listener RSpec::Testrail::Listener.new, :start, :example_failed, :example_passed, :example_pending, :stop