De la documentation au tests, Ruby fourmille d’outils qui aide les développements au quotidien. Cette liste n’est pas exhaustive mais je penses qu’elle permet d’avoir un bon aperçu. Cette liste est largement inspirée de l’article anglais http://www.caliban.org/ruby/rubyguide.shtml.
Interactive Ruby - irb
Package Debian : irb
Petit shell permettant d’exécuter du Ruby en ligne de commande. On peut activer l’autocomplétion avec
% irb -r irb/completion
Ruby Interactive
Package Debian : ri
Outil de documentation sur les classes Ruby :
% ri Hash
ou sur les méthodes (ici # signifie méthode d’instance) :
% ri 'Array#<<'
Ruby Debugger
Ruby vient avec un debugger intégré qui va vous permettre d’avancer pas à pas dans votre programme :
% ruby -r debug test.rb
Debug.rb
Emacs support available.
test.rb:1:2.times do |i|
(rdb:1)
Ensuite, tapez ’help’ pour une liste des commandes disponibles (step, break, ...)
Benchmark
Vous pouvez utiliser le module "benckmark" qui va vous permettre de tester facilement les performances de différents codes. Par exemple, testons différentes manières d’assigner une clef à une variable dans une boucle :
require "benchmark"
n=1_000_000
Benchmark.bm do |x|
x.report { for i in 1..n do a="test"; end };
x.report { for i in 1..n do a=:test; end };
x.report { n.times do a=:test; end };
a=""
x.report { n.times do a=:test; end };
end
Dans le premier, on utilise une boucle "for" et on assigne une String. Dans le second, on assigne un symbole, ce qui devrait être moins coûteux, ne serait qu’en consommation de mémoire (:test est toujours le même objet, alors que "test" est réalloué à chaque itération). Dans le troisième, on utilise une boucle "times". Enfin, dans le dernier, on déclare la variable à l’extérieur du bloc itératif.
% ruby symbol_vs_strings.rb
user system total real
1.670000 0.330000 2.000000 ( 2.153955)
1.230000 0.410000 1.640000 ( 1.754586)
0.950000 0.240000 1.190000 ( 1.243530)
0.890000 0.180000 1.070000 ( 1.144817)
On a quasiment doublé la performance.
Profiling code
Il existe également un module capable de donner des statistiques d’utilisation du code : "profile" :
class Dog
def bark
puts "Wouf!"
end
def initialize
puts "a Dog is born"
bark
end
end
Dog.new.bark
% ruby -r profile testProfiling.rb
a Dog is born
Wouf!
Wouf!
% cumulative self self total
time seconds seconds calls ms/call ms/call name
0.00 0.00 0.00 1 0.00 0.00 Dog#initialize
0.00 0.00 0.00 2 0.00 0.00 Module#method_added
0.00 0.00 0.00 2 0.00 0.00 Dog#bark
0.00 0.00 0.00 1 0.00 0.00 Class#inherited
0.00 0.00 0.00 3 0.00 0.00 Kernel.puts
0.00 0.00 0.00 1 0.00 0.00 Class#new
0.00 0.00 0.00 6 0.00 0.00 IO#write
0.00 0.01 0.00 1 0.00 10.00 #toplevel
Test Units
Vous pouvez consulter la documentation de Test ::Unit. On va prendre une classe en exemple :
class Comptable
def initialize(tva=19.6)
raise "Not a number" if !tva.is_a? Numeric
@tva=tva
end
def average(numbers)
total=numbers.inject {|sum, n| sum + n }
total / numbers.length
end
def ttc(ht)
ht+ht*@tva/100.0
end
end
#puts Comptable.new.average([1,2,3,4,5,6.0])
#puts Comptable.new(5.5).ttc(19.90)
On exécute le script :
% ruby Comptable.rb
3.5
20.9945
On écrit un TestCase correspondant pour tester notre classe. Cela consiste principalement à vérifier ce que la classe doit faire avec des exemples pratiques. Ici, on va vérifier les calculs pour average et ttc, puis on va vérifier le mécanisme d’exception. Ces tests font partie d’une classe de test qui étend Test ::Unit ::TestCase. Il est important de noter que l’on dispose d’une méthode setup et teardown pour initialiser et finaliser des actions :
require 'test/unit'
require 'Comptable'
class TC_Comptable < Test::Unit::TestCase
def setup
@comptable=Comptable.new(20)
end
#def teardown
#end
def test_average
assert(3,@comptable.average([2.5,3.5]))
end
def test_ttc
assert(120.0,@comptable.ttc(100))
end
def test_validation
assert_raise (RuntimeError) { Comptable.new("toto") }
assert_nothing_raised { Comptable.new(4) }
end
end
% ruby testTestUnit.rb
Loaded suite testTestUnit
Started
...
Finished in 0.001643 seconds.
3 tests, 4 assertions, 0 failures, 0 errors
Les tests passent :)
Ressources
Un guide Ruby non officiel en anglais.
Un tutoriel sur Ruby Debug