Pregunta

Tengo una prueba sencilla en mi aplicación Rails que siempre lleva mucho más tiempo que otras pruebas aparentemente similares.

Se necesitan de 1 a 2 segundos de tiempo real para ejecutarse. test_invalid_without_name como a continuación:

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

La próxima prueba, test_valid_with_all_params tarda menos de 1/100 de segundo:

def test_valid_with_all_params
  c = Client.new(VALID_PARAMS)
  assert c.valid?, 'should be valid with appropriate parameters'
end

El modelo de Cliente es totalmente sencillo en esta etapa:

class Client < ActiveRecord::Base

  belongs_to :entity, polymorphic: true

  validates :name, presence: true

end

¿Alguien puede detectar lo que está mal aquí o darme una idea de dónde debería buscar a continuación para intentar resolverlo?

Actualización 1

He usado ruby-prof para perfilar el código, y parece que gran parte del tiempo se pasa en el Psicoanalizar joya.Creo que esto se usa en ActiveRecord::..#serialize, que estoy usando en otro modelo de la siguiente manera:

class Opportunity < ActiveRecord::Base
   belongs_to :client 
   serialize :details, Hash
end

Sin embargo, eliminar la llamada a serialize aquí no hay ninguna diferencia en las pruebas del Cliente (y no veo por qué lo haría, las dos clases están asociadas, pero no se crean instancias de Oportunidades en la prueba del Cliente).

Actualización 2

Resulta que se llama a Psych porque I18n lo está usando.Mi suposición en este punto es que la validación fallida hace que I18n vaya a los archivos locales para mostrar un mensaje de error.Buscaré apagar I18n para realizar pruebas...

¿Fue útil?

Solución

Resulta que un enfoque adecuado para resolver este problema fue utilizar Ruby-prof de la siguiente manera.

Agregar a Gemfile (en el development grupo):

gem 'ruby-prof'

Envuelva el código de prueba en llamadas al generador de perfiles:

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

Esto creará un documento HTML interactivo en la raíz de su aplicación Rails, que muestra el desglose de dónde se dedica el tiempo.

En este caso, era más del 80% en I18n buscando traducciones.Agregué la siguiente línea a config/environments/test.rb para apagarlo en la prueba:

  I18n.backend = I18n::Backend::KeyValue.new({})

Probablemente haré las siguientes mejoras adicionales en el futuro:

  1. Sea más específico con respecto a dónde eliminé I18n, para que las pruebas de aceptación de pila completa puedan utilizar el sistema real.

  2. Escriba un enfoque de creación de perfiles más conveniente.Parece que ruby-prof ofrece varios otros mecanismos para activarlo, este fue el más simple para el uso inicial.

Otros consejos

No es posible responder a la pregunta sin más información.

  • sucede esto cuando ejecuta cada una de las pruebas individualmente?
  • ¿Tiene algo en la configuración / remonte o su test_helper.rb?
  • sucede si pasa un hash con nombre=> nil en lugar de configurarlo?
  • ¿Redefinió el conjunto de nombre?
  • ¿Tiene alguna llamada de devolución de llamada en su modelo?
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top