Aller au contenu

Utilisation du BDD et de Robot Framework dans Squash – Automatisation des cas de test

Récupération des cas de test

Annita
Administratrice Squash TM
Pravash
Product owner
Fabrice
Testeur fonctionnel
Antonine
Automaticienne
Configurer Squash TM
Rédiger les exigences
Rédiger les cas de test
Transmettre les cas de test
Récupérer les cas de test
Automatiser les cas de test
Fournir les cas de test automatisés
Indiquer que l'automatisation est effectuée
Exécuter les tests automatisés

Sélection des cas de test à automatiser dans Squash TM

Antonine choisit des tests à automatiser dans l'onglet "À traiter" de l'Espace Automatisation (voir documentation) en les sélectionnant et en cliquant sur le bouton "Me l'assigner".

test case pick up

Ensuite, en utilisant l'onglet "M'étant assigné" de l'Espace Automatisation (voir documentation), elle indique que l'automatisation de ces tests est lancée :

test case automation in progress

Récupération des fichiers robot

Antonine met à jour son dépôt local pour récupérer les fichiers robot poussés par Squash TM dans le dépôt Git distant.

git pull

Automatisation des cas de test

Annita
Administratrice Squash TM
Pravash
Product owner
Fabrice
Testeur fonctionnel
Antonine
Automaticienne
Configurer Squash TM
Rédiger les exigences
Rédiger les cas de test
Transmettre les cas de test
Récupérer les cas de test
Automatiser les cas de test
Fournir les cas de test automatisés
Indiquer que l'automatisation est effectuée
Exécuter les tests automatisés

Mise en place du code banal (boiler plate)

Structure de la base de code

Avant de mettre en œuvre les premières étapes de Robot Framework, Antonine crée quelques répertoires pour organiser son code. L'arborescence des fichiers qui en résulte est la suivante :

  • .git/ → Git

  • resources/

    • browser_helpers / → aides techniques pour le HTML

      • checkbox_radiobutton_helpers.resource
    • helpers / → aides techniques pour les données

      • datatable_helpers.resource
      • quote_helpers.resource
    • step_definitions / → définitions des pas de test

      • account_management.resource
      • cart_management.resource
      • navigation.resource
      • product_management.resource
    • page_objects / → page objects

      • account_creation_page.resource
      • cart_page.resource
      • header_page.resource
      • home_page.resource
      • identity_page.resource
      • login_page.resource
      • product_page.resource
    • setup_teardown.resource
  • tests/

    • bdd_squash / → contient des fichiers robot générés par Squash TM 🛑 La hiérarchie des sous-répertoires et les fichiers robot ne doivent pas être modifiés !

      • Account_management /

        • squash_resources.resource créé par Antonine 🛑 Le nom du fichier ne doit pas être modifié !
        • 271_Standard_account_creation.robot
        • 294_Cannot_log_with_incorrect_password.robot
      • Cart_management /

        • squash_resources.resource créé par Antonine 🛑 Le nom du fichier ne doit pas être modifié !
        • 296_One_product.robot.robot
        • 297_Add_two_products_in_the_cart.robot
    • bdd_duplicates / → duplication du fichier robot afin d'effectuer des tests dans l'environnement local d'Antonine.

      • Account_management /
        • squash_resources.resource
        • 271_Standard_account_creation.robot
  • .gitignore

Quelques notes de conception

graph TD
    A[Step definitions] --> B[Page objects]
    A --> D[Helpers]
    B --> E[Browser helpers]
    B --> D
Antonine veut séparer clairement les préoccupations :

  • resources/page_objects contient les page objects habituels. Un page object est un fichier encapsulant les détails techniques d'une page testée (IDs, noms, XPaths… des éléments HTML).
    Ce modèle de conception présente deux avantages principaux :

    • Cela réduit le coût de maintenance en centralisant les détails de la page en un seul endroit : si un développeur modifie un élément HTML de la page et que ce changement casse le localisateur utilisé par Antonine pour trouver l'élément, elle n'aura à le mettre à jour qu'à un seul endroit.
    • Cela fournit une API qui a une sémantique métier : le code utilisant le page object connaît les fonctionnalités supportées par la page (par exemple, entrer email et mot de passe, puis essayer de se connecter) mais il n'a pas besoin de connaître la structure HTML ou le comportement JavaScript de celle-ci.
  • resources/step_definitions contient l'implémentation des mots-clés Robot Framework (pas de test). Chaque mot-clé interagit avec un ou plusieurs page objects, sans connaissance de la structure HTML.

  • resources/helpers

    • contient le code qui n'est pas lié à l'application testée (format de données, transformation de chaînes de caractères, conversion de liste ou de dictionnaire…) ;
    • est une couche technique qui ne connaît pas les règles métier de l'application testée.
  • resources/browser_helpers

    • contient le code utilisé par les page objects pour les interactions HTML courantes ;
    • est également une couche technique.

Le répertoire tests/bdd_squash

🛑 Les fichiers robot du répertoire tests/bdd_squash ne doivent pas être modifiés, ils sont contrôlés par Squash TM.
La modification de certains fichiers de ce répertoire, autres que les fichiers squash_resources.resource, pourrait entraver la transmission de nouveaux cas de test ou de cas de test mis à jour (c'est-à-dire les fichiers robot) à l'avenir.
Mais, même si la transmission fonctionnait, toutes les modifications seraient perdues, écrasées par Squash TM.

Fichier .gitignore

Antonine crée le fichier .gitignore. Il définit les fichiers que Git ne doit pas suivre et, par conséquent, ne pas prendre en compte pour les commits, voir la documentation de Git. Ici, elle veut que Git ignore les rapports de test et les captures d'écran.
Ce fichier contient :

# browser → contient tous les fichiers générés après l'exécution des tests de Robot Framework avec la Browser library
#     screenshot
#        failure_screen_1.png → capture d'écran pleine page intégrée au rapport Robot Framework
#        …
#     traces → créé par la Browser library pour stocker les fichiers de traces temporaires
browser/

# output.xml → résultats d'exécution des tests
output.xml

# playwright-log.txt → journal généré par la Browser library
playwright-log.txt

# log.html → fichier de rapport : détails sur les tests exécutés
log.html

# report.html → fichier de rapport : aperçu de l'exécution du test
report.html

Structure d'un fichier robot généré par Squash TM

Antonine analyse un test robot généré par Squash TM :

# Automation priority: 42
# Test case importance: High
*** Settings ***
Resource    squash_resources.resource

*** Keywords ***
Test Setup
    ${__TEST_SETUP} Get Variable Value  ${TEST SETUP}
    ${__TEST_294_SETUP} Get Variable Value  ${TEST 294 SETUP}
    Run Keyword If  $__TEST_SETUP is not None   ${__TEST_SETUP}
    Run Keyword If  $__TEST_294_SETUP is not None   ${__TEST_294_SETUP}

Test Teardown
    ${__TEST_294_TEARDOWN}  Get Variable Value  ${TEST 294 TEARDOWN}
    ${__TEST_TEARDOWN}  Get Variable Value  ${TEST TEARDOWN}
    Run Keyword If  $__TEST_294_TEARDOWN is not None    ${__TEST_294_TEARDOWN}
    Run Keyword If  $__TEST_TEARDOWN is not None    ${__TEST_TEARDOWN}

*** Test Cases ***
Cannot log with incorrect password
    [Setup] Test Setup

    Given I am on the AccountCreation page
    When I fill AccountCreation fields with gender "F" firstName "Alice" lastName "Noel" password "police" email "alice@noel.com" birthDate "01/01/1970" acceptPartnerOffers "yes" acceptPrivacyPolicy "yes" acceptNewsletter "yes" acceptGpdr "yes" and submit
    And I sign out
    And I sign in with email "alice@noel.com" and password "poluce"
    Then The error message "Échec d'authentification" is displayed

    [Teardown]  Test Teardown

Le fichier est organisé en trois parties principales :

1 - Settings :

*** Settings ***
Resource    squash_resources.resource
Le fichier squash_resources.resource contiendra une liste de toutes les dépendances requises par le scénario. Antonine doit créer ce fichier squash_resources.resource dans le dossier du test et y indiquer les chemins relatifs des dépendances.

Par exemple, si les pas de test nécessaires tests/bdd_squash/Account_management/271_Standard_account_creation.robot sont situés dans :

  • resources/setup_teardown.resource
  • resources/step_definitions/account_management.resource

elle remplirait le fichier tests/bdd_squash/Account_management/squash_resources.resource comme suit :

*** Settings ***
Documentation    Resources for all account management tests
Resource    ../../../resources/setup_teardown.resource
Resource    ../../../resources/step_definitions/account_management.resource

squash_resources.resource

Antonine doit créer et implémenter le fichier squash_resources.resource dans chaque dossier contenant des tests BDD.
Ce fichier doit contenir la liste des fichiers définissant les mots-clés utilisés dans le fichier robot généré par Squash TM (voir ci-dessous).

2 - Setup et Teardown :

*** Keywords ***
Test Setup
    ${__TEST_SETUP} Get Variable Value  ${TEST SETUP}
    ${__TEST_294_SETUP} Get Variable Value  ${TEST 294 SETUP}
    Run Keyword If  $__TEST_SETUP is not None   ${__TEST_SETUP}
    Run Keyword If  $__TEST_294_SETUP is not None   ${__TEST_294_SETUP}

Test Teardown
    ${__TEST_294_TEARDOWN}  Get Variable Value  ${TEST 294 TEARDOWN}
    ${__TEST_TEARDOWN}  Get Variable Value  ${TEST TEARDOWN}
    Run Keyword If  $__TEST_294_TEARDOWN is not None    ${__TEST_294_TEARDOWN}
    Run Keyword If  $__TEST_TEARDOWN is not None    ${__TEST_TEARDOWN}

Squash TM a créé des mots-clés à exécuter comme setup et teardown (setup est utilisé pour préparer le contexte du test, teardown pour le nettoyer). Pour chaque test, Antonine doit choisir d'implémenter aucun, un ou plusieurs de ces mots-clés :

  • ${TEST SETUP} et ${TEST TEARDOWN} sont partagés par tous les tests : utilisés pour le setup et le teardown de base non spécifiques (par exemple : ouverture ou fermeture d'un navigateur).

  • ${TEST 294 SETUP} et ${TEST 294 TEARDOWN} sont utilisés pour le setup et le teardown spécifiques à ce test 294. Si ce test nécessite des étapes spécifiques en plus du setup et du teardown de base, Antonine peut écrire le code correspondant dans l'un de ces mots-clés.

Mots-clés de setup et de teardown

  • Si tous les tests nécessitent un setup commun, Antonine doit définir le mot-clé ${TEST SETUP} ; sinon, elle doit laisser ce mot-clé non défini.
  • Si tous les tests nécessitent un teardown commun, Antonine doit définir le mot-clé ${TEST TEARDOWN} ; sinon, elle doit laisser ce mot-clé non défini.
  • Si un test donné nécessite un setup spécifique, Antonine doit définir le mot-clé ${TEST <test_id> SETUP} ; sinon, elle doit laisser ce mot-clé non défini.
  • Si un test donné teste un teardown spécifique, Antonine doit définir le mot-clé ${TEST <test_id> TEARDOWN} ; sinon, elle doit laisser ce mot-clé non défini.

Les fichiers implémentant ces mots-clés doivent être référencés dans le fichier squash_resources.resource.

(Certains IDEs signalent à tort un avertissement lorsqu'un mot-clé Robot Framework n'est pas défini. Cela peut être le cas pour ces mots-clés. Cet avertissement doit être ignoré.)

3 - Le cas de test tel qu'il est écrit dans Squash :

Chaque mot-clé apparaissant dans le cas de test devra être implémenté dans la section *** Keywords *** d'un des fichiers resource.

*** Test Cases ***
Cannot log with incorrect password
    [Setup] Test Setup

    Given I am on the AccountCreation page
    When I fill AccountCreation fields with gender "F" firstName "Alice" lastName "Noel" password "police" email "alice@noel.com" birthDate "01/01/1970" acceptPartnerOffers "yes" acceptPrivacyPolicy "yes" acceptNewsletter "yes" acceptGpdr "yes" and submit
    And I sign out
    And I sign in with email "alice@noel.com" and password "poluce"
    Then The error message "Échec d'authentification" is displayed

    [Teardown]  Test Teardown

Implémentation des mots-clés

Antonine doit implémenter tous les mots-clés.

Les fichiers implémentant ces mots-clés doivent être référencés dans le fichier squash_resources.resource.

Implémentation du setup et du teardown

Antonine écrit quelques méthodes de base, à commencer par le setup et le teardown des tests qu'elle place dans resources/setup_teardown.resource en tant que mots-clés Robot Framework.

  • La définition des variables

    *** Variables ***
    ${TEST SETUP}    Open Application
    ${URL}    http://localhost:8080/
    

  • Setup

    ***Keywords*** 
    Open Application
        [Documentation]    Test setup.
        Register Keyword To Run On Failure    Take Screenshot    failure_screen_{index}    fullPage=True
        New Browser    browser=firefox    headless=True
        New Page    url=${URL}
        Set Viewport Size    1900   1000
    
    Ce setup ouvre une nouvelle page à l'${URL} donnée, avec le navigateur Firefox, et modifie la taille de la fenêtre pour qu'elle corresponde à celle de l'écran d'un ordinateur portable. Ce setup génère également des captures d'écran pleine page en cas d'échec d'une ou plusieurs étapes du test. Les captures d'écran sont placées dans le dossier browser/screenshot et sont également intégrées dans les rapports de test. Cela sera très utile pour analyser les raisons de l'échec d'un test :

Robotframework report

Ecriture des browser helpers

resources/browser_helpers/ contient des ressources avec des mots-clés utilisés dans plusieurs page objects, par exemple, resources/browser_helpers/checkbox_radiobutton_helpers.resource contient des mots-clés pour :

  • Vérifier quel bouton radio est sélectionné dans une liste de boutons radio

    *** Settings ***
    Documentation    Helpers for checkboxes and radiobuttons
    Library    Browser
    
    
    *** Keywords ***
    Verify Selected Radiobutton
        [Arguments]    ${choice}    @{radiobuttons}
        [Documentation]    Checks if the specified radiobutton state matches the specified choice
        FOR    ${radiobutton}    IN    @{radiobuttons}
            IF    "${choice}" == "${radiobutton}[label]"
                Get Checkbox State    ${radiobutton}[rb]    ==    True
                BREAK
            END
        END
    

  • Sélectionner une case à cocher

    *** Keywords ***
    Select Checkbox Regarding Choice
        [Arguments]    ${choice}    ${cb}
        [Documentation]    Check checkbox regarding the specified choice.
        IF    "${choice}" == "yes"    Check Checkbox    ${cb}
    

  • Sélectionner un bouton radio

    *** Keywords ***
    Select Radiobutton Regarding Choice
        [Arguments]    ${choice}    @{radiobuttons}
        [Documentation]    Select radiobutton in a list of radiobuttons regarding the specified choice.
        FOR    ${radiobutton}    IN    @{radiobuttons}
            IF    "${choice}" == "${radiobutton}[label]"
                Check Checkbox    ${radiobutton}[rb]
                BREAK
            END
        END
    

Gestion de différents types de données

Paramètres

Fabrice a écrit un premier type de test basique, avec des valeurs de variables incorporées directement dans les pas de test :

parameters and datasets

Squash TM a généré un test Robot Framework avec des paramètres intégrés entre guillemets :

*** Test Cases ***
Cannot log with incorrect password
    [Setup] Test Setup

    Given I am on the AccountCreation page
    When I fill AccountCreation fields with gender "F" firstName "Alice" lastName "Noel" password "police" email "alice@noel.com" birthDate "01/01/1970" acceptPartnerOffers "yes" acceptPrivacyPolicy "yes" acceptNewsletter "yes" acceptGpdr "yes" and submit
    And I sign out
    And I sign in with email "alice@noel.com" and password "poluce"
    Then The error message "Échec d'authentification" is displayed

    [Teardown]  Test Teardown

Jeux de données

Fabrice a également écrit un deuxième type de test, utilisant des jeux de données et des variables intégrées :

parameters and datasets

Pour ce test, les valeurs sont définies en utilisant la section Jeux de données de Squash TM :

parameters and datasets

Squash TM a généré un test de Robot Framework avec des variables embarquées :

*** Test Cases ***
Standard account creation
    [Setup] Test Setup

    Given I am on the AccountCreation page
    When I fill AccountCreation fields with gender ${gender} firstName ${first} lastName ${last} password ${password} email ${mail} birthDate ${birth} acceptPartnerOffers ${offers} acceptPrivacyPolicy ${privacy} acceptNewsletter ${news} acceptGpdr ${gpdr} and submit
    And I sign out
    And I sign in with email ${mail} and password ${password}
    Then My personal informations are gender ${gender} firstName ${first} lastName ${last} email ${mail} birthDate ${birth}

    [Teardown]  Test Teardown

Gestion des guillemets pour éviter la duplication du code

Certains pas de test sont partagés par ces deux tests, par exemple les mots-clés I sign in with email "alice@noel.com" and password "poluce" et I sign in with email ${mail} and password ${password} sont similaires : la principale différence entre les deux mots-clés générés sont les guillemets entourant les variables dans le premier.

Antonine veut éviter la duplication du code, elle veut donc implémenter une seule fois le mot-clé I sign in with email ${mail} and password ${password}.

Pour ce faire, Antonine doit gérer les guillemets, car si elle ne supprime pas les guillemets des valeurs des variables, le mot-clé fonctionnera parfaitement pour le test des paramètres intégrés, mais échouera pour le test de base, car Robot Framework considérera la valeur du paramètre comme "Alice" et l'injectera dans l'application testée avec les guillemets. (Ce problème devrait être corrigé dans une prochaine version de Squash TM, car tous les mots-clés robot générés par Squash TM comporteront des guillemets).

Dans ce fichier resources/step_definitions/account_management.robot, Antonine implémente le mot-clé I sign in with email ${mail} and password ${password} :

*** Keywords ***
I sign in with email ${mail} and password ${password}
    [Documentation]     Logs a user.
    ${mail} =    Remove Framing Quotes From Parameter  ${mail}
    ${password} =    Remove Framing Quotes From Parameter  ${password}

    Go To The SignIn Page
    Clear Login Fields
    Fill Login Fields  ${mail}  ${password}
    Submit Login

en utilisant la ressource resources/helpers/quotes.resource :

*** Settings ***
Documentation    helpers for quoted parameters coming from Squash TM.
Library    String
Library    Collections


*** Keywords ***
Remove Framing Quotes From Parameter
    [Arguments]    ${parameter}
    [Documentation]    If the parameter starts and ends with a quote,
    ...                this keyword removes them.
    ...                Examples:
    ...                "hello world!" -> hello world!
    ...                "hello world! -> "hello world!
    ...                hello world! -> hello world!
    ${parameter} =    Replace String Using Regexp    ${parameter}    \\".*\\"    ${parameter}[1:-1]
    RETURN    ${parameter}

Exécution d'un test Robot Framework utilisant des jeux de données dans l'environnement local

Pour les tests utilisant des jeux de données, il est possible de récupérer leurs valeurs en utilisant la bibliothèque squash-tf-services library (voir cette page) :

*** Settings ***
Library     squash_tf.TFParamService

...

*** Test Cases ***
Standard account creation
    ${gender} = Get Test Param  DS_gender
    ${first} =  Get Test Param  DS_first
    ${last} =   Get Test Param  DS_last
    ${password} =   Get Test Param  DS_password
    ${mail} =   Get Test Param  DS_mail
    ${birth} =  Get Test Param  DS_birth
    ${offers} = Get Test Param  DS_offers
    ${privacy} =    Get Test Param  DS_privacy
    ${news} =   Get Test Param  DS_news
    ${gpdr} =   Get Test Param  DS_gpdr

    ...
Afin d'exécuter ces tests sur son environnement, Antonine doit faire quelques changements Tout d'abord, elle les duplique dans le dossier tests\bdd_duplicates folder, afin de ne pas toucher aux fichiers .robot utilisés par Squash. Dans les fichiers dupliqués, elle ajoute ensuite une section *** Variables *** et supprime le ${data} = Get Test Param DS_data :

*** Settings ***

*** Variables ***
${gender}    F
${first}    Alice
${last}    Bob
${password}    Pass1234
${mail}    alice.bob@mail.fr
${birth}    10/08/1998
${offers}    yes
${privacy}    yes
${news}    yes
${gpdr}    yes

*** Test Cases ***
Standard account creation
    ...
Pour tous les autres types de tests, Antonine peut directement exécuter le fichier .robot généré par Squash TM.

Docstring

Fabrice peut également utiliser les docstrings pour ajouter des multi-lignes ou de longues chaînes de caractères aux tests :

test case 3

La docstring est gérée par Squash TM en déclarant une variable et en lui assignant la valeur du texte :

*** Test Cases ***
Navigate to one product
    ${docstring_1} =    Set Variable    Le meilleur reste à venir ! Faites parler vos murs avec cette affiche encadrée chargée d'optimisme sera du plus bel effet dans un bureau ou un open-space. Cadre en bois peint avec passe-partout integré pour un effet de profondeur.

    ...

    When I navigate to category "art"
    And I navigate to product "Affiche encadrée The best is yet to come"
    Then The product description is "${docstring_1}"

    ...

Dans le cas d'une docstring multi-ligne telle que :

    Le meilleur reste à venir !
    Faites parler vos murs avec cette affiche encadrée chargée d'optimisme sera du plus bel effet dans un bureau ou un open-space.
    Cadre en bois peint avec passe-partout integré pour un effet de profondeur.

Squash TM génère un fichier robot en utilisant \n :

*** Test Cases ***
Navigate to one product
    ${docstring_1} =    Set Variable    Le meilleur reste à venir !\nFaites parler vos murs avec cette affiche encadrée chargée d'optimisme sera du plus bel effet dans un bureau ou un open-space.\nCadre en bois peint avec passe-partout integré pour un effet de profondeur.

Antonine implémente The product description is "${docstring_1}" comme indiqué dans les sections Paramètres et Jeux de données ci-dessus.

Tables de données

Fabrice a également utilisé des tables de données pour ajouter des données aux tests :

test case 2

La table de données a été extraite et convertie dans la syntaxe Robot Framework par Squash TM :

*** Settings ***
Resource    squash_resources.resource

...

*** Test Cases ***
Add two products in the cart
    ${row_1_1} =    Create List    Product    Number    Dimension
    ${row_1_2} =    Create List    Affiche encadrée The best is yet to come    1    40x60cm
    ${row_1_3} =    Create List    Illustration vectorielle Renard    1
    ${datatable_1} =    Create List    ${row_1_1}    ${row_1_2}    ${row_1_3}

    ...

    Then the cart contains "${datatable_1}"

    ...

Les tables de données sont gérées ligne par ligne : Squash TM génère une liste de chaînes de caractères pour chaque ligne, appelée ${row_1_*}. La liste ${datatable_1} est une liste de toutes les lignes, autrement dit, une liste de listes, la première ligne étant une liste des étiquettes d'entêtes.

Antonine a plusieurs façons de gérer cette entrée, elle choisit de la convertir d'une liste de listes en une liste de dictionnaires. Elle ajoute la méthode dans le fichier resources/helpers/datatable_helper.resource :

*** Keywords ***
Create ListOfDictionary From Datatable
    [Arguments]    ${datatable}
    [Documentation]    Convert a list of lists to a list of dictionaries.
    ...                Example of input from Squash TM's BDD datatable (list of lists):
    ...                ['['name', 'firstName', 'age']', '['Doe', 'Alice', '12']', '['Smith', 'John', '45']']
    ...                Output (list of dictionaries):
    ...                {'{'name': 'Doe', 'firstName': Alice, 'age': '12'}',
    ...                 '{'name': 'Smith', 'firstName': 'John', 'age': '45'}']

    ${datatable_size} =    Get Length    ${datatable}
    @{final_list} =    Create List
    FOR    ${i}    IN RANGE    1    ${datatable_size}    1
        ${nb_items} =    Get Length    ${datatable}[${i}]
        &{dict} =    Create Dictionary
        FOR    ${j}    IN RANGE    0    ${nb_items}    1
            Set To Dictionary    ${dict}    ${datatable}[0][${j}]=${datatable}[${i}][${j}]
        END
        Append To List    ${final_list}    ${dict}
    END
    RETURN    @{final_list}

Ensuite, Antonine implémente facilement le Then the cart contains "${datatable_1}", en utilisant ses données structurées :

*** Keywords ***
The Cart contains "${datatable}"
    [Documentation]    Checks that specified products are found in the cart.
    @{products} =  Create ListOfDictionary From Datatable  ${datatable}
    Go To The Cart Page
    Products Should Be In Cart  @{products}

Ecriture des page objects

Antonine crée un page object pour chaque page utilisée par les pas de test, dans le dossier resources/page_objects. Un page object contient une section *** Variables *** avec les localisateurs et une section *** Keywords *** où les mots-clés utilisés dans les pas de test sont implémentés. Par exemple, le page object de la page de connexion est :

*** Settings ***
Documentation    Login page object
Library    Browser


*** Variables ***
&{log_locators}    create_account_link=//a[contains(@href, "connexion?create_account=1")]
...                login_button=//*[@id="submit-login"]
...                email_field=//*[@id="field-email"]
...                password_field=//*[@id="field-password"]


*** Keywords ***
Clear Login Fields
    [Documentation]    Clear all login fields.
    Clear Text    ${log_locators}[email_field]
    Clear Text    ${log_locators}[password_field]

Fill Login Fields
    [Arguments]    ${email}    ${password}
    [Documentation]    Logs a user on the website using specified values.
    Type Text    ${log_locators}[email_field]    ${email}
    Type Text    ${log_locators}[password_field]    ${password}

Submit Login
    [Documentation]    Initiate login.
    Click    ${log_locators}[login_button]

Error Message Should Be Displayed
    [Arguments]    ${message}
    [Documentation]    Checks that the specified error message is displayed.
    Get Element    //li[text()="${message}"]

Go To The AccountCreation Page
    [Documentation]    Navigates to the AccountCreation page.
    Click    ${log_locators}[create_account_link]

Encapsulation dans Robot Framework

Un mot-clé peut dépendre de plusieurs page objects. Ainsi, pour éviter toute ambiguïté, Antonine a choisi de stocker toutes les variables de type localisateur dans un dictionnaire avec un nom de variable unique clairement identifiable. Dans la login-page, ce dictionnaire est appelé &{log_locators}.

Implémentation des mots-clés de Robot Framework (pas de test)

Les fichiers resources/step_definitions/* contiennent les définitions des pas de test Robot Framework.

Il existe trois types de pas :

Given

Un pas Given est utilisé pour établir une précondition de test.
Il peut naviguer et interagir avec plusieurs pages afin de préparer les données nécessaires. Il peut même configurer les données en contournant l'interface utilisateur de l'application : en appelant l'API REST fournie par l'application, en injectant des données dans la base de données de l'application…
Un pas Given n'a pas besoin d'être sur une page particulière pour être appelé.

Par exemple, certains cas de test doivent commencer par la page AccountCreation. Ce pas de test est implémenté en naviguant vers la page AccountCreation et en vérifiant que la navigation a réussi (fichier resources/step_definitions/account_management) :

*** Settings ***
Resource    ../page_objects/header_page.resource
Resource    ../page_objects/login_page.resource
Resource    ../page_objects/account_creation_page.resource


***Keywords*** 
I am on the AccountCreation page
    [Documentation]    Navigates to the AccountCreation page
    Go To The SignIn Page
    Go To The AccountCreation Page
    Page Should Be AccountCreation Page

La vérification de la réussite de la navigation est effectuée par le mot-clé Page Should Be AccountCreation Page, implémenté dans resources/page_objects/account_creation_page.resource en vérifiant à la fois le titre de la page et celui de l'onglet :

*** Variables ***
&{acc_locators}    page_title=//h1[contains(text(), "Créez votre compte")]
...                mister_rb=//*[@id="field-id_gender-1"]
...                miss_rb=//*[@id="field-id_gender-2"]
...                first_name_field=//*[@id="field-firstname"]
...                last_name_field=//*[@id="field-lastname"]
...                email_field=//*[@id="field-email"]
...                password_field=//*[@id="field-password"]
...                birth_date_field=//*[@id="field-birthday"]
...                privacy_cb=//*[@name="customer_privacy"]
...                gpdr_cb=//*[@name="psgdpr"]
...                news_cb=//*[@name="newsletter"]
...                offers_cb=//*[@name="optin"]
...                validate_button=//*[@id="customer-form"]/footer/button


***Keywords*** 
Page Should Be AccountCreation Page
    [Documentation]    Checks if we are on the AccountCreation page.
    Get Title    ==    Identifiant
    Get Element    ${acc_locators}[page_title]

When

Un pas When exécute une action.

Par exemple, le code mis en œuvre par le mot-clé I sign in with email ${mail} and password ${password} est :

*** Keywords ***
I sign in with email ${mail} and password ${password}
    [Documentation]    Logs a user.
    ${mail} =    Remove Framing Quotes From Parameter  ${mail}
    ${password} =    Remove Framing Quotes From Parameter  ${password}

    Go To The SignIn Page
    Clear Login Fields
    Fill Login Fields  ${mail}  ${password}
    Submit Login

De nombreux pas de test When nécessitent d'être exécutés alors qu'une page donnée est affichée, ils vérifient donc que c'est bien le cas.
Par exemple, l'implémentation de I sign out est :

*** Keywords ***
I sign out
    [Documentation]    Logs out a user.
    Sign Out
    User Is Logged Out

La vérification que l'utilisateur est effectivement déconnecté est effectuée par le mot-clé User Is Logged Out, implémenté dans resources/page_objects/header_page.resource en vérifiant que le lien de connexion est à nouveau visible.

*** Variables ***
&{h_locators}    login_link=//a[@title="Identifiez-vous"]
...              logout_link=//a[contains(@href, "?mylogout=") and @class="logout hidden-sm-down"]
...              welcome_message=//a[@title="Voir mon compte client"]/span
...              cart_link=//span[text()="Panier"]
...              home_link=//img[@alt="Prestashop-Robot"]


*** Keywords ***
User Is Logged In
    [Arguments]    ${first_name}    ${last_name}
    [Documentation]    Checks that the specified user is logged in.
    Get Text    ${h_locators}[logout_link]    *=    Déconnexion
    Get Text    ${h_locators}[welcome_message]    ==    ${first_name} ${last_name}

Then

Un pas Then est utilisé pour vérifier qu'une postcondition de test est remplie.
Il peut naviguer et interagir avec plusieurs pages afin de vérifier que les données sont conformes aux attentes. Il peut même récupérer les données en contournant l'interface utilisateur de l'application : en appelant l'API REST fournie par l'application, en interrogeant la base de données de l'application…
Un pas Then n'a pas besoin d'être sur une page particulière pour être appelé.

Par exemple, l'implémentation du mot-clé Then My personal informations are gender ${gender} firstName ${first} lastName ${last} email ${mail} birthDate ${birth} est réalisée en affichant la page des données personnelles, en récupérant les valeurs des champs et en vérifiant qu'elles ont les valeurs attendues :

*** Keywords ***
My personal informations are gender ${gender} firstName ${first} lastName ${last} email ${mail} birthDate ${birth}
    [Documentation]    Checks if the specified values match the personal informations of a logged user.
    ${gender} =    Remove Framing Quotes From Parameter  ${gender}
    ${first} =    Remove Framing Quotes From Parameter  ${first}
    ${last} =    Remove Framing Quotes From Parameter  ${last}
    ${mail} =    Remove Framing Quotes From Parameter  ${mail}
    ${birth} =    Remove Framing Quotes From Parameter  ${birth}
    Go To The MyAccount Page
    Page Should Be MyAccount Page
    Go To The Identity Page
    Private Informations Should Be  ${gender}  ${first}  ${last}  ${mail}  ${birth}

La vérification des informations est effectuée par le mot-clé Private Informations Should Be, implémenté dans resources/page_objects/identity_page.resource en vérifiant les valeurs de tous les paramètres spécifiés :

*** Variables ***
&{id_locators}    mister_rb=//*[@id="field-id_gender-1"]
...               miss_rb=//*[@id="field-id_gender-2"]
...               first_name_field=//*[@id="field-firstname"]
...               last_name_field=//*[@id="field-lastname"]
...               email_field=//*[@id="field-email"]
...               birth_date_field=//*[@id="field-birthday"]
...               submit_button=//*[@id="customer-form"]/footer/button
...               privacy_cb=//*[@name="customer_privacy"]
...               gpdr_cb=//*[@name="psgdpr"]
...               old_password_field=//*[@id="field-password"]
...               new_password_field=//*[@id="field-new_password"]


*** Keywords ***
Private Informations Should Be
    [Arguments]   ${gender}  ${first}  ${last}  ${mail}  ${birth}
    [Documentation]    Checks that the specified values match the personal informations of a logged user.

    &{gender_M} =     Create Dictionary    label=M    rb=${id_locators}[mister_rb]
    &{gender_F} =     Create Dictionary    label=F    rb=${id_locators}[miss_rb]
    @{genders} =    Create List    ${gender_M}    ${gender_F}

    Verify Selected Radiobutton    ${gender}     @{genders}

    Get Attribute    ${id_locators}[first_name_field]    value    ==    ${first}
    Get Attribute    ${id_locators}[last_name_field]    value    ==    ${last}
    Get Attribute    ${id_locators}[email_field]    value    ==    ${mail}
    Get Attribute    ${id_locators}[birth_date_field]    value    ==    ${birth}

Linter Robocop

Antonine utilise le linter Robocop (un linter est un analyseur de code statique) pour s'assurer que son code est propre :

Installation

Antonine installe Robocop comme décrit dans la documentation Robocop :

pip install robotframework-robocop

Utilisation

Ensuite, pour analyser le code d'un fichier ou d'un dossier, Antonine exécute :

robocop [path 1] [path 2] [path n]
avec les chemins des fichiers et/ou dossiers qu'elle veut que Robocop analyse.

Avertissements Robocop

Le code Robot Framework généré par Squash TM peut déclencher quelques avertissements de Robocop, dont certains devraient être corrigés dans les prochaines versions. En ce qui concerne le code Robot Framework écrit par Antonine, de bonnes pratiques de codage devraient permettre d'éviter les avertissements, à l'exception de ceux résultant de la façon dont Squash TM génère ses fichiers robot :

  • wrong-case-in-keyword-name : les pas de test BDD ne sont pas écrits en title case (c'est-à-dire en utilisant une majuscule pour la première lettre de chaque mot).
  • line-too-long : Squash TM permet d'écrire des pas de test jusqu'à 255 caractères alors que Robocop recommande moins de 120 caractères.
  • too-long-test-case : Squash TM permet d'écrire des tests comprenant de nombreux pas, alors que Robocop recommande moins de 20 pas.

Antonine peut ignorer ces avertissements, ou bien elle peut configurer son projet pour ignorer certaines règles ou certains fichiers robot comme détaillé dans la documentation Robocop sur l'inclusion et l'exclusion de règles.

Livraison des cas de test automatisés

Annita
Administratrice Squash TM
Pravash
Product owner
Fabrice
Testeur fonctionnel
Antonine
Automaticienne
Configurer Squash TM
Rédiger les exigences
Rédiger les cas de test
Transmettre les cas de test
Récupérer les cas de test
Automatiser les cas de test
Fournir les cas de test automatisés
Indiquer que l'automatisation est effectuée
Exécuter les tests automatisés

Antonine est maintenant prête à exécuter le test sur son environnement local :

robot <test.robot>
et vérifier le rapport Robot Framework (fichier /report.html) :

Robotframework report

et le journal Robot Framework (fichier /log.html) :

Robotframework report

Lorsqu'elle trouve quelque chose de suspect lors de l'automatisation d'un test, elle effectue le test manuellement et, s'il y a vraiment un bug, elle le signale comme décrit dans la documentation.

Lorsque les tests se déroulent correctement, elle commite et pousse :

git add .
git commit -m "Implemented first account and cart steps"
git push

Indication que l'automatisation a été effectuée

Annita
Administratrice Squash TM
Pravash
Product owner
Fabrice
Testeur fonctionnel
Antonine
Automaticienne
Configurer Squash TM
Rédiger les exigences
Rédiger les cas de test
Transmettre les cas de test
Récupérer les cas de test
Automatiser les cas de test
Fournir les cas de test automatisés
Indiquer que l'automatisation est effectuée
Exécuter les tests automatisés

Ensuite, à l'aide de l'onglet "M'étant assigné" de l'Espace Automatisation (voir la documentation), Antonine indique que les tests ont été automatisés :

test case automation done