Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
5ad8322
Add SpeedWeightingTest with 7 new unit tests
wudm12 Sep 21, 2025
fbd86ee
Create Rapport.md
Yubito04 Oct 9, 2025
1714064
Create .gitkeep
Yubito04 Oct 9, 2025
92683c1
Add files via upload
Yubito04 Oct 9, 2025
c5c7c9d
Rename capture test.png to capture-test.png
Yubito04 Oct 9, 2025
b14565c
Rename jacoco core overview.png to jacoco-core-overview.png
Yubito04 Oct 9, 2025
f13117b
Update Rapport.md
Yubito04 Oct 9, 2025
eb1c409
Merge pull request #1 from Yubito04/patch-1
wudm12 Oct 10, 2025
682e5a6
Update pom.xml en ajoutant pitest et la librairie javafaker
Yubito04 Oct 10, 2025
b41fbc9
Update SpeedWeightingTest.java
Yubito04 Oct 10, 2025
4805f26
Merge pull request #2 from Yubito04/master
wudm12 Oct 10, 2025
b5056cc
pitest + test 8
wudm12 Oct 10, 2025
ae17729
Merge branch 'master' of https://github.com/wudm12/graphhopper
wudm12 Oct 10, 2025
9d95f51
retirer les doublons pitest + java faker
wudm12 Oct 10, 2025
e408c4d
Update Rapport.md
wudm12 Oct 10, 2025
0230227
Add PIT mutation score comparison to workflow
wudm12 Nov 4, 2025
0c04a07
Trigger first GitHub Action run
wudm12 Nov 4, 2025
bd3ea1a
Run PIT with Java 17 for compatibility
wudm12 Nov 4, 2025
7ffebd3
Fix PIT argLine issue by setting argLine empty
wudm12 Nov 4, 2025
5f1e3b0
Run PIT only on core module to avoid web-api argLine issue
wudm12 Nov 4, 2025
9338f2e
Build dependencies before running PIT on core module
wudm12 Nov 4, 2025
a5fb7f9
Update mutation score to 0
github-actions[bot] Nov 4, 2025
3d42fba
Ajout Tâche 3 — Validation du workflow PIT
wudm12 Nov 4, 2025
58fac94
Add Mockito-based unit tests for CHStorage and TurnCostStorage
wudm12 Nov 4, 2025
f0183a9
Ajout du rapport Tâche 3 — Validation et conception
wudm12 Nov 4, 2025
4fab406
Fix workflow: remove automatic push of mutation score
wudm12 Nov 4, 2025
905469c
Add Rickroll composite action
wudm12 Nov 4, 2025
8e379fd
Add Rickroll action trigger on test failure
wudm12 Nov 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/actions/rickroll/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: Rickroll
description: Drop a cheeky rickroll in the job summary on failure
runs:
using: "composite"
steps:
- shell: bash
run: |
cat >> "$GITHUB_STEP_SUMMARY" <<'EOF'
### 😅 You got rickrolled!
[Never Gonna Give You Up (YouTube)](https://youtu.be/dQw4w9WgXcQ)

![Rickroll](https://media.giphy.com/media/Vuw9m5wXviFIQ/giphy.gif)
EOF
56 changes: 55 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jobs:
strategy:
fail-fast: false
matrix:
java-version: [ 24, 25-ea ]
java-version: [ 17 ]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
Expand Down Expand Up @@ -36,4 +36,58 @@ jobs:
${{ runner.os}}-node_modules-
- name: Build ${{ matrix.java-version }}
run: mvn -B clean test
- name: Run PIT Mutation Testing (core module only)
run: mvn clean install -DskipTests && mvn -pl core org.pitest:pitest-maven:mutationCoverage -DargLine=""

- name: Extract current PIT score
id: current
run: |
SCORE=$(grep -oPm1 "(?<=<score>)[^<]+" target/pit-reports/*/summary.xml || echo 0)
echo "current_score=$SCORE" >> $GITHUB_OUTPUT
echo "Current mutation score: $SCORE"

- name: Get previous PIT score
id: previous
run: |
if [ -f mutation_score.txt ]; then
PREV=$(cat mutation_score.txt)
else
PREV=0
fi
echo "previous_score=$PREV" >> $GITHUB_OUTPUT
echo "Previous mutation score: $PREV"

- name: Compare scores
id: compare
run: |
CUR=${{ steps.current.outputs.current_score }}
PREV=${{ steps.previous.outputs.previous_score }}

echo "🔍 Comparing mutation scores..."
echo "Previous: $PREV"
echo "Current: $CUR"

if [ "$CUR" -lt "$PREV" ]; then
echo "Mutation score decreased! ($CUR < $PREV)"
exit 1
fi

echo "Mutation score OK or improved ($CUR ≥ $PREV)"

- name: Save new mutation score
if: success()
run: echo "${{ steps.current.outputs.current_score }}" > mutation_score.txt

- name: Rickroll on failure
if: failure()
uses: ./.github/actions/rickroll


# - name: Commit updated mutation score
# if: success()
# run: |
# git config user.name "github-actions[bot]"
# git config user.email "github-actions[bot]@users.noreply.github.com"
# git add mutation_score.txt
# git commit -m "Update mutation score to ${{ steps.current.outputs.current_score }}" || echo "No changes to commit"
# git push
167 changes: 167 additions & 0 deletions Rapport.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# Binôme

- Wayne Timmons
- Ayoub Bencheikh

# Tâche 2 — Tests de SpeedWeighting

## Classe testée
- `com.graphhopper.routing.weighting.SpeedWeighting`

## Nouveaux cas de test ajoutés (7)

### 1. testCalcEdgeWeightNormal
- **Intention :** Vérifier que `calcEdgeWeight()` retourne bien `distance / speed` quand la vitesse est > 0.
- **Données de test :** distance = 1000.0, vitesse = 50.0.
- **Oracle attendu :** Résultat = 20.0 (1000 / 50).

### 2. testCalcEdgeWeightZeroSpeed
- **Intention :** Vérifier que `calcEdgeWeight()` retourne `Double.POSITIVE_INFINITY` si la vitesse est 0.
- **Données de test :** vitesse = 0.0.
- **Oracle attendu :** Résultat = `Double.POSITIVE_INFINITY`.

### 3. testCalcEdgeWeightReverse
- **Intention :** Vérifier que `calcEdgeWeight()` utilise `getReverse(speedEnc)` quand `reverse = true`.
- **Données de test :** distance = 500.0, vitesse inverse = 25.0.
- **Oracle attendu :** Résultat = 20.0 (500 / 25).

### 4. testCalcEdgeMillis
- **Intention :** Vérifier que `calcEdgeMillis()` retourne le poids en millisecondes (`calcEdgeWeight * 1000`).
- **Données de test :** distance = 100.0, vitesse = 10.0.
- **Oracle attendu :** Résultat = 10000 ms ((100 / 10) * 1000).

### 5. testCalcMinWeightPerDistance
- **Intention :** Vérifier que `calcMinWeightPerDistance()` retourne `1 / maxSpeed`.
- **Données de test :** maxSpeed = 120.0.
- **Oracle attendu :** Résultat = 1/120.

### 6. testGetName
- **Intention :** Vérifier que `getName()` retourne la chaîne `"speed"`.
- **Données de test :** aucune donnée spécifique.
- **Oracle attendu :** `"speed"`.

### 7. testHasTurnCosts
- **Intention :** Vérifier que `hasTurnCosts()` retourne `true` si un `TurnCostProvider` est configuré.
- **Données de test :** `TurnCostStorage` non nul, `uTurnCosts = 5.0`.
- **Oracle attendu :** `true`.


Nouveau test : testCalcEdgeWeightWithFakerDeterministic

Intention : Vérifier le bon calcul du poids avec des valeurs aléatoires mais déterministes générées par java-faker.

Données de test : distance et vitesse générées via Faker(new Random(12345)).

Oracle attendu : Résultat = distance / speed.

Justification : ce test montre l’usage d’un générateur de données réalistes pour améliorer la variabilité et la robustesse des tests.


## Preuves d’exécution & couverture

### Exécution des tests
![Console – 7 tests OK](docs/images/capture-test.png)

### Couverture (JaCoCo) – Vue d’ensemble Core
![JaCoCo – Core](docs/images/jacoco-core-overview.png)

### Couverture (JaCoCo) – Détail SpeedWeighting
![JaCoCo – SpeedWeighting](docs/images/speedweighting.png)


-----


## Étape 1 – Tests originaux
- **Mutation coverage : 0% (0/51 mutants tués)**
- Aucun test existant ne couvrait la classe sélectionnée.

## Étape 2 – Nouveaux tests ajoutés
- Nous avons ajouté **7 nouveaux tests unitaires** dans `SpeedWeightingTest`.
- Ces tests visent à couvrir :
- le calcul du poids en fonction de la vitesse,
- la gestion des vitesses nulles ou invalides,
- les conditions limites (ex. vitesse très élevée ou très basse),
- la cohérence du retour attendu par rapport à l’oracle (valeur théorique calculée manuellement).

## Étape 3 – Score de mutation avec les nouveaux tests
- **Mutation coverage : ~65% (33/51 mutants tués)**
- **Line coverage : ~86% (19/22 lignes couvertes)**
- Les nouveaux tests ont permis de tuer une majorité des mutants, notamment ceux liés à :
- la négation de conditions (`NegateConditionalsMutator`),
- les changements de bornes dans les comparaisons (`ConditionalsBoundaryMutator`),
- les mutations sur les opérations mathématiques (`MathMutator`),
- les constantes modifiées (`InlineConstantMutator`).

## Étape 4 – Mutants survivants
- Certains mutants ont survécu, principalement :
- **`MemberVariableMutator`** : changements de valeurs internes non testées directement.
- **`ConstructorCallMutator`** : peu ou pas de vérification sur les appels de constructeurs.
- **`BooleanTrueReturnValsMutator`** : cas limites où le résultat booléen n’est pas validé par nos assertions.

Ces survivants indiquent que des cas spécifiques ne sont pas encore couverts par nos tests.

## Étape 5 – Conclusion
- Avec les **tests originaux** : score de mutation **0%**.
- Avec les **nouveaux tests** : score de mutation **65%**.
- Les nouveaux tests apportent donc une **forte amélioration de la robustesse** face aux mutations.

## Étape 6 – Intégration de JavaFaker

Nous avons ajouté la librairie [java-faker](https://github.com/DiUS/java-faker) au projet via Maven :

```xml
<dependency>
<groupId>com.github.javafaker</groupId>
<artifactId>javafaker</artifactId>
<version>1.0.2</version>
<scope>test</scope>
</dependency>


Tâche 3 — Modification du workflow GitHub Actions et validation du score de mutation

Afin d’assurer la stabilité du projet et de suivre la qualité des tests automatisés, nous avons modifié le workflow CI/CD (.github/workflows/build.yml) pour qu’il échoue automatiquement si le score de mutation PIT diminue après un commit.

Choix de conception

Le plugin PIT (Pitest 1.21.1) a été intégré via la commande :

mvn org.pitest:pitest-maven:mutationCoverage


Un bug récurrent {argLine} empêchait PIT de s’exécuter sur le module graphhopper-web-api.
Ce problème a été résolu en :

forçant l’utilisation de Java 17 (version stable compatible avec PIT) ;

limitant l’analyse au module core à l’aide de -pl core ;

nettoyant et construisant préalablement les dépendances avec :

mvn clean install -DskipTests


Le workflow compare ensuite le score actuel avec le précédent, enregistré dans un fichier mutation_score.txt.
S’il baisse, le processus échoue ; sinon, il le met à jour et le pousse automatiquement sur le dépôt.

Validation

Les exécutions locales et distantes ont permis de :

confirmer le BUILD SUCCESS complet sous Java 17 ;

générer un rapport PIT dans core/target/pit-reports/ contenant les fichiers index.html, mutations.xml et summary.xml ;

obtenir un score de mutation de 43 % et une couverture de lignes de 69 % sur le package com.graphhopper.routing.weighting.

Le rapport HTML ci-dessous prouve que la mesure du score de mutation est fonctionnelle et intégrée à la CI :

Line Coverage : 69 %
Mutation Coverage : 43 %
Test Strength : 69 %

Conclusion

Cette configuration garantit que toute future régression du score de mutation sera détectée automatiquement par GitHub Actions.
Elle renforce la qualité logicielle et la traçabilité des modifications dans le cadre du projet GraphHopper.
Loading