Académique Documents
Professionnel Documents
Culture Documents
Référence : nt_ums3365_guide-developpement-logiciels_promise
Auteur : P. Payet, F. Gabarrot
Nombre de pages : 19
Historique des évolutions
Date Description Section affectée
31/07/2014 Création.
07/12/2015 Nouvelle édition du document par P. Payet.
Le processus de développement suit des conventions, pour faciliter la vie du programmeur et lui
permettre de rester AGILE. Dans la suite du document, nous détaillerons l’environnement de
développement du projet avec les conventions et outils adoptés.
Ce document s'adresse à toutes les personnes de l'équipe projet ou à toute personne souhaitant
apporter sa collaboration.
Contact :
osureunion-informatique@univ-reunion.fr
Un login et un mot de passe d'accès est nécessaire pour l'accès aux projets sur ces deux forges.
Vérifier que la version de python que vous utiliser est bien la 2.7 par défaut :
$ python --version
Python 2.7.6
Si ce n'est pas le cas, vous devez faire pointer le lien symbolique /usr/bin/python vers
/usr/bin/python2.
Installer un environnement virtuel python pour chaque librairie en cours de développement. Ici nous
utiliserons un environnement virtuel commun pour toutes les librairies de développment.
sudo pip install virtualenvwrapper
printf '\n# Load virtualenvwrapper module\nsource /usr/local/bin/virtualenvwrapper.sh'
>> ~/.bashrc
source ~/.bashrc
mkvirtualenv promise
Pour que l'installation des dépendances de chaque librairie aboutisse, il faut installer plusieurs
paquets au préalable :
sudo apt-get install python-wxgtk2.8 libxml2-dev libxslt1-dev lib32z1-dev cython
python3-dev gfortran libblas3 libblas-dev liblapack3 liblapack-dev libhdf5-dev
libpng12-dev libfreetype6-dev libnetcdf-dev tcl-dev tk-dev python-tk python3-tk
Activer/désactiver un environnement
$ workon
toto
promise
ubber_project
$ workon promise
(promise) $ python –version
Python 2.7.6
(promise) $ deactivate
$ workon toto
(toto) $ python –-version
Python 3.5.0
5.2.1 Nose
En programmation agile, il faut tester son code. Pour cela, on utilise un framework de test: nose. Il
se base sur la librairie unittest est se définit lui même comme un “nicer testing for python”. Il
permet d'écrire des tests rapidement avec une syntaxe simplifié par rapport à unittest et surtout de
trouver automatique tous les tests à exécuter. Fini la maintenance du script shell qui doit exécuter
tous les tests. Il suffit de respecter la syntaxe de détection de nose pour que le framework les
exécute.
Si vous êtes habitué à écrire vos tests avec unittest et ne voulez pas apprendre une syntaxe plus
simple et plus lisible, c'est possible! nose est effet capable de lire aussi bien les tests écrit avec la
syntaxe de unittest que ceux écrit avec sa propre syntaxe.
Comme expliqué précédemment, les tests se trouvent dans le répertoire test/ à la racine du projet.
noseva chercher tous les fichiers ou répertoire détecter par cette expression régulière (?:^|
[\\b_\\.-])[Tt]est
$ tree test/
test/
├── test_module1
│ └── test_module1.py
├── test_module2
│ └── test_module2.py
└── test_package.py
A l'intérieur des ces fichiers, il va ensuite chercher toutes les fonctions ou classes à l'intérieur de ces
fichiers ayant une correspondance avec l'expression régulière précédante.
def test_lower_bound_function_to_test1():
expected_value = None
assert test_function_to_test1(-1) == expected_value
def test_wrong_file_function_to_test2():
expected_value = IOError
filepath = '/wrong_path_to_test/file.txt'
try:
function_to_test2(filepath)
except Exception as e:
assert (e.__cause__, IOError)
Lorsque tous les tests sont écrits, on utilise la commande nosetests pour les exécuter.
5.2.2 Tox
Ce module python sert à automatiser les tests. Il est compatible avec de nombreux framework de
test python (nose, unittest, pytest). Son installation est très simple:
$ pip install tox
Pour l'utiliser il faut configurer un fichier tox.ini à la racine du projet.
Un avantage de ce module est qu'il peut s'exécuter localement pour lancer la batterie de tests et
d'environnement virtuel et peut aussi être utiliser par un serveur d'intégration (ex: Jenkins). Le
développeur peut donc lancer les mêmes tests qui vont être éxécuter par le serveur d'intégration
continue à chacun de ses push. Une bonne pratique à mettre place par chaque développeur afin de
ne pas être innondé de mail d'erreurs par la suite.
6.2 Le versionning
Format X.Y.Z :
• X : nombre entier correspondant à l'édition principale du logiciel. On l'incrémente lorsqu'on
réalise une évolution majeure du logiciel (révolution!). X=0 est réservé à des versions
prototypes ou encore instables et/ou non finalisées. X=1 est la première version stable.
• Y : nombre entier correspondant au numéro de révision. On l'incrémente quand on
implémente des nouvelles fonctionnalités ou bien quand on les améliore, ou encore quand
on corrige des grosses boulettes.
• Z : nombre entier correspondant à un numéro de correctif. C'est pour de la petite boulette.
#- ---------------------------------------------------------------------
## @file logerr.py
## @defgroup logerr logerr ←- pratique pour définir un module
## @brief Manage log, log file, traceback and exception
## @author Franck GABARROT,
## @date 2014
## @copyright CECILL-B
## @note
##- 2014/04/04: creation.
#- ---------------------------------------------------------------------
# ---------------------------------------------------------------------
# @brief Create logger and create or open (if already exists) log file.
# @param[in] directory Log directory.
# @param[in] modulename Module name.
# @param[in] datetime String date and time information to add to the
# filename : modulename_datetime.log. Default: no datetime string.
# @param[in] rotate Log file automatic rotating file greating than maxsize,
# default: no rotating mode.
# @param[in] maxbytes Max file size for automatic rotating file (byte),
# default: 1 Gbyte.
# @param[in] backupcount Max number of log files archived.
# @return Logger object from python-logging module. Return None if an
# error occurs.
# @ingroup logerr
#- ---------------------------------------------------------------------
def createLogger(directory, modulename, datetime=None, rotate=False, maxbytes=1000000,
backupcount=10):
"""Create logger and create or open (if already exists) log file.
"""
logger=None
Le développeur se doit de tester son code au niveau unitaire mais aussi la manière dont son code
s'intègre dans l'ensemble du projet. De même, la qualité du code doit être la plus constante possible
mais. L'éxecution de tous ces tests peut prendre un certain temps et c'est là qu'intervient la
plateforme d'intégration continue. Elle va s'occuper d'exécuter tous l'ensemble des tests permettant
de vérifier la qualité, les fonctions et l'intégration du code.
Nous utilisons ici Jenkins CI accessible à l'adresse suivante (serveur interne) :
http://10.82.61.249:8080
Figure 1: Vue principale de Jenkins CI résumant l'ensemble des jobs et leur état.
Dans un soucis d'économie de ressources physiques, les builds générés par Jenkins sont exécutés
au sein de conteneurs Docker (REST API 10.82.61.249:4243). L'ensemble de la sortie standard est
conservé dans la section « Console Output » de chaque build.
Actuellement, un e-mail de notification sera envoyé à chaque fois qu'un build aura échoué ou
qu'un job passe du statut instable ou statut stable à tous les développeurs du code pushé.
Lorsqu'on ajoute un nouveau job à Jenkins, il faut créer un environnement de test correspondant.
Si l'environnement est sur windows il faudra créer une machine virtuelle mais si celui ci est sur
Linux, on utilisera un conteneur Docker. Ce conteneur doit refleter l'installation réelle du projet sur
un environnement vierge.
Ajouter une image slave dans Docker
Pour cela vous devez créer un Dockerfile. Vous pourrez trouver des exemples de ce fichier dans
les dépôts.
Jenkins a besoin de savoir comment récupérer le code dans la section Source Code Management.
Les identifiants qui permettent à Jenkins de se connecter au gitlab portent le label « git » :
Pour que l'ensemble des tests soient exécuter à chaque push sur le dépôt, configurer les triggers :
Finalement, ajouter une notification par e-mail dans les actions post-build :