Parser le rapport
Maintenant que vos tests s'exécutent et génÚrent des rapports, vous devez convertir ces rapports dans un format que SquashTM peut comprendre.
Ce que vous apprendrez dans cette section :
- Parser un rapport de test xUnit XML issu de Robot Framework
- Le convertir au format JSON de SquashTM
- Faire correspondre les résultats de tests aux références de test automatisé que vous avez configurées dans SquashTM
Exemple Robot Framework et xUnit XML
Cette section démontre le parsing de sortie xUnit XML depuis Robot Framework. Si vous utilisez un framework de test ou un format de rapport différent (ex. Cucumber JSON), vous devrez adapter la logique du parser pour correspondre à la structure spécifique de votre rapport.
Dans la section précédente, vous avez configuré un pipeline qui exécute Robot Framework et produit un rapport xunit.xml. Dans cette section, vous ajouterez un parser au pipeline qui convertit xunit.xml au format JSON de SquashTM.
Voir le script de parser complet
Vous pouvez consulter le script de parser complet ici : parse_robot_results.py.
Exemple : GitLab CI/CD + Robot Framework
Ătape 1 : CrĂ©er le script de parser
Créez un script Python qui parse le fichier XML xUnit et génÚre un fichier JSON compatible avec SquashTM.
Créez un répertoire ci dans votre projet et ajoutez le script de parser :
your-project/
âââ .gitlab-ci.yml
âââ ci/
â âââ parse_robot_results.py â CrĂ©ez ce fichier
âââ tests/
â âââ login_validation_tests.robot
âââ ...
Fichier : ci/parse_robot_results.py
#!/usr/bin/env python3
"""
Parse xUnit/JUnit XML test results and generate a SquashTM-compatible JSON report.
This script extracts test results from xUnit/JUnit XML files and creates
a structured JSON report compatible with SquashTM API format.
"""
import base64
import json
import xml.etree.ElementTree as ET
from pathlib import Path
def encode_file_to_base64(file_path):
"""Encode a file to base64."""
with open(file_path, 'rb') as f:
return base64.b64encode(f.read()).decode('utf-8')
def parse_tests(xml_file):
"""Parse xUnit/JUnit XML file."""
tree = ET.parse(xml_file)
root = tree.getroot()
tests = []
suite_name = root.get('name', 'Suite')
# Loop through all test cases
for testcase in root.findall('.//testcase'):
test_name = testcase.get('name', 'Test')
classname = testcase.get('classname', suite_name)
time_seconds = float(testcase.get('time', '0'))
# Determine status
failure = testcase.find('failure')
error = testcase.find('error')
skipped = testcase.find('skipped')
if failure is not None:
status = 'FAILURE'
failure_message = failure.get('message', failure.text or 'Test failed')
failure_details = [failure_message.strip()]
elif error is not None:
status = 'BLOCKED'
failure_details = None
elif skipped is not None:
status = 'SKIPPED'
failure_details = None
else:
status = 'SUCCESS'
failure_details = None
# Build reference as '<InnermostSuite>.<TestName>'
suite_for_ref = classname.split('.')[-1]
# Create test result
result = {
'reference': f"{suite_for_ref}.{test_name}",
'status': status,
'duration': round(time_seconds * 1000) # Convert to milliseconds
}
# Add failure details if present
if failure_details:
result['failure_details'] = failure_details
tests.append(result)
return tests
def create_attachments():
"""Create attachments (test report files encoded in base64)."""
attachments = []
files = ['xunit.xml', 'report.html', 'log.html', 'output.xml']
for file in files:
if Path(file).exists():
attachments.append({
'name': file,
'content': encode_file_to_base64(file)
})
return attachments
def main():
"""Main function."""
tests = parse_tests('xunit.xml')
attachments = create_attachments()
report = {
'automated_test_suite': {
'attachments': attachments
},
'tests': tests
}
with open('result.json', 'w', encoding='utf-8') as f:
json.dump(report, f, indent=2, ensure_ascii=False)
print(f"{len(tests)} test(s) parsed")
print(f"result.json created with {len(attachments)} attachment(s)")
if __name__ == '__main__':
main()
Comment fonctionne le parser
Le script effectue plusieurs opérations : il parse le fichier XML xUnit, crée les piÚces jointes et génÚre le JSON SquashTM.
Implémentation spécifique au format
Les sections suivantes expliquent la logique de parsing spĂ©cifique au format xUnit XML. Si vous utilisez un format de rapport diffĂ©rent, ces sections vous aideront Ă comprendre ce qui doit ĂȘtre adaptĂ© pour votre format.
1. Parser la structure XML xUnit
La fonction parse_tests() lit le format xUnit qui contient des éléments <testcase> avec des attributs comme name, classname et time. Chaque cas de test peut contenir des éléments enfants : <failure>, <error> ou <skipped> qui indiquent le statut du test.
2. Mapper le statut des tests
Le parser mappe les résultats xUnit aux statuts SquashTM :
- ĂlĂ©ment
<failure>â statutFAILUREdans SquashTM - ĂlĂ©ment
<error>â statutBLOCKEDdans SquashTM - ĂlĂ©ment
<skipped>â statutSKIPPEDdans SquashTM - Pas de failure/error/skipped â statut
SUCCESSdans SquashTM
3. Construire la référence de test automatisé
La référence identifie de maniÚre unique chaque test dans SquashTM :
- Format :
<SuiteName>.<TestName>(par exemple,Login Validation Tests.Valid Login Passes) - Cette référence doit correspondre au champ référence du test automatisé configuré dans vos cas de test SquashTM
4. Créer les piÚces jointes
PiÚces jointes spécifiques à Robot Framework
Les piÚces jointes suivantes sont spécifiques à Robot Framework. Adaptez les noms de fichiers et les types pour correspondre aux fichiers de sortie de votre framework de test.
La fonction create_attachments() encode les fichiers de rapport en base64 :
xunit.xml: Rapport de test au format xUnitreport.html: Rapport HTML généré par Robot Frameworklog.html: Log détaillé des testsoutput.xml: Sortie XML complÚte de Robot Framework
5. Extraire des informations supplémentaires
- Durée : Convertie de secondes (xUnit) en millisecondes (SquashTM)
- Détails d'échec : Extraits du message ou du contenu texte de l'élément
<failure>
6. Générer le fichier JSON
Le script crĂ©e un fichier result.json contenant la structure complĂšte avec les tests et les piĂšces jointes, prĂȘt Ă ĂȘtre envoyĂ© Ă SquashTM.
Exemple de transformation
Entrée XML xUnit (test échoué) :
<testcase classname="Login Validation Tests" name="Invalid Login Fails" time="0.456">
<failure message="AssertionError: Expected login to fail but it succeeded">
Login with invalid credentials should have been rejected.
</failure>
</testcase>
Sortie JSON SquashTM :
{
"reference": "Login Validation Tests.Invalid Login Fails",
"status": "FAILURE",
"duration": 456,
"failure_details": [
"AssertionError: Expected login to fail but it succeeded"
]
}
Pour la référence complÚte de la structure JSON incluant les champs optionnels comme automated_test_suite et les piÚces jointes, consultez la spécification détaillée du format
Envoi vers SquashTM
Dans la section suivante, vous ajouterez le code pour envoyer automatiquement ce fichier result.json à SquashTM via l'API. Pour l'instant, le fichier est simplement généré et sauvegardé comme artefact.
Ătape 2 : Ajouter le job de parser au pipeline
Maintenant, ajoutez un nouveau job à votre .gitlab-ci.yml qui exécute le parser aprÚs la fin des tests.
Ouvrez votre fichier .gitlab-ci.yml et ajoutez une étape post et le job de parser :
stages:
- test
- post # Ajoutez cette nouvelle étape
# ... (conservez votre job robotframework-tests existant)
parse-and-publish:
stage: post
needs:
- job: robotframework-tests
artifacts: true
when: always
allow_failure: false
script:
- python --version
- python ci/parse_robot_results.py
artifacts:
when: always
expire_in: 7 days
paths:
- result.json
Ce que cela fait :
stage: post: S'exĂ©cute aprĂšs la fin de l'Ă©tapetestneeds: Attend le jobrobotframework-testset tĂ©lĂ©charge ses artefacts (incluantxunit.xml). Cela garantit que le job de parser a accĂšs au fichierxunit.xmlgĂ©nĂ©rĂ© par le job de test.when: always: S'exĂ©cute mĂȘme si les tests ont Ă©chouĂ© (nous voulons parser tous les rĂ©sultats), garantissant que tous les rĂ©sultats sont capturĂ©s.allow_failure: false: Fait Ă©chouer le pipeline si le parsing Ă©chouescript: ExĂ©cute le script Python de parserartifacts: Sauvegarde le fichierresult.jsongĂ©nĂ©rĂ© pour inspection et traçabilitĂ©
Fichier de pipeline complet
Ă ce stade, votre .gitlab-ci.yml complet devrait ressembler Ă ceci :
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "web"'
- if: '$CI_PIPELINE_SOURCE == "schedule"'
- when: never
variables:
ROBOT_VERSION: "7.4.1"
default:
image: python:3.14-slim
stages:
- test
- post
robotframework-tests:
stage: test
allow_failure: true
script:
- python --version
- pip install --upgrade pip --root-user-action=ignore
- pip install robotframework==${ROBOT_VERSION} --root-user-action=ignore
- robot --xunit xunit.xml ./tests/
artifacts:
when: always
expire_in: 7 days
paths:
- output.xml
- log.html
- report.html
- xunit.xml
reports:
junit: xunit.xml
parse-and-publish:
stage: post
needs:
- job: robotframework-tests
artifacts: true
when: always
allow_failure: false
script:
- python --version
- python ci/parse_robot_results.py
artifacts:
when: always
expire_in: 7 days
paths:
- result.json
Ătape 3 : Commiter et vĂ©rifier
Commitez vos changements et poussez vers GitLab :
git add ci/parse_robot_results.py .gitlab-ci.yml
git commit -m "Add test results parser"
git push
Vérifier le parser
- Allez dans votre projet GitLab
- Naviguez vers Build â Pipelines
- Cliquez sur le dernier pipeline
- Vous devriez maintenant voir deux jobs :
robotframework-testsetparse-and-publish - Cliquez sur le job
parse-and-publishpour voir la sortie du parser - Une fois terminé, téléchargez l'artefact
result.jsonpour inspecter les résultats parsés
Ce que vous avez accompli
Votre pipeline CI/CD maintenant :
- Exécute les tests automatisés
- Parse les résultats de tests au format JSON de SquashTM
- GénÚre un fichier
result.jsonavec tous les résultats de tests - Fait correspondre les résultats de tests aux références de test automatisé
Prochaine étape
Maintenant que vous avez des résultats de tests parsés au format JSON de SquashTM, l'étape finale est de publier ces résultats dans votre instance SquashTM via l'API.
Dans la section suivante, vous apprendrez comment ajouter un job qui envoie le fichier result.json Ă SquashTM.
Passez Ă Publier dans SquashTM