conferencia rails: integracion continua y rails
DESCRIPTION
TRANSCRIPT
Integración Continua y Rails
David Calavera11870.com
ego slide
• desarrollador en 11870.com
• open source: Hudson, Netbeans
• commiter de la Fundación Apache
sobre mi
sobre la charla
sobre que
NO trata esta charla
Texto
nada que nos enganche
más a Rails
como configurar
un servidor de CI
sobre que trata esta charla
usar menos herramientas
automatizar tareas
calidad del código
¿qué es integración continua?
practica de reunir el código que estamos desarrollando frecuentemente, para verificarlo y evitar errores
“
”David Calavera
Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily - leading to multiple integrations per day. Each integration is verified by an automated build (including test) to detect integration errors as quickly as possible. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly.
“
”Martin Fowler
¿para qué sirve?
reducir riesgos
falta de cohesión
descubrir errores pronto
http://www.agitar.com/solutions/why_unit_testing.html
baja calidad del código
evitar repetir
procesos manuales
generar deploys
en cualquier momento
automatizar el build
• reducir el número de procesos manuales
• ¡¡Rails incorpora 71 tareas a ejecutar!!• rake --tasks --silent | wc -l
• ¡¡Capistrano añade 22 tareas más!!• expr `cap --tasks | wc -l` - 7
¡¡autodestrucción!!
reducir su duración
• usar una máquina dedicada para CI
• mejorar el rendimiento de nuestros tests
• separar los tests por categorías
• ejecutar el build por etapas
ejecutar los test en paralelo
• sudo gem install deep_test
DeepTest::TestTask.new 'deep_test:functionals' do |t| t.pattern = "test/functional/**/*_test.rb" t.number_of_workers = 2end
ejecutar los test en paralelo
• también para RSpec
Spec::Rake::SpecTask.new 'deep_spec:functionals' do |t| t.spec_files = FileList['spec/functional/**/*_spec.rb'] t.deep_test :number_of_workers => 2end
ejecutar los test en paralelo
• ¡con una base de datos para cada worker!
DeepTest::TestTask.new 'deep_test:functionals' do |t| t.pattern = "test/functional/**/*_test.rb" t.worker_listener = 'DeepTest::Database::MysqlSetupListener'end
usar un servidor de CI
• preguntar por cambios en el repositorio
• realizar acciones en horarios determinados
• soportar diferentes herramientas
• mostrar builds históricos
• soportar diferentes tipos de informes
• soportar diferentes tipos de notificaciones
CruiseControl.rb
CruiseControl.rb
• muy POCO “user friendly”
• plugins perdidos por internet
• pero muy fáciles de desarrollar
• http://cruisecontrolrb.thoughtworks.com
Hudson
Hudson
• MUY “user friendly”
• plugins muy fácilmente localizables
• pero algo más complicado de desarrollar
• http://hudson.dev.java.net
Run Code Run
•
Run Code Run
• de momento solo proyectos open source
• de momento solo se integra con github
• soporte de CI para la última Rails Rumble
• http://runcoderun.com
mejorar la perspectiva
aumentar la confianza
¿cuáles son las reglas básicas?
commit frecuente
no subir
código roto
arreglar el build
inmediatamente
escribir test automáticos
hacer builds en local
evitar usar código roto
¿qué pasos hay que seguir para
montar un sistema de CI?
1. integración de la base de datos
lo que hay que hacer
• automatizar los cambios de la base de datos• crear la base de datos
• modificar la base de datos
• testing e inspección
Migraciones
• muchas mejoras desde Rails 2.1create db/migrate/20081112232842_modify_user.rb
class ModifyUser < ActiveRecord::Migration def self.up change_table :user do |user| t.rename :surname, :last_name t.remove :age ... end endend
2. Testing continuo
test unitarios
• enfocados en un objeto
• comprobar que es totalmente unitario• sudo gem install unit_record
• usar mocks en lugar de fixtures
ActiveRecord::Base.disconnect!
test unitarios
• ¡¡hay que hacerlos para cualquier clase!!• sudo gem install unit_controller
def setup @controller = UserController.new @controller.do_not_render_vewend
test funcionales
• usa factories en lugar de fixtures• sudo gem install thoughtbot-factory_girl
Factory.define :user do |u| u.first_name 'Joe' u.last_name 'Doe' u.email {|att| "#{att.first_name}@example.com".downcase }end
test funcionales
• ¡¡hay que hacerlos para todas las clases!!• interacción entre el modelo y la base de datos
• interacción entre el modelo y el controlador
• interacción entre el controlador y la vista
3. Inspección continua
reducir la complejidad
• Flog
def flog(output, *directories) `find #{directories.join(" ")} -name \\*.rb|xargs flog > #{RAILS_ROOT}/tmp/flog/#{output}.txt`end
desc "Flog models, controller, helpers and lib"task :flog do flog "all", *%w[app/models app/controllers app/helpers lib]end
eliminar código duplicado o sin usar
• Dust
def unused_lvar a = 1 1 + 2end d = Dust::LocalVariableDuster.new(Object, :unused_lvar)d.dust!d.warnings
eliminar código duplicado o sin usar
• PMD-CPD
def cpd(*directories) `java net.sourceforge.pmd.cpd.CPD --minimum-tokens 100 -files #{directories.map(" --files ")} --language ruby`endtask :cpd do cpd *%w[app/models app/controllers app/helpers lib]end
comprobar cobertura
• Rcovdesc 'Test coverage report'task :coverage do rm_f "coverage" rm_f "coverage.data" rcov = "rcov --rails --aggregate coverage.data -Ilib" `#{rcov} --no-html test/unit/*_test.rb` `#{rcov} --no-html test/functional/*_test.rb` `#{rcov} --html test/integration/*_test.rb` `open coverage/index.html` if PLATFORM['darwin']end
all in one
• Metrics_fu para cruisecontrol.rb• Saikuro
• Flog
• Rcov
• Rails stats
• RubyMetrics para hudson• Rcov
• Rails stats
revisión de código
4. Deploy continuo
deploy continuo
• etiquetar el repositorio
• producir un entorno limpio
• etiquetar cada build
• tener la capacidad de volver atrás
5. Feedback continuo
feedback continuo
• la información correcta
• a la persona indicada
• en el momento esperado
• de la forma correcta
¿alguna pregunta?
Fotos• http://flickr.com/photos/chicanerii/507573394
• http://flickr.com/photos/3epmedia/1160364177
• http://flickr.com/photos/cathycracks/183170786
• http://flickr.com/photos/smitty/2245445147/
• http://flickr.com/photos/fcw/384316867/
• http://www.flickr.com/photos/auxesis/2965947278/
• http://www.flickr.com/photos/penguin_man44/1203331011/
• http://flickr.com/photos/rekha6/2902282813/
• http://flickr.com/photos/teepee1/1508261796/
• http://flickr.com/photos/teepee1/2614839885/
• http://flickr.com/photos/_saturnine/2294717858/
• http://flickr.com/photos/ezra/459279198/
• http://flickr.com/photos/x180/1397019888
• http://flickr.com/photos/soulcheck/384769773/
• http://flickr.com/photos/znachor/255143511/
• http://flickr.com/photos/julianbleecker/156303245/