Ненадежные / Flakey Capybara / AngularJS Интеграционные тесты с проблемами синхронизации

Как я могу сделать эти тесты надежно пройти?

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


Тестовая среда кодаРельсы 3.2RSpec 2.xВодосвинкаполтергейстPhantomJSAngularJSGoogle Chrome Версия 47.0.2526.106 (64-разрядная версия)Тестирование драгоценных камней из Gemfile.lock
capybara (2.1.0)
database_cleaner (0.7.1)
debug_inspector (0.0.2)
guard-bundler (0.1.3)
guard-livereload (1.2.0)
guard-rspec (2.1.2)
jasminerice (0.0.10)
pg (0.17.1)
phantomjs (2.1.1.0)
poltergeist (1.4.1)
protractor-rails (0.0.17)
pry (0.9.12)
rack (1.4.7)
rack-test (0.6.3)
rails (3.2.21)
rails-assets-angular (1.3.20)
rspec-rails (2.11.4)
simplecov (0.8.2)
sprockets (2.2.3)
zeus (0.13.3)
zeus-parallel_tests (0.2.1)
Вещи, которые я пробовалУбедитесь, что я использую ожидающие DSL соответствия CapybaraУбедитесь, что мой очиститель базы данных правильно настроенПротестируйте каждый элемент страницы, предполагая, что он может отсутствовать на странице и все еще может загружатьсяУзкие противоречивые тестыВыполнить только непоследовательный тест

Определите код DSL Capybara, которые являются причиной несовместимых результатов испытаний.

то есть создание новой записи и предполагая, что страница перенаправлена ​​и что запись находится на странице click_on

или же

.click не всегда «работает»Обновите Capybara до последней версии (в отдельной ветке)Обновлен Poltergeist и RSpec до последней версии (в отдельной ветке, все еще работаем над этим)Ресурсы, которые я использовал

[1]Капибара DSL
[2]Советы Capybara, PhantomJs, Poltergeist и Rspec
И многое другое ...

Как проходили тесты

rspec spec/integration/costings/show_costing_spec.rb --format documentation

Тестовый кодshow_costing_spec.rb
require "spec_helper"

RSpec.describe "Show a new costing in the listing," do

  before :each do
    admin_sign_in
    create_costing("test1")
  end

  it "shows the costing after creation" do
    within "#costings_table" do
      expect(page).to have_css("#name", text: "test1")
    end
  end

  it "shows the details of the new costing after creation" do
    expect(page).to have_content("Costings")
    within "#costings_table" do
      expect(page).to have_content("test1")
      all("#show").last.click
    end

    expect(page).to have_content("Costing Details")
    expect(page).to have_css("#name", text: "test1")
  end
end  
spec_helper.rb
# This file is copied to spec/ when you run 'rails generate r spec:install'  
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
# Add library functions here so we can test them.
require File.expand_path(File.dirname(__FILE__) + "/../lib/general")
require 'rspec/rails'
require 'rspec/autorun'

# Integration Testing
require 'capybara/poltergeist'
Capybara.register_driver :poltergeist_debug do |app|
 Capybara::Poltergeist::,Driver.new(app, :inspector => true)  
end
Capybara.javascript_driver = :poltergeist_debug
Capybara.default_driver = :poltergeist_debug

# Capybara Integration Test Helpers
def admin_sign_in
  visit "/login"
  #Create staff member in database
  Staff.make!(:admin)
  #Log In
  fill_in "staff_username", with: "adminstaff"
  fill_in "staff_password", with: "password"
  click_button "login"
end

def create_costing(item)
  visit "/api#/costings"
  click_on "new_btn"
  within "#form_costing" do
    find("#name", match: :first).set("#{item}")
    find("#description", match: :first).set("test description")    
    find("#from_date", match: :first).set("15/02/2016")
    find("#cost_hourly_cents", match: :first).set("1.00")
    click_on "create_btn"
  end
end

RSpec.configure do |config|
  config.before(:suite) do
    # Requires supporting ruby files with custom matchers and macros, etc,
    # in spec/support/ and its subdirectories.
    require File.expand_path(File.dirname(__FILE__) + "/support/blueprints")
    Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
  end

  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  config.fixture_path = "#{::Rails.root}/spec/fixtures"

  # Allow a 'focus' tag so that we can run just a few tests which we are currently working on
  config.treat_symbols_as_metadata_keys_with_true_values = true
  config.filter_run focus: true
  config.run_all_when_everything_filtered = true
  config.filter_run_excluding :slow unless ENV["SLOW_SPECS"]

  # Defer Garbage Collection
  config.before(:all) { DeferredGarbageCollection.start }
  config.after(:all)  { DeferredGarbageCollection.reconsider }

  # 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 = false
  # config.infer_spec_type_from_file_location!

  # Configure Database Cleaner
  config.include Capybara::DSL
  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

  config.before(:each, :js => true) do
    DatabaseCleaner.strategy = :truncation
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end
end
Результаты теста

Test Run 1: Failing

Параметры запуска: include {: focus => true} exclude {: slow => true}

Все примеры были отфильтрованы; игнорируя {: focus => true}

Показать новую калькуляцию в списке, показывает калькуляцию после создания, показывает детали новой калькуляции после создания (СБОЙ - 1)

Неудачи:

1) Показать новую калькуляцию в листинге,
показывает детали новой калькуляции после создания
Ошибка / Ошибка: ожидаемо (страница) .to have_content ("test1")
ожидал, что #has_content? ("test1") вернет true, получил false
# ./spec/integration/costings/show_costing_spec.rb:20:in блок (3 уровня) в
# ./spec/integration/costings/show_costing_spec.rb:19:in блок (2 уровня) в




Закончено за 5,46 секунд 2 примера, 1 неудача

Test Run 2: Passing

Параметры запуска: include {: focus => true} exclude {: slow => true}

Все примеры были отфильтрованы; игнорируя {: focus => true}

Показать новую калькуляцию в листинге,
показывает стоимость после создания
показывает детали новой калькуляции после создания

Закончено за 3,57 секунды 2 примера, 0 сбоев

Обновление 1

Обновлены гемы тестирования до следующих версий:
капибара (2.6.2) из ​​(2.1.0)
database_cleaner (1.5.1) из (0.7.1)
debug_inspector (0.0.2)
охранник (0.1.3)
guard-livereload (1.2.0)
Guard-Spec (2.1.2)
Жасминерис (0.0.10)
пг (0.17.1)
фантомы (2.1.1.0)
полтергейст (1.9.0) из (1.4.1)
транспортир-рельсы (0.0.17)
pry (0.10.3) из (0.9.12)
стойка (1.4.7)
рейк-тест (0.6.3)
рельсы (3.2.21)
рельсы-активы-угловые (1.4.9) из (1.3.20)
рельсы rspec (3.4.2) из ​​(2.11.4)
simplecov (0.8.2)
звездочки (2.2.3)
Зевс (0.13.3)
zeus-parallel_tests (0.2.1)




















Result 1

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

Обновление 2

Я реализовал предложения Тома Уолпола. Убедитесь, что мой admin_sign_in ожидает завершения входа в систему.

Также обновил мои настройки database_cleaner, как предложил Том.

Result 2

На мой стек эти изменения, похоже, не повлияли.

Замечания: Если кто-то не использует AngularJS, я чувствую, что эти изменения имели бы значение. Так что спасибо Тому за твои предложения.

Обновление 3

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

Что я использовал
Я использовал "save_and_open_page" и "print page.html" для отладки.

К чему я переехал
Когда я работал с RSpec 3.4.2, я добавил вспомогательный метод отладки:

rails_helper.rb

def debugit
  puts current_url
  require 'pry'
  binding.pry
end

Result 3

URL будет напечатан в консоли, и тест будет приостановлен. На этом этапе я смогу перейти к URL-адресу, войти в систему, перейти на тестовую страницу и посмотреть, что сделал тест Capybara.

Это позволило мне определить, что источник моих проблем возник, когда в тесте использовался DSL capybara fill_in. В некоторых тестовых прогонах поля будут заполнены правильно, и форма будет отправлена. В другом случае форма будет заполнена правильно, но кнопка отправки будет нажата слишком быстро. В результате мы создали запись, но поля ввода имени и описания не были сохранены.

Обновление 4

Я обнаружил, что, поскольку я использовал формы и таблицы ввода AngularJS, AngularJS требовалось совсем немного времени для привязки к полям ввода. Если это не было разрешено, на этот раз входные данные не будут сохранены.

Capybara предоставляет методы ожидания, такие как "inside" и "find". Я использовал их, но они не помогли с проблемой времени привязки AngularJS. Я обнаружил, что ng-if можно использовать для создания оператора if для ожидания конкретного элемента, который будет означать привязки AngularJS к полям формы.

Поэтому я использовал методы ожидания Capybara для ожидания полей, которые я хотел заполнить, и использовал AngularJS 'ng-if, чтобы не показывать поля, пока они не будут готовы.

Реализация
index.html.erb

<div  ng-if="tableParams.data">
  <table id="costings_table ng-table="tableParams" class="table">
    <td id="field1">{{table.field1}}</td>
    <td id="field2">{{table.field2}}</td>
  </table>
</div>

Result 4

Тесты наконец проходят! Однако у меня есть все эти методы find с xpath, гарантирующие, что конкретные и трудные для цели объекты ожидаются ...

Обновление 5

Несмотря на то, что в моем gemfile я использовал gem phantomJS версии 2.1.1, моя версия командной строки была только 1.X. Это оказалось значительным.

Я обновил версию phantomJS для командной строки до 2.1.1. В то же время я обеспечил, чтобы все мои поля ввода, кнопки, таблицы, заголовки имели уникальные идентификаторы. Затем я смог удалить все вхождения find (: xpath), не нарушая тесты.

Result 5

Этот набор тестов теперь надежно проходит все время! Именно то, что я хотел! Да!