25
Sep/09
0

Automatisation des microtests Erlang via Rake

Les fonctions de tests unitaires commencent à apparaitre dans plusieurs fichiers, et il devient nécessaire de pouvoir régulièrement rejouer l’ensemble de ces tests. Ceci ne pouvant se faire que de manière automatique pour être efficace.

Attention on rappelle qu’il ne s’agit ici que de vérifier simplement et rapidement des comportements écrits directement dans les fichiers sources. Il est évident que pour des opérations plus complexes, un réel outil de tests unitaires tel que eUnit devra être mis en place.

Pour cela, on va réutiliser ce que l’on a déjà mis en place précédemment concernant l’exécution de la machine virtuelle Erlang via Rake (voir posts précédents).

Le but est de parcourir l’ensemble des fichiers sources .erl et déterminer pour chacun d’eux si une fonction tes/0 a été définie, auquel cas on exécute la méthode du module en question.

L’analyse du fichier sera une bête expression régulière, et pour cela on patch la classe File de Ruby afin de conserver une certaine harmonie dans l’écriture :

class File
  def self.contains?(filename, regexp)
    text = File.read filename
    return text.match(regexp) != nil
  end
end

Pas très efficace comme programmation mais nous ne sommes concernés que par des fichiers sources qui sont, par définition, des fichiers textes de petite taille.

On crée alors une tâche Rake :

desc "Unit tests"
task :test => :compile do
  sources.each do |source|
    if File.contains? source, /^test\(\) ->$/
      mod = File.basename(source, ".erl")
      puts "Unit testing #{mod}"
      system "erl -pa #{EBIN_DIR} #{ROOT}/deps/*/ebin -noshell -noinput -s inets -s crypto -s #{mod} test -s init stop"
    end
  end
end

Cette tâche dépend de la compilation afin de pouvoir jouer les fonctions.

On a repris la commande système utilisée pour lancer l’application. Certains paramètres ont été ajoutés :

-noshell -noinput # Exécution en mode console non interactive
-s inets -s crypto # Démarrage de modules nécessaires, ici crypto est lié aux cookies
-s #{mod} test # Exécution de la fonction test() du module mod
-s init stop # Arrêt de la machine virtuelle
18
Sep/09
0

Calcul de distances et tests unitaires

Le système nécessite un calcul de distances approximatif entre 2 points. Pour cela, on récupère le calcul théorique sur internet (par exemple, ici).

La transformation en distance est une reprise tel que des algorithmes :

distance(Coord1, Coord2) ->
  {Lat1, Lon1} = Coord1,
  {Lat2, Lon2} = Coord2,
  AngularDist = math:acos(
                 math:sin(Lat1 * math:pi() / 180) * math:sin(Lat2 * math:pi() / 180) +
                 math:cos(Lat1 * math:pi() / 180) * math:cos(Lat2 * math:pi() / 180) *
                 math:cos((Lon2 - Lon1) * math:pi() / 180)),
  AngularDist * 6371. %% km

Les coordonnées sont passées pour l’instant sous la forme d’un tuple comprenand la latitude et la longitude.