Accueil ⇒ Projets ⇒ Algotest

Algotest

Principe

Les deux scripts suivants permettent de comparer les résultats d'un programme sur un jeu de fichiers passés en entrée (stdin) avec un jeu de fichiers de sortie pré-définis. Le premier exécute les différents tests tandis que le second compare la sortie obtenue avec celle attendue. Vous pouvez retrouver les scripts sous forme de fichiers à télécharger dans le dossier suivant.

Exécution des tests

L'exécution des tests passe par un simple script shell sans réelle difficulté. Les fichiers d'entrée doivent porter l'extension .in et les fichiers de sortie associés doivent avoir le même nom, à la seule différence de l'extension qui doit être .out. Pour pouvoir exécuter ce script, vous devez disposer des outils suivants :

#!/bin/sh
 
# Réglages
TMP=~/.algotest
 
# Traductions
MSG_OK = "Sortie correcte."
MSG_ERR = "Sortie incorrecte."
MSG_YA = "La sortie :"
MSG_CA = "Sortie attendue :"
SEP="--"
 
echo;
for CURTEST in *.in; do
	echo -n "${CURTEST} :	";
	time $1 < ${CURTEST} > ${TMP};
	if algotest-check.pl ${TMP} `echo "${CURTEST}" | sed s/.in/.out/g`;
	then
		echo ${MSG_OK};
	else
		echo ${MSG_ERR};
		echo;
		echo ${MSG_YA};
		echo ${SEP};
		cat $TMP;
		echo ${SEP};
		echo ${MSG_CA};
		echo ${SEP};
		cat `echo "${CURTEST}" | sed s/.in/.out/g`;
		echo ${SEP};
	fi
	echo;
done
 
# Nettoyage
rm -f $TMP

Comparaison des fichiers

On aurait pu utiliser l'outil diff pour exécuter cette seconde tâche, mais ces scripts sont conçus pour comparer les sorties ligne à ligne (comme dans certaines olympiades internationales) ce qui autorise certaines largesses délicates à implémenter avec diff.

#!/usr/bin/perl
 
use strict;
 
# Déclaration des données
my ($CANDIDAT, $SOLUTION);
my ($canChar, $solChar) = ('4', '2');
my %separators = (
    ' '  => 1,
    '\n' => 1,
    '\r' => 1
);
 
# Ouverture des fichiers
open $SOLUTION, $ARGV[0]
    or die("Erreur a l'ouverture du fichier solution.");
open $CANDIDAT, $ARGV[1]
    or die("Erreur a la lecture de la sortie du programme.");
 
# Comparaison des caractères deux à deux
while ($canChar ne '' && $solChar ne '') {
    do {
        $canChar = getc $CANDIDAT;
    } while ($separators{$canChar});
    do {
        $solChar = getc $SOLUTION;
    } while ($separators{$solChar});
    if ($canChar ne $solChar) {
        exit 1;
    }
}
 
# Clôture
close $CANDIDAT;
close $SOLUTION;
exit 0;

Conclusion

Voilà pour ces deux scripts (codés en 2005) qui, malgré leur petite taille, peuvent se révéler assez utiles lorsqu'il s'agit de traiter un grand volume de données. Vous pouvez aussi retrouver les scripts sous forme de fichiers à télécharger dans le dossier suivant.