اختبار القضبان :: اختبار الوحدة للتحقق من صحة النموذج بطيء بشكل مدهش - I18n؟
-
02-01-2020 - |
سؤال
لدي اختبار بسيط في تطبيق Rails الخاص بي والذي يستغرق دائمًا وقتًا أطول بكثير من الاختبارات الأخرى المشابهة ظاهريًا.
يستغرق التشغيل من 1 إلى 2 ثانية من الوقت الحقيقي test_invalid_without_name
على النحو التالي:
VALID_PARAMS = { name: 'Client record' }
def test_invalid_without_name
c = Client.new(VALID_PARAMS)
c.name = nil
refute c.valid?, 'should not be valid without a name'
end
الاختبار القادم , test_valid_with_all_params
يستغرق أقل من 1/100 من الثانية:
def test_valid_with_all_params
c = Client.new(VALID_PARAMS)
assert c.valid?, 'should be valid with appropriate parameters'
end
نموذج العميل واضح تمامًا في هذه المرحلة:
class Client < ActiveRecord::Base
belongs_to :entity, polymorphic: true
validates :name, presence: true
end
هل يمكن لأي شخص اكتشاف الخطأ هنا، أو إعطائي فكرة عن المكان الذي يجب أن أبحث فيه بعد ذلك لمحاولة اكتشاف ذلك؟
تحديث 1
لقد استخدمت روبي البروفيسور لملف تعريف الكود، ويبدو أنه يتم قضاء الكثير من الوقت في نفسية جوهرة.أعتقد أن هذا يستخدم في ActiveRecord::..#serialize
, ، والذي أستخدمه في نموذج آخر على النحو التالي:
class Opportunity < ActiveRecord::Base
belongs_to :client
serialize :details, Hash
end
ومع ذلك، إزالة المكالمة إلى serialize
هنا لا يحدث أي فرق في اختبارات العميل (ولا أستطيع أن أرى سبب ذلك، فالفئتان مرتبطتان، ولكن لا يتم إنشاء فرص في اختبار العميل).
تحديث 2
تبين أنه يتم استدعاء Psych لأن I18n يستخدمه.افتراضي في هذه المرحلة هو أن فشل التحقق من الصحة يتسبب في انتقال I18n إلى الملفات المحلية لسحب رسالة خطأ.سأنظر في التخلص من I18n للاختبار ...
المحلول
اتضح أن الطريقة المناسبة لحل هذه المشكلة هي استخدام Ruby-prof على النحو التالي.
أضف إلى Gemfile (في ملف development
مجموعة):
gem 'ruby-prof'
لف رمز الاختبار في المكالمات إلى منشئ ملفات التعريف:
def test_invalid_without_name
RubyProf.start
cr = Client.new(VALID_PARAMS)
cr.name = nil
refute cr.valid?, 'should not be valid without a name'
result = RubyProf.stop
printer = RubyProf::CallStackPrinter.new(result)
printer.print(File.open(File.join(Rails.root, 'profile_invalid_without_name.html'), 'w'))
end
سيؤدي هذا إلى إنشاء مستند HTML تفاعلي في جذر تطبيق Rails الخاص بك، والذي يوضح تفاصيل المكان الذي يقضيه الوقت.
في هذه الحالة، كانت نسبة 80%+ في I18n تبحث عن ترجمات.أضفت السطر التالي إلى config/environments/test.rb
لإيقافه في الاختبار:
I18n.backend = I18n::Backend::KeyValue.new({})
من المحتمل أن أقوم بإجراء التحسينات الإضافية التالية في المستقبل:
كن أكثر تحديدًا فيما يتعلق بالمكان الذي أقوم فيه بإخراج I18n، حتى تتمكن اختبارات القبول الكاملة للمكدس من استخدام الشيء الحقيقي.
اكتب نهجًا أكثر ملاءمة للتوصيف.يبدو أن Ruby-prof يقدم آليات أخرى مختلفة لتنشيطه، وكان هذا أبسط للاستخدام الأولي.
نصائح أخرى
ليس من الممكن الإجابة على السؤال دون مزيد من المعلومات.
- هل يحدث هذا عند إجراء كل اختبار على حدة؟
- هل لديك أي شيء في الإعداد/التفكيك أو test_helper.rb الخاص بك؟
- هل يحدث ذلك إذا قمت بتمرير تجزئة بالاسم => nil بدلاً من تعيينها؟
- هل قمت بإعادة تعريف واضعة الاسم؟
- هل لديك أي رد اتصال على النموذج الخاص بك؟