diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index aa9555fccabe52797d3ebb49b51db77678f63042..7c1fb1d456add949affbd0e0ed6cb75b6d69fb52 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -40,22 +40,11 @@ lint:
   script: "./gradlew lint"
 
 
-test-frontend:
+test-and-sonarqube:
   stage: test
   tags:
-   - openstack
-  script: "./gradlew :frontend:test --parallel"
-  artifacts:
-    reports:
-      junit:
-        - "./frontend/karma-junit-tests-report/TEST*.xml"
-
-
-test-backend:
-  stage: test
-  tags:
-   - openstack
-  script: "./gradlew :backend:test --parallel"
+    - openstack
+  # the backend tests need an elasticsearch instance
   services:
     # even if that would be ideal
     # we can't just launch the service with just elasticsearch:6.3.1
@@ -70,10 +59,19 @@ test-backend:
       # especially the error regarding
       # `max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]`
       command: ["bin/elasticsearch", "-Ediscovery.type=single-node"]
+  variables:
+    GRADLE_OPTS: "-Dorg.gradle.daemon=true"
+  script:
+    - ./gradlew :frontend:test --parallel
+    - ./gradlew :backend:test --parallel
+    - find /tmp/node/*/bin -name node -exec ln -s {} /tmp/node/node \;
+    - export PATH="/tmp/node/:$PATH"
+    - ./gradlew sonarqube -x test
   artifacts:
     reports:
       junit:
-        - "./backend/build/test-results/test/TEST-*.xml"
+        - ./backend/build/test-results/test/TEST-*.xml
+        - ./frontend/karma-junit-tests-report/TEST*.xml
 
 
 # BUILD
@@ -89,11 +87,6 @@ build:
     paths:
       - "$JAR_PATH"
     expire_in: 1 week
-  only:
-    changes:
-      - .gitlab-ci.yml
-      - backend/src/**/*
-      - frontend/**/*
 
 
 # DEPLOY
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 8b06b9812dc5e8f580433afaed5519e9e0c32112..ca99a00edbda7ccc394869431fec04f9a5ac33a6 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -10,9 +10,6 @@
         <module name="faidare.backend.main" />
       </profile>
     </annotationProcessing>
-    <bytecodeTargetLevel>
-      <module name="faidare.backend.main" target="1.8" />
-      <module name="faidare.backend.test" target="1.8" />
-    </bytecodeTargetLevel>
+    <bytecodeTargetLevel target="1.8" />
   </component>
 </project>
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index e208459b8afde5f7980720efd6bbb97f7ae24541..ff8249e49968d1849269b0d8a2fe49a31c72a63f 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,6 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+  <component name="FrameworkDetectionExcludesConfiguration">
+    <file type="web" url="file://$PROJECT_DIR$" />
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
     <output url="file://$PROJECT_DIR$/out" />
   </component>
 </project>
\ No newline at end of file
diff --git a/backend/build.gradle.kts b/backend/build.gradle.kts
index c15af8dabbc9f5942c4635a08ef1e0f976dc625c..e80e4269580a4d4efde2b6af7614ed9e336ec897 100644
--- a/backend/build.gradle.kts
+++ b/backend/build.gradle.kts
@@ -16,6 +16,7 @@ plugins {
     id("org.springframework.boot") version "2.1.2.RELEASE"
     id("com.gorylenko.gradle-git-properties") version "1.5.2"
     id("io.spring.dependency-management") version "1.0.6.RELEASE"
+    id("org.sonarqube")
 }
 
 
diff --git a/build.gradle.kts b/build.gradle.kts
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..24155372eb5d122404c96691f7691eb52a09b0ae 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -0,0 +1,3 @@
+plugins {
+    id("org.sonarqube") version "2.8"
+}
diff --git a/frontend/build.gradle.kts b/frontend/build.gradle.kts
index bb0567fa87a53e9825f3f5837324fb675c548d92..c86af189a2098b2890746f80a4292d64bad5946e 100644
--- a/frontend/build.gradle.kts
+++ b/frontend/build.gradle.kts
@@ -3,6 +3,7 @@ import com.moowork.gradle.node.npm.NpmTask
 plugins {
     base
     id("com.moowork.node") version "1.2.0"
+    id("org.sonarqube")
 }
 
 val isCi = System.getenv("CI") != null
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..4ce5f43071019d0faad8786c5f3e4fe7d3d8f7f7
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,13 @@
+# gradle.properties
+systemProp.sonar.host.url=https://urgi.versailles.inrae.fr/sonarqube
+
+#----- Token generated from an account with 'publish analysis' permission
+systemProp.sonar.login=94f359749d72f13d1e1a407521a8dd57c71ba562
+
+systemProp.sonar.sources=frontend/src
+systemProp.sonar.language=typescript
+systemProp.sonar.scm.provider=git
+systemProp.sonar.typescript.tsconfigPath=frontend/tsconfig.json
+systemProp.sonar.typescript.lcov.reportPaths=frontend/coverage/lcov.info
+systemProp.sonar.typescript.node=/tmp/node/node
+systemProp.sonar.typescript.exclusions=**/*.spec.ts