У меня на моем 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 ==)
Я не могу понять, что может быть причиной повреждения данных? как это решить? Спасибо!
🤔 А знаете ли вы, что...
Ruby on Rails активно соблюдает принцип REST (Representational State Transfer) для построения веб-сервисов.
На этот вопрос сложно дать конкретный ответ, поскольку в вашем вопросе отсутствует ключевая информация. В частности, в сообщении об ошибке говорится:
..., "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