Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici

Scala Build Tool

Définition

sbt (Scala Build Tool) est l’outil de gestion et de construction de projet le plus utilisé en Scala, utilisable également en Java.

Grâce au fichier build.sbt, on peut configurer son projet et le compiler de façon incrémentale grâce aux informations extraites du compilateur. Il propose de nombreuses fonctionnalités comme le packaging, la publication ou encore le lancement des tests d’un projet.

En plus des fonctionnalités classiques, sbt propose également de construire son projet sur de multiples versions de Scala.

Installation

Avant de pouvoir installer sbt, un JDK est nécessaire. Le site officiel recommande d’installer la version 8 ou 11. Pour installer sbt, on peut télécharger le .zip ou le .tgz disponibles sur la page officielle puis suivre les étapes d’installation.

Il est préférable d’opter pour un gestionnaire de paquets propre à son système d’exploitation pour pouvoir gérer les versions plus efficacement.

1. Sur Mac/Linux

a. Homebrew

brew est un utilitaire de paquets disponible sur Linux et Mac. Il permet d’installer les paquets disponibles dans sa librairie avec cette commande :

$ brew install sbt 

On ne peut pas récupérer simplement une version spécifique d’un programme ; brew installe toujours la dernière version d’un programme à condition que le code Github de Homebrew ait été mis à jour.

Les programmes sont installés directement dans le dossier d’installation de brew et des liens symboliques vers le dossier /usr/local sont créés.

$ find / -type d -name sbt 
/usr/local/Cellar/sbt 
 
$ ls -l /usr/local/bin 
sbt -> ../Cellar/sbt/1.3.13/bin/sbt 

b. SDKMAN!

SDKMAN! est un utilitaire de paquets disponible sur Linux, Mac et Windows. Il permet d’installer les paquets disponibles dans sa librairie avec cette commande :

$ sdk install sbt 

Les programmes sont installés...

Création d’une application

1. Architecture du projet

sbt utilise une architecture similaire à Maven pour les fichiers source en remplaçant le dossier java par le dossier scala.

build.sbt 
project/ 
src/ 
-- main/ 
  |-- resources/ 
  |-- scala/ 
|-- test/ 
  |-- resources/ 
  |-- scala/ 
target/ 

On retrouve des dossiers src et test pour les classes de production et de tests. L’équivalent du pom.xml est le fichier build.sbt contenant toutes les informations nécessaires pour compiler le projet. Le dossier target contient toutes les classes compilées et le dossier project des fichiers utilitaires.

Si vous travaillez dans un projet git, il est conseillé d’inclure le dossier target/ dans le .gitignore.

2. Définition de construction

a. Définition de la version de sbt

Tout d’abord, pour déterminer quelle version de sbt utiliser pour compiler le projet, il faut la spécifier dans un fichier de configuration. Pour cela, on inscrit dans le fichier build.properties présent dans le dossier project les informations suivantes :

sbt.version=1.3.13 

Si la version spécifiée n’est pas présente sur le poste, elle sera téléchargée par le lanceur sbt.

Si le fichier build.properties n’existe pas, l’application pourra tout de même être lancée mais dans une version arbitraire. Il est donc recommandé de toujours spécifier ce fichier pour éviter des erreurs de compilation et pour s’assurer d’avoir un même environnement de travail sur tous les postes.

b. Fichier build.sbt

Avec sbt, la définition de construction est définie dans le fichier build.sbt et correspond à la définition d’un ou plusieurs projets de type Project.

La définition d’un projet se fait en spécifiant le dossier dans lequel se trouvent les sources, par défaut le dossier courant et trois informations par défaut : le nom et la version du projet et la version de Scala à utiliser. Chaque paramètre se définit avec une clé et une valeur séparées par l’opérateur :=.

Cela donne le résultat suivant :

lazy val projet = (project in file(".")) 
 .settings( 
   name...

Exécution du programme

Dans cette partie, on reprend l’exemple utilisé dans la partie Un aperçu du langage - Entrée / Sortie. Pour lancer ce programme avec sbt, il faut tout d’abord lancer la console sbt grâce à la commande sbt, suivie de la commande run.

> sbt 
[info] welcome to sbt 1.4.0 (N/A Java 14.0.1) 
sbt:projet-scala> run 
[info] compiling 1 Scala source to 
/Users/agnesm/IdeaProjects/scala-book-project/target/scala- 
2.12/classes ... 
[info] running eni.Bonjour 
Quel est votre prénom ? Agnès 
Quel est votre nom ? Maury 
Quel est votre âge ? 28 
Allez-vous bien ? Non 
Bonjour Agnès Maury ! 
Vous avez 28 ans ! 
Vous vous sentez mal 
[success] Total time: 8 s, completed 16 Apr 2021, 12:57:58 

Pour fournir des arguments au programme, il suffit de les renseigner après la commande run.

Dans notre exemple, on vérifie au lancement de l’application que la liste des arguments est non vide, auquel cas on termine le problème avec un code d’erreur. Pour cela, on utilise la méthode System.exit suivie du code de retour.

if (args.length == 0) { 
 println("Impossible de lancer sans argument") 
 System.exit(-1) 
} 

On peut également créer un exécutable d’un programme sous forme d’un jar avec la commande...

Tests unitaires

1. Dépendances

Par défaut, les classes nécessaires pour lancer un test sont disponibles mais il est très fréquent que des frameworks de tests soient utilisés afin d’avoir plus d’outils et de classes utilitaires à notre disposition pour écrire les tests unitaires.

Celui que nous allons voir dans ce livre est ScalaTest. Il permet d’écrire des tests de différentes façons selon le besoin et les appétences des développeurs.

Pour l’importer, il suffit d’ajouter la dépendance suivante :

libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.2" %  
Test 

2. Écrire un test unitaire

Les tests unitaires sont définis dans une classe qui étend le trait TestSuite. Comme introduit dans la dernière section, ScalaTest offre plusieurs façons d’écrire des tests sous la forme de traits qui étendent TestSuite.

De façon générale, dans un test unitaire, on souhaite vérifier le comportement d’une méthode avec des assertions. En Scala, la méthode utilisée est assert qui prend en entrée une condition et fait échouer le test si cette condition est fausse.

Par exemple, si on prend un argument champ et qu’on veut vérifier qu’il est égal à la chaîne de caractères “vide”, on écrit :

assert(champ == "vide") 

Même si les Exception sont très peu présentes en Scala, elles peuvent survenir. Lors d’un test, on peut les intercepter et vérifier leur valeur grâce à la méthode typée intercept autour de la méthode testée.

Par exemple, si on veut capter l’Exception générée lors la division par zéro, on écrit :

val exception = intercept[Exception] { 
 2 / 0 
} 

On peut ensuite effectuer des assertions sur cette Exception comme par exemple vérifier son message ou encore son type avec la méthode isInstanceOf.

assert(exception.isInstanceOf[java.lang.ArithmeticException]) 

Si on ne s’intéresse pas au contenu de l’exception, mais uniquement à son interception, on utilise la méthode typée assertThrows qui prend en argument le...