Sep/090
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
Sep/090
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.