Как устранить нестабильные характеристики?

У меня на моем CICD случайно происходит сбой Ruby Rspec (локально не происходит сбой).

Это уменьшенная часть моего RSpec:

require "rails_helper"

RSpec.describe "Admin::Vendors", type: :request do
  let!(:vendors) {
    create_list(:vendor, 5, type: 1) do |vendor|
      create(:vendor_user, vendor_id: vendor.id, role: "vendor")
    end

    create_list(:vendor, 5, type: 2) do |vendor|
      create(:vendor_user, vendor_id: vendor.id, role: "vendor")
    end

    create_list(:vendor, 5, status: "waiting_for_approval") do |vendor|
      create(:vendor_user, vendor_id: vendor.id, role: "vendor")
    end

    create_list(:vendor, 5, status: "inactive") do |vendor|
      create(:vendor_user, vendor_id: vendor.id, role: "vendor")
    end
  }
  
  describe "index" do
    context "(success - display the list of vendors by vendor name asc)" do
      before { get "/api/v1/vendor_management/admin/vendors?sort_column=vendor_name&sort_by=asc", headers: headers[:auth] }

      it "returns list of vendors in asc order" do
        asc_vendor_names = json["vendors"].pluck("name")
        expect(json).not_to be_empty
        expect(json["vendors"]).not_to be_empty
        expect(response).to have_http_status(200)
        expect(asc_vendor_names).to eq(asc_vendor_names.sort)
      end
    end

    context "(success - display the list of vendors by vendor name desc)" do
      before { get "/api/v1/vendor_management/admin/vendors?sort_column=vendor_name&sort_by=desc", headers: headers[:auth] }

      it "returns list of vendors in desc order" do
        desc_vendor_names = json["vendors"].pluck("name")
        expect(json).not_to be_empty
        expect(json["vendors"]).not_to be_empty
        expect(response).to have_http_status(200)
        expect(desc_vendor_names).to eq(desc_vendor_names.sort.reverse)
      end
    end
  end

end

и по какой-то причине в 70% случаев в моем конвейере возникает этот сбой:

Failures:

  1) Admin::VendorManagement::VendorController index (success - display the list of vendors by vendor name desc) returns list of vendors in desc order
     Failure/Error: expect(desc_vendor_names).to eq(desc_vendor_names.sort.reverse)
     
       expected: ["Wyatt Conn", "Vikki Rowe VM", "Rocco Bauch", "Randal Muller", "Noe Koch", "Natashia Stark", "Miss L...oe Walter", "Dwain Stoltenberg", "Chara Orn", "Benito Hegmann", "Armida Kuphal", "Agustin Mosciski"]
            got: ["Wyatt Conn", "Vikki Rowe VM", "Rocco Bauch", "Randal Muller", "Noe Koch", "Natashia Stark", "Miss L...h Murazik", "Dwain Stoltenberg", "Chara Orn", "Benito Hegmann", "Armida Kuphal", "Agustin Mosciski"]
     
       (compared using ==)

Я не могу понять, что может быть причиной повреждения данных? как это решить? Спасибо!

вероятно, существует другая сортировка - в контроллере есть order(name: :asc) и сортировка, выполняемая sql, в тесте есть .sort и сортировка, выполняемая Ruby, поэтому, вероятно, сортировки различаются, в качестве решения вы можете создатьvendor_users с конкретными именами (не от фейкера), чтобы быть уверенным в порядке сортировки и, возможно, просто проверьте первый элемент (не весь список)

Anton Bogdanov 28.05.2024 13:47

Ваша нынешняя неудача - между "Старком" и "Столтенбергом". В настоящее время они имеют разные имена, что, исходя из кода, совершенно невозможно, поскольку вы сравниваете один и тот же список. Можете ли вы объяснить, как это происходит?

engineersmnky 28.05.2024 16:44

@engineersmnky именно мое замешательство! Я сортирую список ответов локально и сравниваю сам с собой! понятия не имею, как это происходит, более того - это происходит не локально, а только в моем кругообороте

RanH 29.05.2024 07:59

@AntonBogdanov Я не думаю, что это проблема с сортировкой, в основном потому, что это происходит только случайным образом и в моем конвейере cicd (никогда локально), в любом случае рекомендуется попробовать вставить значения вручную, я попробую, спасибо

RanH 29.05.2024 08:06
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

..., "Natashia Stark", "Miss L...oe Walter", "Dwain Stoltenberg", ...
..., "Natashia Stark", "Miss L...h Murazik", "Dwain Stoltenberg", ...

Но в чем же эта критическая разница между ...oe Walter и ...h Murazik? Какие значения на самом деле находятся в другом порядке и, следовательно, вызывают сбой?

Вы можете записать полные строки, чтобы точно увидеть, что изменилось. Я предполагаю, что это будет что-то вроде mr Tom... и Mr Bob..., где первая буква будет строчной.


В любом случае, неудачная строка в тесте:

expect(desc_vendor_names).to eq(desc_vendor_names.sort.reverse)

Я думаю, что единственный способ, которым это может потерпеть неудачу (если только не произойдет что-то действительно странное), заключается в том, что левая часть сортирует по алфавиту в SQL, а правая сторона сортирует по алфавиту в Ruby.

Почему это имеет значение? Потому что .sort Ruby основан на кодах UTF8, тогда как ваша база данных, вероятно, использует какие-то другие параметры сортировки. Это может привести к различным тонким различиям в порядке сортировки, если строки содержат символы с диакритическими знаками (é, ø, į, ...) или символы верхнего и нижнего регистра.

Например, учитывая строки: ['test 1', 'Test 2'], они (вероятно) будут отсортированы в другом порядке в Ruby и в базе данных.


Так как же можно исправить тест?

Я бы рекомендовал просто убедиться, что ваши фабрики/фикстуры/инициализатор используют имена, которые не вызовут проблем, т. е. ничего, что начинается со строчной буквы или «необычного» акцентированного символа, чтобы ваши порядки сортировки Ruby и SQL были такой же.

В качестве альтернативы вы можете использовать что-то более надежное, чтобы Ruby .sort вел себя так же, как SQL, например:

# probably good enough!
.sort_by(&:downcase)

# Also accounts for most accented character issues:
.sort do |a, b|
  I18n.transliterate(a.downcase) <=> I18n.transliterate(b.downcase)
end

# Hardcore solution:
https://github.com/ninjudd/icunicode

Спасибо @Tom Lord, я добавил журналирование в тесты и обнаружил проблему - каждый раз, когда Faker создавал имена с помощью "." (точки) сортировка пошла не так, как было предложено - сортировка SQL и сортировка Ruby отдали приоритет "." разные (один больше алфавита, другой меньше). На самом деле я решил эту проблему, обновив инструкцию Faker следующим образом: name { Faker::Name.name.gsub(/\W/, '').gsub("\u0000", '') }

RanH 17.06.2024 10:37

Другие вопросы по теме