Préparation entretien · 227 questions

Questions d'entretien automatisation des tests

Mis à jour

Selenium, Playwright, conception de framework et les questions sur les tests instables qui séparent quelqu'un qui a maintenu une suite de quelqu'un qui n'en a écrit qu'une.

55 questions

Comment décidez-vous quoi automatiser et quoi laisser en manuel ?

Stratégie d'automatisationjuniormidsenior

Automatisez ce qui tourne souvent contre un comportement stable avec un pass/fail objectif : régression, smoke, répétitions à forte charge de données, contrats d'API.

Automatisez ce qui tourne souvent contre un comportement stable avec un pass/fail objectif : régression, smoke, répétitions à forte charge de données, contrats d'API. Gardez en manuel ce qui demande du jugement ou change sans cesse : le travail exploratoire, le visuel, l'utilisabilité, les fonctionnalités toutes neuves en pleine évolution.

Le test de ROI en une ligne : le coût d'écrire et de maintenir ceci sera-t-il remboursé par les exécutions ?

Exemple concret

Chemin nominal du checkout : tourne à chaque build, stable depuis un an, résultat binaire — automatisé depuis longtemps. Le nouveau panneau de suggestions IA : redessiné deux fois par mois, la qualité est une affaire de jugement — encore manuel, à dessein. Même produit, décisions opposées, les deux correctes.

Points clés
  • Automatiser : répété + stable + objectif
  • Manuel : jugement ou évolution
  • ROI = coût d'écriture vs nombre d'exécutions
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

« Automatiser tout ce qui est répétitif » sans mentionner le coût de maintenance — la maintenance est là où les budgets d'automatisation meurent vraiment.

Copier le lien

Qu'est-ce qui ne devrait PAS être automatisé ?

Stratégie d'automatisationjuniormid

Le test exploratoire (sa valeur est le jugement humain), l'utilisabilité et l'attrait visuel, les fonctionnalités qui changent encore chaque semaine, les vérifications ponctuelles, les flux de type…

Le test exploratoire (sa valeur est le jugement humain), l'utilisabilité et l'attrait visuel, les fonctionnalités qui changent encore chaque semaine, les vérifications ponctuelles, les flux de type CAPTCHA/2FA conçus pour résister aux machines, et tout ce dont l'automatisation coûterait plus qu'elle ne rapporte.

Savoir quoi sauter est la différence entre une suite et un fardeau.

Exemple concret

On a automatisé une fois la mise en page visuelle d'une facture PDF — des comparaisons de pixels. Ça échouait à chaque mise à jour de police, chaque différence de rendu selon l'OS, chaque ajustement de design légitime : des dizaines de fausses alertes, zéro vrai bug. Supprimé après deux mois ; un coup d'œil humain par release faisait mieux.

Points clés
  • Exploration, visuels, évolution, ponctuels
  • Les flux anti-bots résistent par conception
  • Coût > retour = sauter
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Une liste vide. « Tout peut être automatisé avec de l'effort » dit à l'examinateur que vous n'avez jamais payé une facture de maintenance.

Copier le lien

Comment calculez-vous ou défendez-vous le ROI de l'automatisation des tests ?

Stratégie d'automatisationmidsenior

Honnêtement : coût = écriture + maintenance + infrastructure ; retour = temps d'exécution manuelle économisé × exécutions, plus un feedback plus rapide et des bugs attrapés avant la release.

Honnêtement : coût = écriture + maintenance + infrastructure ; retour = temps d'exécution manuelle économisé × exécutions, plus un feedback plus rapide et des bugs attrapés avant la release. Si une suite tourne à chaque build, même des tests coûteux remboursent vite ; un test qui tourne trimestriellement peut ne jamais se rembourser.

La version senior : le plus grand retour de l'automatisation est la vitesse de release — une régression qui prenait une semaine prend maintenant une heure, donc vous livrez chaque semaine.

Exemple concret

L'argument qui a obtenu le budget : notre régression manuelle de 3 jours tournait mensuellement — 36 jours-testeur par an, et les releases faisaient la queue derrière. La suite a coûté ~20 jours à construire, un jour par mois à maintenir, et a permis à la régression de tourner la nuit. Elle s'est remboursée avant la fin de l'année — et les releases ont cessé de faire la queue.

Points clés
  • Coût : écrire + maintenir + infra
  • Retour : temps × exécutions + vitesse
  • La vitesse de feedback est le vrai prix
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Inventer une formule précise avec des chiffres bidon. Les examinateurs préfèrent les leviers honnêtes plus une vraie histoire de retour sur investissement.

Copier le lien

Expliquez l'architecture de Selenium. Que se passe-t-il réellement quand vous appelez driver.click() ?

Selenium (cœur)midsenior

Votre code parle à un driver de navigateur (chromedriver, geckodriver) via le protocole W3C WebDriver — des requêtes HTTP portant du JSON.

Votre code parle à un driver de navigateur (chromedriver, geckodriver) via le protocole W3C WebDriver — des requêtes HTTP portant du JSON. driver.click() devient un POST au serveur local du driver ; le driver le traduit dans les internes d'automatisation propres au navigateur, le navigateur agit, et la réponse revient.

Selenium 4 a rendu le W3C natif, abandonnant l'ancienne couche de traduction JSON Wire.

Exemple concret

Pourquoi ça compte au-delà de l'anecdote : ce saut HTTP est pourquoi les actions Selenium ont de la latence, pourquoi une paire chromedriver/Chrome incompatible casse tout, et pourquoi Playwright — qui garde un socket persistant vers le navigateur au lieu d'un HTTP par commande — semble plus rapide et est moins instable sur le timing.

Points clés
  • Code → driver (HTTP/W3C) → navigateur
  • click() = POST au driver
  • Selenium 4 = W3C natif
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Réciter « Selenium a quatre composants » sans savoir tracer un seul clic de bout en bout.

Copier le lien

Quelles stratégies de locators Selenium supporte-t-il, et comment choisir ?

Sélecteurs (locators)juniormid

ID, name, sélecteur CSS, XPath, texte du lien, texte partiel du lien, nom de balise, nom de classe. Le choix est un classement de stabilité : un test id dédié d'abord, puis ID, puis name, puis un…

ID, name, sélecteur CSS, XPath, texte du lien, texte partiel du lien, nom de balise, nom de classe. Le choix est un classement de stabilité : un test id dédié d'abord, puis ID, puis name, puis un court sélecteur CSS ancré à quelque chose de significatif, XPath là où vous avez besoin de texte ou de parcourir le DOM.

Le principe : localiser par ce que l'élément EST, pas par où il se trouve.

Exemple concret

Le même bouton, trois façons : [data-testid=checkout-submit] survit aux refontes ; #submit-btn survit à la plupart des changements ; div.cart > div:nth-child(3) > button meurt le jour où une bannière est ajoutée au-dessus. Les trois « marchent » le premier jour — seuls les deux premiers marchent au sixième mois.

Points clés
  • Test id > ID > name > CSS > XPath
  • Le sens plutôt que la position
  • nth-child = casse future
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Classer par ce qui est le plus facile à écrire au lieu de ce qui survit au changement — l'examinateur pose la question sur le sixième mois, pas le premier jour.

Copier le lien

Sélecteurs CSS vs XPath — lequel préférez-vous et pourquoi ?

Sélecteurs (locators)juniormid

CSS par défaut : plus court, plus lisible, marginalement plus rapide, et il correspond à la façon dont les développeurs pensent le DOM.

CSS par défaut : plus court, plus lisible, marginalement plus rapide, et il correspond à la façon dont les développeurs pensent le DOM. XPath pour les deux choses que CSS ne peut pas faire — la correspondance sur le contenu textuel et le parcours vers le haut vers un parent ou de côté vers un frère.

Ce n'est pas une guerre ; c'est un défaut plus un outil pour les exceptions.

Exemple concret

Trouver le bouton de suppression dans la ligne qui contient « John Smith » : CSS ne voit pas le texte, donc XPath gagne sa place — //tr[td[text()='John Smith']]//button[@aria-label='Delete']. Pour tout le reste sur cette page, les versions CSS font la moitié de la longueur et sont deux fois plus lisibles.

Points clés
  • CSS par défaut : plus court, lisible
  • XPath : correspondance de texte + parcours vers le haut
  • Défaut + exception, pas une guerre
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Une réponse religieuse pour l'un ou l'autre camp. La réponse senior est « CSS par défaut, XPath pour le texte et les parents ».

Copier le lien

Quelle est la différence entre XPath absolu et relatif ?

Sélecteurs (locators)junior

Absolu part de la racine et parcourt chaque étape : /html/body/div[2]/div/form/input — un seul changement de DOM n'importe où sur le chemin le casse.

Absolu part de la racine et parcourt chaque étape : /html/body/div[2]/div/form/input — un seul changement de DOM n'importe où sur le chemin le casse. Relatif part de n'importe où de significatif avec // : //input[@name='email'].

Un XPath absolu dans une revue de code est un commentaire automatique ; il n'y a aucune situation où c'est le bon choix.

Exemple concret

Copy-XPath dans DevTools vous donne le chemin absolu — c'est comme ça qu'ils finissent dans les bases de code. Le jour où le marketing ajoute un div de bannière de cookies en haut du body, chaque /html/body/div[2]/... de la suite meurt d'un coup. Le //input[@name='email'] relatif ne le remarque même pas.

Points clés
  • Absolu : chemin complet, fragile
  • Relatif : // + attributs
  • Le copy-XPath de DevTools = la source du péché
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Seulement les définir. Dites la conséquence : l'absolu casse à tout changement de mise en page, donc il ne passe jamais la revue.

Copier le lien

Comment gérez-vous les éléments dynamiques dont les IDs changent à chaque chargement de page ?

Sélecteurs (locators)mid

Ancrez à ce qui ne change pas : les correspondances partielles d'attributs (starts-with, contains) pour le préfixe stable d'un ID généré, d'autres attributs stables (name, role, aria-label,…

Ancrez à ce qui ne change pas : les correspondances partielles d'attributs (starts-with, contains) pour le préfixe stable d'un ID généré, d'autres attributs stables (name, role, aria-label, placeholder), un texte stable, ou un ancêtre stable. Le meilleur correctif de tous : faire ajouter des test ids.

N'ancrez jamais à la partie aléatoire — c'est écrire l'instabilité de demain aujourd'hui.

Exemple concret

App React générant id='input-4f7a2' : la moitié stable est le préfixe — css=[id^='input-'] cadré dans #login-form. Mieux, le champ avait name='email' depuis le début. Le mieux, un PR plus tard il avait data-testid='login-email' et le problème de locator a cessé d'exister.

Points clés
  • starts-with/contains sur la partie stable
  • Préférez les attributs sémantiques
  • Vrai correctif : demander des test ids
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Faire une correspondance regex sur la partie aléatoire — ancrer exactement à la chose qui change.

Copier le lien

Expliquez les attentes implicites, explicites et fluent. Lesquelles utilisez-vous ?

Attentes & synchronisationjuniormidsenior

Implicite : un réglage global — interroge le DOM pour toute recherche d'élément. Explicite : attendre une condition précise sur un élément précis — cliquable, visible, texte présent.

Implicite : un réglage global — interroge le DOM pour toute recherche d'élément. Explicite : attendre une condition précise sur un élément précis — cliquable, visible, texte présent. Fluent : explicite plus un intervalle d'interrogation personnalisé et des exceptions ignorées.

Utilisez les attentes explicites, toujours. Ne mélangez jamais implicite et explicite — les timeouts interagissent de façon imprévisible et produisent des délais mystérieux.

Exemple concret

Une suite mélangeant une attente implicite de 10 s avec des attentes explicites avait des vérifications qui prenaient 40 secondes à échouer — les deux mécanismes se cumulaient. Passé l'attente implicite à zéro, tout en explicite : même suite, échecs en secondes, et les délais mystérieux ont disparu.

Points clés
  • Explicite = condition sur l'élément
  • Ne jamais mélanger implicite + explicite
  • Playwright auto-attend (actionnabilité)
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Ne pas connaître le problème du mélange — « j'utilise les deux » est la réponse qui échoue à cette question.

Copier le lien

Pourquoi Thread.sleep() (ou time.sleep()) est-il considéré comme une mauvaise pratique ?

Attentes & synchronisationjunior

Il attend un temps fixe quelle que soit la réalité — trop court un jour lent (échec instable), trop long un jour rapide (minutes gaspillées, à chaque exécution, pour toujours).

Il attend un temps fixe quelle que soit la réalité — trop court un jour lent (échec instable), trop long un jour rapide (minutes gaspillées, à chaque exécution, pour toujours). Une attente conditionnelle sort dès que la condition est vraie et échoue bruyamment quand elle ne l'est jamais.

Les sleeps cachent aussi la vraie question : QU'attendez-vous ? Nommez-le, attendez-le.

Exemple concret

L'audit d'une suite de 400 tests a trouvé 130 sleeps de 3 secondes en moyenne : six minutes et demie de pure attente par exécution, quarante exécutions par jour. Les remplacer par des attentes conditionnelles a réduit le temps d'exécution d'un quart — et corrigé deux instabilités dont les sleeps étaient « généralement assez longs ».

Points clés
  • Temps fixe vs condition réelle
  • Jour lent = instabilité, jour rapide = gaspillage
  • Nommez ce que vous attendez
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

« Ça ralentit les tests » comme seule raison — le péché plus profond est le non-déterminisme : les sleeps sont pourquoi la suite ment.

Copier le lien

Qu'est-ce qui cause une StaleElementReferenceException et comment la corriger ?

Attentes & synchronisationmid

Vous déteniez une référence à un élément, puis le DOM s'est re-rendu — votre référence pointe vers un nœud qui n'existe plus.

Vous déteniez une référence à un élément, puis le DOM s'est re-rendu — votre référence pointe vers un nœud qui n'existe plus. Classique après des clics qui rafraîchissent une liste, des re-rendus de SPA, ou toute mise à jour AJAX.

Correctif : re-trouver l'élément après le changement, ne pas mettre en cache les références d'éléments à travers les mises à jour de page, et attendre la fin du re-rendu avant de re-trouver.

Exemple concret

Boucler sur les lignes d'un tableau, cliquer « archiver » sur chacune : le premier clic réussit, le second lève une exception stale — le clic a re-rendu tout le tableau, et les références de lignes sauvegardées par la boucle sont mortes avec. Correctif : re-interroger les lignes à chaque itération, ou archiver par un locator frais à chaque fois.

Points clés
  • DOM re-rendu sous votre référence
  • Re-trouver, ne pas mettre en cache
  • Courant dans les boucles sur des listes
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

La demi-réponse « l'élément a été supprimé » — le point est que VOTRE RÉFÉRENCE est morte ; l'élément est souvent juste là, re-rendu.

Copier le lien

Qu'est-ce que le Page Object Model et pourquoi l'utiliser ?

Page Object Modeljuniormid

Un design pattern : chaque page (ou composant) reçoit une classe contenant ses locators et les actions que vous effectuez dessus ; les tests appellent ces méthodes et se lisent comme des scénarios,…

Un design pattern : chaque page (ou composant) reçoit une classe contenant ses locators et les actions que vous effectuez dessus ; les tests appellent ces méthodes et se lisent comme des scénarios, pas comme de la chirurgie du DOM.

Le gain est un seul endroit à corriger : quand la page de connexion change, vous mettez à jour LoginPage, pas quarante tests.

Exemple concret

Une refonte a déplacé le formulaire de connexion dans une modale. Suite avec POM : un fichier changé, vert avant midi. Les anciens scripts sans lui : les mêmes trois locators collés à travers 40 tests, deux jours de rechercher-remplacer, et une semaine de retardataires échouant un par un.

Points clés
  • Une classe par page : locators + actions
  • Les tests se lisent comme des scénarios
  • Un changement = un fichier
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Le définir sans l'argument de maintenance — « un seul endroit à corriger » EST la réponse.

Copier le lien

Qu'est-ce qui appartient à un page object et qu'est-ce qui appartient au test ?

Page Object Modelmidsenior

Page object : locators, actions (login(user, pass)), lecteurs d'état (getErrorText()). Test : le scénario et chaque assertion — arranger, agir via les méthodes de page, affirmer sur ce que la page…

Page object : locators, actions (login(user, pass)), lecteurs d'état (getErrorText()). Test : le scénario et chaque assertion — arranger, agir via les méthodes de page, affirmer sur ce que la page rapporte.

La ligne qui compte : les page objects renvoient l'état ; les tests le jugent. Des assertions dans les page objects cachent ce qu'un test vérifie réellement.

Exemple concret

loginPage.login(user, wrongPass) puis expect(loginPage.getError()).toContain('Invalid') — le test énonce l'attente. L'anti-version, loginPage.loginAndVerifyError(), enterre l'assertion là où personne lisant le test ne peut voir ce qui est vérifié — et où chaque test en hérite qu'il le veuille ou non.

Points clés
  • Pages : locators + actions + getters
  • Tests : scénarios + TOUTES les assertions
  • Les pages renvoient, les tests jugent
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Des assertions dans les page objects — le smell classique de niveau intermédiaire que cette question existe pour détecter.

Copier le lien

Décrivez-moi l'architecture d'un framework d'automatisation que vous avez construit.

Conception de frameworkmidsenior

Ayez une histoire en couches prête : config par environnement ; une fabrique de driver/navigateur ; page objects et composants ; un client d'API pour la mise en place et le nettoyage ; des builders…

Ayez une histoire en couches prête : config par environnement ; une fabrique de driver/navigateur ; page objects et composants ; un client d'API pour la mise en place et le nettoyage ; des builders de données de test ; les tests eux-mêmes — fins, en forme de scénario ; et le reporting avec des artefacts en cas d'échec, câblé dans la CI.

Puis une décision de conception que vous pouvez défendre : pourquoi les fixtures plutôt que l'héritage, pourquoi la mise en place via l'API d'abord, pourquoi des données parallèle-safe.

Exemple concret

La décision que les examinateurs creusent dans la mienne : la connexion se fait via l'API une fois par worker, injectée comme état de session — le test de connexion UI existe séparément, et chaque autre test démarre connecté. Ce seul choix a réduit le temps de la suite d'un tiers et supprimé la source d'instabilité la plus répétée.

Points clés
  • Couches : config → driver → pages → données → tests → reporting
  • Tests fins, support épais
  • Défendez une vraie décision
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Nommer des outils au lieu de la structure. « Selenium, TestNG, Allure » est une liste de courses — les couches et les décisions sont l'architecture.

Copier le lien

Quels sont les principaux types de framework d'automatisation ?

Conception de frameworkjuniormid

La liste du manuel : linéaire (enregistrement/rejeu), modulaire, piloté par les données (même test, jeux de données externes), piloté par mots-clés (actions comme mots-clés de tableur), hybride…

La liste du manuel : linéaire (enregistrement/rejeu), modulaire, piloté par les données (même test, jeux de données externes), piloté par mots-clés (actions comme mots-clés de tableur), hybride (mélange), et à couche BDD (Gherkin par-dessus).

L'ajout honnête : les vrais frameworks modernes sont des hybrides — page objects + cas pilotés par les données + fixtures. La taxonomie est du vocabulaire d'entretien plus qu'une réalité quotidienne.

Exemple concret

Notre « type » ? Structure en page objects, pytest parametrize alimentant 40 cas limites depuis des données (piloté par les données), une fine couche BDD sur exactement les cinq flux que les parties prenantes métier lisent vraiment, tout le reste en code simple. Nommer un seul seau pour ça raterait la conception.

Points clés
  • Linéaire, modulaire, piloté par données/mots-clés, hybride, BDD
  • Réalité : tout est hybride
  • Dites ce que le VÔTRE mélange et pourquoi
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Réciter les six types avec fierté et sans opinion — la relance « lequel est le vôtre ? » l'expose immédiatement.

Copier le lien

Comment implémentez-vous les tests pilotés par les données ?

Tests pilotés par les donnéesjuniormid

Un corps de test, plusieurs jeux de données : le runner injecte les lignes — @parametrize de pytest, @DataProvider de TestNG, @ParameterizedTest de JUnit 5 — depuis des tables en ligne, des fichiers…

Un corps de test, plusieurs jeux de données : le runner injecte les lignes — @parametrize de pytest, @DataProvider de TestNG, @ParameterizedTest de JUnit 5 — depuis des tables en ligne, des fichiers CSV/JSON, ou des builders.

Chaque ligne doit se rapporter comme son propre résultat de test nommé : « boundary_18 passé, boundary_17 échoué » — pas un seul test qui cache laquelle des quarante entrées a cassé.

Exemple concret

Règles de remise : un test de checkout, une table de 30 lignes — code, valeur du panier, niveau utilisateur, prix attendu. Nouvelle règle ? Nouvelle ligne, pas de nouveau code. Quand VIP50 a cassé, le rapport disait exactement cette ligne — la conversation de correction a commencé par le seul nom de l'échec.

Points clés
  • Un corps, lignes injectées
  • parametrize / DataProvider
  • Chaque ligne = résultat nommé
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Une boucle dans un seul test — quarante entrées, une ligne de résultat, et aucune idée de quelle ligne a échoué.

Copier le lien

Expliquez les annotations TestNG et l'ordre dans lequel elles s'exécutent.

Test runnersjuniormid

De l'extérieur vers l'intérieur, de la suite à la méthode : @BeforeSuite → @BeforeTest → @BeforeClass → @BeforeMethod → @Test → @AfterMethod → @AfterClass → @AfterTest → @AfterSuite.

De l'extérieur vers l'intérieur, de la suite à la méthode : @BeforeSuite → @BeforeTest → @BeforeClass → @BeforeMethod → @Test → @AfterMethod → @AfterClass → @AfterTest → @AfterSuite.

Chaque portée s'associe à ce qu'elle enveloppe : niveau suite pour une mise en place globale unique, niveau méthode pour un état par test comme un driver frais. Plus les incontournables : @DataProvider, groups, dependsOnMethods, enabled=false.

Exemple concret

Câblage typique : @BeforeSuite démarre le générateur de rapport, @BeforeClass se connecte une fois pour les tests de cette page, @BeforeMethod remet au dashboard pour que chaque test démarre égal, @AfterMethod prend une capture d'écran en cas d'échec. Mettre la création du driver au niveau suite au lieu du niveau méthode, c'est comme ça que les tests commencent à partager un état sale.

Points clés
  • Suite → Test → Class → Method, en miroir après
  • La portée correspond à la durée de vie de la mise en place
  • @AfterMethod = hook de capture d'écran
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Le mauvais ordre sous pression — répétez « suite, test, class, method » jusqu'à ce que ce soit un réflexe.

Copier le lien

Que sont les fixtures pytest et conftest.py ?

Test runnersmid

Les fixtures sont une mise en place/nettoyage par injection de dépendances : déclarez une fonction avec @pytest.fixture, demandez-la par nom de paramètre, yield la ressource, nettoyez après le yield.

Les fixtures sont une mise en place/nettoyage par injection de dépendances : déclarez une fonction avec @pytest.fixture, demandez-la par nom de paramètre, yield la ressource, nettoyez après le yield. Les portées contrôlent la durée de vie : function, class, module, session. conftest.py partage les fixtures à travers une arborescence de répertoires sans aucun import.

C'est de la composition plutôt que de l'héritage — la raison pour laquelle les frameworks pytest restent plats et lisibles.

Exemple concret

Une fixture browser (portée session) alimente une fixture logged_in_page (portée function) qui se connecte via l'API et yield une page prête ; les tests prennent juste logged_in_page en argument. Le teardown après le yield ferme proprement même en cas d'échec — pas de classe BaseTest, pas de chaînes de super().

Points clés
  • Injecter par nom de paramètre
  • yield = séparation mise en place/nettoyage
  • conftest.py = partagé, sans imports
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Expliquer les fixtures comme « les méthodes de setup de pytest » — en ratant l'injection, les portées et conftest, qui sont tout l'intérêt.

Copier le lien

TestNG vs JUnit — quelles sont les différences significatives ?

Test runnersmid

Historiquement TestNG l'emportait sur le XML de suite, les groups, le @DataProvider natif, les dépendances et la config parallèle — c'est pourquoi les frameworks de l'ère Selenium se sont…

Historiquement TestNG l'emportait sur le XML de suite, les groups, le @DataProvider natif, les dépendances et la config parallèle — c'est pourquoi les frameworks de l'ère Selenium se sont standardisés dessus. JUnit 5 a comblé la plupart des écarts : @ParameterizedTest, @Tag, extensions, exécution parallèle.

Aujourd'hui : les nouveaux projets Java pur vont souvent vers JUnit 5 (défaut de l'écosystème) ; les stacks d'automatisation existants restent sur TestNG — les deux vont bien, et le dire est la réponse senior.

Exemple concret

La différence encore réelle que je rencontre : le XML de suite de TestNG permet de composer exactement quels groupes tournent où — smoke sur les PR, complet la nuit — sans changement de code. JUnit 5 le fait avec des tags et la config de l'outil de build. Même résultat, endroit différent pour le câblage.

Points clés
  • TestNG : suites, groups, dépendances
  • JUnit 5 a comblé la plupart des écarts
  • Les deux vont bien — les raisons battent la religion
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Répondre depuis 2015 — prétendre que JUnit ne peut pas paramétrer ou taguer est instantanément daté.

Copier le lien

Quelle est la différence entre assertions dures et souples, et quand utilisez-vous chacune ?

Assertionsjuniormid

Les assertions dures arrêtent le test au premier échec — juste quand les étapes suivantes n'ont aucun sens sans que celle-ci passe.

Les assertions dures arrêtent le test au premier échec — juste quand les étapes suivantes n'ont aucun sens sans que celle-ci passe. Les assertions souples collectent tous les échecs et rapportent ensemble à la fin — juste quand vous vérifiez plusieurs faits indépendants sur un écran.

Les assertions souples DOIVENT se terminer par assertAll(), sinon elles passent silencieusement pour toujours.

Exemple concret

Page de confirmation de commande : soft-assert le nom, le total, l'adresse, la date de livraison — une exécution rapporte les quatre erreurs au lieu de corriger-relancer-corriger-relancer. Mais « la commande a été créée » est une assertion dure d'abord : s'il n'y a pas de commande, les quatre autres vérifications sont du bruit sur une page qui ne devrait pas exister.

Points clés
  • Dure : arrêter — barrières de flux
  • Souple : collecter — faits indépendants
  • assertAll() ou passage silencieux
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Ne pas mentionner assertAll() — l'examinateur pêche spécifiquement le mode de défaillance du passage silencieux.

Copier le lien

Qu'est-ce qui fait une bonne assertion ?

Assertionsmid

Elle vérifie le RÉSULTAT qui intéresse l'utilisateur, pas un détail d'implémentation ; elle est précise (la valeur, pas juste non-null) ; et elle échoue avec un message qui diagnostique — attendu vs…

Elle vérifie le RÉSULTAT qui intéresse l'utilisateur, pas un détail d'implémentation ; elle est précise (la valeur, pas juste non-null) ; et elle échoue avec un message qui diagnostique — attendu vs réel vs où.

Testez le comportement : après le checkout, affirmez que la commande existe avec le bon total — pas qu'un div a reçu une classe CSS.

Exemple concret

Faible : assertTrue(orders.size() > 0) — échoue comme « attendu true ». Forte : assertEquals(order.total, 49.99) avec contexte — échoue comme « le total était 54.99, attendu 49.99, commande #1042 ». Le second échec EST le rapport de bug ; le premier est un devoir à faire.

Points clés
  • Affirmez les résultats, pas les internes
  • Valeurs précises, pas non-null
  • Message d'échec = diagnostic
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Ne parler que de syntaxe. La question est vraiment « vos verts veulent-ils dire quelque chose ? »

Copier le lien

Qu'est-ce qui cause les tests instables ?

Tests instablesmid

Des courses entre le test et l'app : agir avant que le rendu/les données se stabilisent (timing), des tests partageant un état ou des données mutables, des dépendances d'ordre, une dérive…

Des courses entre le test et l'app : agir avant que le rendu/les données se stabilisent (timing), des tests partageant un état ou des données mutables, des dépendances d'ordre, une dérive d'environnement, des dépendances tierces en plein test, des animations — et parfois un vrai bug produit intermittent déguisé en instabilité.

Diagnostiquez avant de supposer : certains « tests instables » sont des tests corrects attrapant une vraie course.

Exemple concret

Notre test le plus instable échouait « aléatoirement » en affirmant un compteur de dashboard. Cause racine : il lisait le compteur avant que le rafraîchissement async atterrisse — parfois assez vite, parfois non. Le correctif n'était pas une nouvelle tentative ; c'était d'attendre que l'indicateur de chargement disparaisse. Le timing, comme d'habitude.

Points clés
  • Les courses de timing = cause n°1
  • État partagé et dépendances d'ordre
  • Certaines instabilités sont de vrais bugs
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

« Les tests instables sont des tests mal écrits » — parfois le test va bien et le produit court. Rater ça, c'est rater de vrais bugs.

Copier le lien

Vous avez 50 tests instables et l'équipe ignore maintenant les builds rouges. Que faites-vous ?

Tests instablesmidsenior

Restaurez la confiance d'abord : mettez en quarantaine les 50 dans un job non-bloquant — avec des tickets et des responsables, pas un cimetière — pour que main passe au vert et que le rouge veuille…

Restaurez la confiance d'abord : mettez en quarantaine les 50 dans un job non-bloquant — avec des tickets et des responsables, pas un cimetière — pour que main passe au vert et que le rouge veuille dire quelque chose à nouveau, aujourd'hui.

Puis résorbez par fréquence : bouclez chaque instabilité avec artefacts, corrigez la cause (attentes, isolation des données, ordre), remettez-la dans la suite bloquante. Et ajoutez une barrière : les nouveaux tests tournent N fois avant d'être autorisés.

Exemple concret

L'ordre compte parce que la confiance meurt vite et revient lentement : après la quarantaine, le premier vrai échec sur le main désormais vert a été investigué en quelques minutes — l'habitude d'ignorer le rouge s'est inversée la semaine même, pendant que les 50 étaient encore corrigés en arrière-plan.

Points clés
  • Quarantaine maintenant, avec des responsables
  • Corriger par fréquence d'échec
  • Barrière pour les nouveaux tests (N exécutions propres)
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Sauter directement à corriger les tests un par un — la confiance dans la suite meurt pendant que vous êtes sur le test n°14. La quarantaine d'abord.

Copier le lien

La nouvelle tentative automatique des tests échoués est-elle une bonne idée ?

Tests instablesmid

Comme outil de diagnostic, oui ; comme mode de vie, non. Une nouvelle tentative qui transforme le rouge en vert cache un vrai signal — soit un test instable, soit un bug produit intermittent — et les…

Comme outil de diagnostic, oui ; comme mode de vie, non. Une nouvelle tentative qui transforme le rouge en vert cache un vrai signal — soit un test instable, soit un bug produit intermittent — et les deux méritent une investigation, pas une suppression.

Milieu défendable : réessayer une fois, mais logger et rapporter chaque passage après nouvelle tentative comme « instable », suivi et résorbé. Les nouvelles tentatives silencieuses sont comment les suites pourrissent.

Exemple concret

Un test de paiement « passait à la nouvelle tentative » pendant des mois — tout le monde haussait les épaules. Quand quelqu'un a enfin lu le log de nouvelle tentative, l'échec de la première tentative était une vraie course : le double envoi créait deux intentions de paiement. La production l'a trouvé de la façon coûteuse d'abord. La nouvelle tentative avait mis en sourdine un vrai bug.

Points clés
  • Les nouvelles tentatives cachent le signal
  • Si utilisées : visibles + suivies
  • Passage après nouvelle tentative = signalé instable
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Un oui plat ou un non plat. La réponse senior est le conditionnel : la nouvelle tentative comme tolérance instrumentée, jamais comme silence.

Copier le lien

Comment gardez-vous les tests indépendants les uns des autres ?

Conception de frameworkmidsenior

Chaque test crée son propre état et nettoie : ses propres données (uniques par exécution — UUIDs, horodatages), sa propre session, ne lit pas ce qu'un test précédent a écrit, aucune hypothèse…

Chaque test crée son propre état et nettoie : ses propres données (uniques par exécution — UUIDs, horodatages), sa propre session, ne lit pas ce qu'un test précédent a écrit, aucune hypothèse d'ordre. Mise en place via l'API, teardown dans des fixtures qui tournent même en cas d'échec.

Le test d'indépendance : n'importe quel test tourne seul, et toute la suite passe mélangée et en parallèle.

Exemple concret

La dépendance classique : le test A crée « testuser@mail.com », le test B se connecte avec. Exécutez B seul — échoue. Exécutez en parallèle — le teardown de A supprime l'utilisateur en plein B. Correctif : B crée son propre utilisateur unique via l'API en deux lignes. Ennuyeux, à toute épreuve, parallèle-safe.

Points clés
  • Ses propres données, uniques par exécution
  • Mise en place API, teardown garanti
  • Doit passer mélangé + parallèle
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

« Exécutez-les dans le bon ordre » — la dépendance d'ordre EST la maladie, pas le remède.

Copier le lien

Comment gérez-vous les données de test en automatisation ?

Tests pilotés par les donnéesmid

Trois règles : chaque test POSSÈDE ses données (créées par exécution, noms uniques, détruites après) ; la création se fait sous l'UI (API ou amorçage — rapide, fiable) ; et la mise en place des…

Trois règles : chaque test POSSÈDE ses données (créées par exécution, noms uniques, détruites après) ; la création se fait sous l'UI (API ou amorçage — rapide, fiable) ; et la mise en place des données vit dans des builders/factories pour que « un utilisateur avec une carte expirée » soit un seul appel lisible.

Les données de fixture partagées sont la racine de la moitié de toutes les instabilités parallèles.

Exemple concret

Avant : tout le monde testait contre « test_user_1 », et les lundis étaient des jours d'instabilité — les exécutions du week-end le laissaient sale. Après : makeUser(with_expired_card=True) en construit un frais par test via l'API en ~200 ms. Les exécutions parallèles ont cessé d'entrer en collision le jour même.

Points clés
  • Possédez-les, construisez-les via l'API
  • Factories : one-liners lisibles
  • Uniques par exécution = parallèle-safe
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

« On a un compte de test partagé » — la réponse qui prédit chaque histoire d'instabilité du lundi matin.

Copier le lien

Comment gérez-vous l'authentification dans chaque test sans vous connecter via l'UI à chaque fois ?

Conception de frameworkmidsenior

Connectez-vous une fois, sous l'UI : frappez l'API d'auth (ou faites une connexion UI par worker), capturez la session — token, cookies, storage state — et injectez-la dans le contexte frais de…

Connectez-vous une fois, sous l'UI : frappez l'API d'auth (ou faites une connexion UI par worker), capturez la session — token, cookies, storage state — et injectez-la dans le contexte frais de chaque test. Le storageState de Playwright rend ça de première classe.

Gardez exactement un test de connexion UI pour couvrir le flux lui-même ; tout le reste démarre authentifié.

Exemple concret

200 tests × 8 secondes de connexion UI = 27 minutes par exécution à faire la même chose 200 fois — avec le formulaire de connexion comme une loterie d'instabilité à 200 chances. Passé à connexion API + storageState par worker : même suite, 27 minutes récupérées, et les instabilités liées à la connexion sont tombées à zéro.

Points clés
  • Auth via l'API, injecter la session
  • storageState / réutilisation de cookies
  • Un seul vrai test de connexion UI
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

« Je mets la connexion dans @BeforeMethod » — ça exécute quand même l'UI 200 fois ; la question porte sur le fait de passer sous l'UI.

Copier le lien

Comment exécutez-vous les tests sur plusieurs navigateurs ?

Multi-navigateurs & Gridjuniormid

Paramétrez le navigateur : une fabrique de driver/context lit BROWSER depuis la config, la CI exécute la suite comme une matrice — jobs chromium/firefox/webkit en parallèle.

Paramétrez le navigateur : une fabrique de driver/context lit BROWSER depuis la config, la CI exécute la suite comme une matrice — jobs chromium/firefox/webkit en parallèle. Les projects de Playwright rendent ça déclaratif ; Selenium utilise une fabrique plus Grid ou un fournisseur cloud pour le vrai étalement.

Cadrez par l'analytique : suite complète sur votre navigateur principal, chemins critiques sur les autres.

Exemple concret

Vérification de réalité qui impressionne : notre suite complète de 400 tests tourne sur Chromium à chaque build ; Firefox et WebKit exécutent le pack critique de 60 tests la nuit. Tout-en-matrice-complète sonne exhaustif et triple le coût CI pour des bugs qui ne diffèrent presque jamais hors des cas limites de rendu et de saisie.

Points clés
  • Le navigateur comme config, pas comme code
  • Matrice CI / projects Playwright
  • Complet sur le navigateur principal, critique sur les autres
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Décrire le changement de navigateur mais pas de stratégie pour QUELS navigateurs reçoivent QUELLE profondeur — la matrice sans le jugement.

Copier le lien

Qu'est-ce que Selenium Grid et quand en avez-vous besoin ?

Multi-navigateurs & Gridmid

Grid exécute vos tests sur des navigateurs distants : un hub route les sessions vers des nodes avec différentes combos navigateur/OS — RemoteWebDriver plus les desired capabilities, même code de…

Grid exécute vos tests sur des navigateurs distants : un hub route les sessions vers des nodes avec différentes combos navigateur/OS — RemoteWebDriver plus les desired capabilities, même code de test. Grid 4 l'a modernisé (binaire unique, Docker, observabilité).

Vous en avez besoin pour l'échelle (parallèle au-delà d'une machine) ou l'étalement (combos OS/navigateur que vous n'avez pas en local). Beaucoup d'équipes obtiennent maintenant les deux via Docker en CI ou un grid cloud à la place.

Exemple concret

Dimensionnement honnête : pour nos besoins Chromium+Firefox Linux uniquement, docker-compose en CI a battu la maintenance d'un Grid — deux conteneurs, terminé. Grid a gagné sa place chez un client ayant besoin d'un vrai étalement Windows/Safari/Edge-legacy sur site : hub plus cinq nodes hétérogènes, une seule suite.

Points clés
  • Le hub route, les nodes exécutent
  • Même code via RemoteWebDriver
  • Docker/cloud le remplace souvent
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Expliquer le diagramme hub/node mais être incapable de dire quand NE PAS s'embêter — « Docker en CI nous couvre » est souvent la réponse senior.

Copier le lien

Playwright vs Selenium — lequel choisiriez-vous et pourquoi ?

Outils modernesmid

Nouveau projet, sans contraintes : Playwright — l'auto-attente tue la plus grosse classe d'instabilité, une seule API pilote Chromium/Firefox/WebKit, le trace viewer rend les échecs…

Nouveau projet, sans contraintes : Playwright — l'auto-attente tue la plus grosse classe d'instabilité, une seule API pilote Chromium/Firefox/WebKit, le trace viewer rend les échecs auto-diagnostiquables, le parallélisme est intégré. Selenium l'emporte encore sur : tous les bindings de langage, un énorme écosystème/vivier de talents, les vrais besoins de Grid/navigateurs legacy, et l'investissement existant.

La réponse est le contexte, énoncé à voix haute.

Exemple concret

Deux histoires vraies : SaaS greenfield — Playwright, et l'équipe a cessé de discuter des attentes entièrement en un mois. Banque avec 800 tests Selenium/Java et recrutement Java uniquement — rester en place était correct ; une réécriture brûlerait un an pour re-arriver à la parité.

Points clés
  • Playwright : auto-attente, trace, vitesse
  • Selenium : langages, écosystème, legacy
  • Le contexte décide — dites lequel
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Dénigrer l'un ou l'autre outil. Les examinateurs maintiennent souvent celui que vous écartez.

Copier le lien

Quelles sont les limites de Cypress ?

Outils modernesmid

Structurelles, du fait de tourner dans le navigateur : restrictions de même origine (les flux multi-domaines sont maladroits), un seul onglet de navigateur — pas de vrai multi-onglets/multi-fenêtres,…

Structurelles, du fait de tourner dans le navigateur : restrictions de même origine (les flux multi-domaines sont maladroits), un seul onglet de navigateur — pas de vrai multi-onglets/multi-fenêtres, pas de WebKit/Safari, JavaScript/TypeScript uniquement, et pas de mobile natif.

En échange vous obtenez une superbe DX : débogage time-travel, attentes automatiques, rechargements instantanés. Excellent dans sa boîte ; connaissez les murs de la boîte.

Exemple concret

Le mur classique : un flux OAuth rebondissant vers un domaine de connexion tiers et revenant. Dans Cypress ça voulait dire de la gymnastique cy.origin et du stubbing ; le même flux dans Playwright était juste… un test. Si votre produit traverse des domaines constamment, cette seule différence décide de l'outil.

Points clés
  • Dans le navigateur = boîte de même origine
  • Pas de multi-onglets, pas de Safari, JS uniquement
  • Superbe DX dans la boîte
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

« Cypress est mauvais » — il est opinionné. Les limites-avec-compromis sont la réponse ; la haine n'est pas de l'analyse.

Copier le lien

Qu'est-ce que le BDD, et quel est votre avis honnête sur Cucumber ?

BDDmidsenior

Le BDD est une pratique de collaboration : le métier, le dev et la QA s'accordent sur le comportement en exemples avant le code — Given/When/Then.

Le BDD est une pratique de collaboration : le métier, le dev et la QA s'accordent sur le comportement en exemples avant le code — Given/When/Then. Cucumber automatise ces exemples via des définitions d'étapes.

Avis honnête : transformateur quand les parties prenantes lisent/écrivent réellement les scénarios ; pure lourdeur quand ce sont des ingénieurs écrivant du Gherkin pour d'autres ingénieurs — une couche de traduction que personne n'a demandée. L'outil va bien ; le mésusage est épidémique.

Exemple concret

Vu les deux : un produit d'assurance où les souscripteurs relisaient vraiment les scénarios — le Gherkin a attrapé deux malentendus de règles avant le code, valant chaque fichier d'étapes. Et une startup où la QA écrivait du Gherkin que personne d'autre n'ouvrait jamais : mêmes tests, plus une couche regex à maintenir. Même outil, valeur opposée.

Points clés
  • BDD = exemples partagés d'abord
  • Cucumber = la couche d'automatisation
  • Pas de lecteurs métier → sautez-le
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

« Le BDD est un outil de test » — c'est une pratique de collaboration ; l'outillage sans la collaboration n'est que de la cérémonie.

Copier le lien

Comment gérez-vous les listes déroulantes, alertes, iframes et fenêtres multiples en Selenium ?

Selenium (cœur)juniormid

Selects natifs : la classe Select — byVisibleText/byValue. Dropdowns custom (la plupart des UIs modernes) : cliquer pour ouvrir, attendre, cliquer l'option comme n'importe quel élément.

Selects natifs : la classe Select — byVisibleText/byValue. Dropdowns custom (la plupart des UIs modernes) : cliquer pour ouvrir, attendre, cliquer l'option comme n'importe quel élément. Alertes : driver.switchTo().alert() — accept/dismiss/getText. Iframes : switchTo().frame(...), travailler, puis defaultContent(). Fenêtres : capturer les handles, switchTo().window(newHandle), fermer et revenir.

Le thème : savoir dans quel CONTEXTE vous êtes.

Exemple concret

L'heure-perdue classique : « élément non trouvé » sur un locator qui est visiblement là — parce qu'il vit dans une iframe et que le driver est encore sur la page parente. Depuis, première question de débogage pour tout non-trouvé : suis-je dans le bon frame ?

Points clés
  • Classe Select vs custom = flux de clics
  • switchTo() : alert / frame / window
  • Toujours revenir
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Ne connaître que la classe Select — les dropdowns des apps modernes ne sont pas des selects, et l'examinateur le sait.

Copier le lien

Comment gérez-vous les téléversements et téléchargements de fichiers dans les tests automatisés ?

Selenium (cœur)juniormid

Téléversement : s'il y a un <input type=file>, sendKeys/setInputFiles le chemin — aucun dialogue ne s'ouvre jamais. Inputs cachés derrière des boutons stylés : ciblez l'input quand même.

Téléversement : s'il y a un <input type=file>, sendKeys/setInputFiles le chemin — aucun dialogue ne s'ouvre jamais. Inputs cachés derrière des boutons stylés : ciblez l'input quand même. Téléchargement : configurez le profil du navigateur pour sauvegarder automatiquement dans un dossier connu, attendez le fichier, affirmez dessus — ou interceptez la réponse/API directement.

N'automatisez jamais le dialogue de fichier de l'OS — il est hors du navigateur et hors de votre contrôle.

Exemple concret

Un uploader « glisser-déposer uniquement » avait quand même l'input fichier sous le style — setInputFiles dessus marchait parfaitement. Pour le test d'export, on a sauté le navigateur entièrement : le bouton de téléchargement appelait un endpoint connu, donc le test d'API affirmait le content-type et les lignes CSV en 200 ms.

Points clés
  • sendKeys/setInputFiles sur l'input
  • Téléchargements : dossier de profil ou API
  • Ne jamais toucher le dialogue de l'OS
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Recourir à AutoIt/Robot pour cliquer le dialogue de l'OS — la réponse qui dit que vous ne connaissiez pas l'élément input.

Copier le lien

Comment capturez-vous des captures d'écran et des diagnostics utiles quand un test échoue ?

Reportingjuniormid

De façon centralisée, dans un hook d'échec — jamais par test : un afterEach/listener attrape la capture d'écran, l'URL de la page, la console du navigateur, et (Playwright) la trace/vidéo en cas…

De façon centralisée, dans un hook d'échec — jamais par test : un afterEach/listener attrape la capture d'écran, l'URL de la page, la console du navigateur, et (Playwright) la trace/vidéo en cas d'échec, attachés au rapport.

Objectif : diagnostiquer depuis le seul rapport. Si la première réponse au rouge est « exécute-le en local », les diagnostics ont échoué.

Exemple concret

Le trace viewer de Playwright a changé le triage d'astreinte : un échec nocturne à 3 h du matin voulait dire reproduire-et-prier le matin. Maintenant la trace montre chaque action, snapshot du DOM, appel réseau et ligne de console jusqu'à l'échec — la plupart des rouges sont diagnostiqués en deux minutes sans relance.

Points clés
  • Hook, pas du code par test
  • Capture d'écran + console + trace
  • Diagnostiquable sans réexécution
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

« J'appelle takeScreenshot() dans mon test » — les captures d'écran appartiennent au hook d'échec du framework, une fois, pour chaque test.

Copier le lien

Comment intégrez-vous vos tests automatisés dans la CI ?

Bases de la CImidsenior

Par étapes selon la vitesse : à chaque PR, la barrière rapide — lint, unit, API, smoke (minutes, bloquante). Régression complète la nuit ou avant la release, parallélisée sur des workers.

Par étapes selon la vitesse : à chaque PR, la barrière rapide — lint, unit, API, smoke (minutes, bloquante). Régression complète la nuit ou avant la release, parallélisée sur des workers. Navigateurs via conteneurs/matrice ; secrets depuis les coffres CI ; rapports et artefacts publiés là où l'équipe vit.

L'objectif de conception : un feedback assez rapide pour que les développeurs ne contournent pas la barrière.

Exemple concret

Le chiffre qui compte : notre barrière de PR est de 6 minutes — les devs l'attendent. Quand elle a grimpé à 20, les gens ont commencé à merger avec une « culture --no-verify » et les bugs ont suivi. On a scindé la suite, déplacé la profondeur en nocturne, repassé sous 8 — la conformité est revenue sans un seul e-mail de politique.

Points clés
  • PR : barrière bloquante rapide
  • Nocturne : profondeur complète, parallèle
  • Barrière lente = barrière contournée
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

« Jenkins exécute mes tests la nuit » comme réponse complète — l'étagement par vitesse et confiance est ce que la question sonde.

Copier le lien

Quel workflow Git utilisez-vous, et comment résolvez-vous un conflit de merge ?

Gestion de versionsjuniormid

Branches de fonctionnalité depuis main, petites PR, revue, squash-merge, main toujours livrable — plus un rebase-avant-PR pour rester à jour.

Branches de fonctionnalité depuis main, petites PR, revue, squash-merge, main toujours livrable — plus un rebase-avant-PR pour rester à jour. Résolution de conflit : récupérer le dernier main, rebase/merge en local, ouvrir chaque fichier en conflit, choisir/combiner entre les marqueurs <<< >>> en comprenant les DEUX changements, réexécuter les tests, terminer le merge.

La règle : ne jamais résoudre du code que vous ne comprenez pas — demandez à son auteur.

Exemple concret

Les conflits de code de test ont une spécialité maison : deux branches ont toutes deux édité le même page object — l'une a renommé un locator que le nouveau test de l'autre utilise. Résoudre « les nôtres » compile et casse silencieusement leur test. C'est pourquoi l'étape réexécuter-les-tests après résolution est non négociable.

Points clés
  • Branche → petite PR → squash
  • Comprendre les deux côtés d'abord
  • Réexécuter les tests après résolution
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

« J'utilise git » sans workflow, ou résoudre les conflits par « accepter les nôtres » — les deux sont comment le travail des autres disparaît.

Copier le lien

Que cherchez-vous en relisant le code de test de quelqu'un d'autre ?

Conception de frameworksenior

Dans l'ordre : ce test peut-il échouer de façon significative — de vraies assertions sur de vrais résultats ; l'indépendance — ses propres données, pas de couplage d'ordre ; la stabilité — attentes…

Dans l'ordre : ce test peut-il échouer de façon significative — de vraies assertions sur de vrais résultats ; l'indépendance — ses propres données, pas de couplage d'ordre ; la stabilité — attentes conditionnelles, pas de sleeps, locators sensés ; la lisibilité — le scénario est évident ; et le placement — l'UI est-elle même la bonne couche pour cette vérification ?

La revue de code de test est là où la qualité de la suite est réellement décidée.

Exemple concret

Le commentaire de revue que je fais le plus : « ceci affirme que l'API a renvoyé 200 — affirmez que la COMMANDE existe avec le bon total. » Le deuxième plus fréquent : « ce sleep est une course qui attend d'être instable — qu'attendons-nous réellement ? » Les deux sont des correctifs de cinq minutes à la revue et des chasses d'une semaine un mois plus tard.

Points clés
  • Peut-il échouer ? Les assertions d'abord
  • Indépendance, attentes, locators
  • La bonne couche pour la vérification
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Des réponses de guide de style — nommage et imports — en ratant « ce test vérifie-t-il réellement quelque chose ? »

Copier le lien

Comment décidez-vous à quelle couche automatiser une vérification donnée ?

Stratégie d'automatisationsenior

Poussez chaque vérification à la couche la plus basse qui peut attraper le bug : logique pure → unitaire ; comportement de service et contrats → API/intégration ; seulement les vrais parcours de bout…

Poussez chaque vérification à la couche la plus basse qui peut attraper le bug : logique pure → unitaire ; comportement de service et contrats → API/intégration ; seulement les vrais parcours de bout en bout → UI. Plus bas est plus rapide, plus stable, et pointe les échecs.

Le smell qui déclenche la question : une suite UI de 40 minutes dont 30 minutes re-testent des règles métier que la couche API pourrait vérifier en secondes.

Exemple concret

Le calcul de remise avait 25 tests UI — panier, code, affirmer le total, trois minutes chacun. Les règles sont passées en tests API : 25 cas en quatre secondes au total. L'UI en a gardé exactement deux : un parcours utilisateur appliquant un code, un montrant l'état d'erreur. Couverture identique ; feedback 40× plus rapide.

Points clés
  • La couche la plus basse qui l'attrape
  • Logique→unitaire, règles→API, parcours→UI
  • UI = le parcours, pas les règles
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Réciter la pyramide sans exemple de migration — la question est vraiment « avez-vous DÉPLACÉ des vérifications vers le bas ? »

Copier le lien

Comment testez-vous qu'un élément N'EST PAS présent, sans ralentir votre suite ?

Attentes & synchronisationmid

Le piège est d'attendre un timeout complet pour prouver l'absence. Bons mouvements : d'abord attendre un ancrage positif — l'état qui prouve que la page s'est stabilisée — puis affirmer l'absence…

Le piège est d'attendre un timeout complet pour prouver l'absence. Bons mouvements : d'abord attendre un ancrage positif — l'état qui prouve que la page s'est stabilisée — puis affirmer l'absence instantanément (findElements().isEmpty(), une attente d'invisibilité à court timeout, ou le expect(locator).toBeHidden() de Playwright, qui le gère nativement).

Ancrage d'abord, puis absence — rapide et sans course.

Exemple concret

« L'élément supprimé disparaît » : la version naïve attendait 10 s que la ligne n'existe plus — à chaque exécution, même celles qui passent. Corrigé : attendre le toast « Élément supprimé » (positif, instantané une fois fait), puis affirmer que la liste de lignes ne le contient pas — coût total ~200 ms et aucune fenêtre de course.

Points clés
  • Ancrer sur un état positif d'abord
  • Puis vérification d'absence, timeout court/nul
  • Playwright : toBeHidden gère automatiquement
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

waitForInvisibility avec un timeout de 10 secondes comme réponse complète — prouver l'absence en payant le prix fort à chaque exécution.

Copier le lien

Qu'est-ce que la Page Factory, et l'utiliseriez-vous ?

Page Object Modelmid

La saveur à annotations du POM de Selenium : des champs @FindBy, initialisés par PageFactory.initElements(), avec recherche par proxy paresseuse et mise en cache optionnelle.

La saveur à annotations du POM de Selenium : des champs @FindBy, initialisés par PageFactory.initElements(), avec recherche par proxy paresseuse et mise en cache optionnelle.

L'utiliserais-je ? Pour du nouveau code, non — des locators By simples (ou des locators Playwright) font la même chose avec moins de magie : traces d'appels plus claires, pas de surprises de cache périmé venant de @CacheLookup, pas d'indirection de proxy au débogage. Reconnaissez-la, maintenez-la volontiers, ne commencez pas avec.

Exemple concret

Le signe au débogage : avec les proxies @FindBy, un locator cassé surgit comme un échec de proxy façon NullPointer à deux appels de la cause ; avec un By simple, l'exception dit exactement quel locator sur quelle ligne. Dix minutes vs trente secondes — la magie se facture toujours plus tard.

Points clés
  • @FindBy + proxies initElements
  • Même POM, plus de magie
  • Nouveau code : locators simples
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Présenter PageFactory comme « le POM professionnel » — c'est une saveur optionnelle, et la pratique moderne l'a dépassée.

Copier le lien

Comment automatiseriez-vous le test d'une application sans test IDs et au DOM changeant constamment ?

Sélecteurs (locators)senior

Deux pistes. Tactiquement : localiser par la sémantique côté utilisateur — rôles, labels, noms accessibles, texte stable — qui survivent aux re-rendus parce que c'est ce que l'app SIGNIFIE.

Deux pistes. Tactiquement : localiser par la sémantique côté utilisateur — rôles, labels, noms accessibles, texte stable — qui survivent aux re-rendus parce que c'est ce que l'app SIGNIFIE. Le getByRole/getByLabel de Playwright est fait exactement pour ça.

Stratégiquement : plaider pour les test ids — une ligne par élément, et la facture d'instabilité finance l'argument. La testabilité est une demande de fonctionnalité comme une autre.

Exemple concret

Une app React se re-rendant constamment : chaque locator basé sur les classes mourait chaque semaine. Passé au style getByRole('button', {name: 'Submit order'}) partout — les échecs de locator sont tombés à quasi zéro, parce que les rôles et noms ne changent que quand le produit change vraiment. Puis l'équipe a ajouté des test ids quand même ; la PR faisait 40 changements d'une ligne.

Points clés
  • Sémantique : rôle + nom accessible
  • Le sens survit aux re-rendus
  • Piste parallèle : vendre les test ids
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Un XPath plus sophistiqué comme réponse — une fragilité plus astucieuse reste de la fragilité ; l'échappatoire est la sémantique, pas le golf de sélecteurs.

Copier le lien

Qu'est-ce qu'un navigateur headless, et quels sont les compromis ?

Multi-navigateurs & Gridjuniormid

Un vrai moteur de navigateur tournant sans fenêtre visible — même rendu, même JS, pas de GUI. Défaut pour la CI : démarrage plus rapide, moins de mémoire, pas de serveur d'affichage nécessaire.

Un vrai moteur de navigateur tournant sans fenêtre visible — même rendu, même JS, pas de GUI. Défaut pour la CI : démarrage plus rapide, moins de mémoire, pas de serveur d'affichage nécessaire.

Compromis : vous ne pouvez pas le regarder (donc les artefacts comptent plus), et quelques vraies différences de comportement existent — viewport par défaut, timing de focus/animation, historiquement quelques codecs/polices. Règle : headless en CI, débogage en headed, et attention à la distinction nouveau-vs-ancien headless dans Chrome.

Exemple concret

Le fantôme headless classique : un test vert en local (headed), rouge en CI — élément « non visible ». Cause : le viewport headless par défaut 800×600 rangeait le bouton sous un menu replié. Une ligne épinglant le viewport 1920×1080 en config a mis fin à une semaine de mystère intermittent.

Points clés
  • Vrai moteur, pas de fenêtre
  • Défaut CI : rapide, léger
  • Épinglez le viewport ; déboguez en headed
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

« Headless est plus rapide » sans compromis — l'histoire du viewport est la différence entre l'utiliser et le comprendre.

Copier le lien

Comment structurez-vous les assertions et le reporting pour qu'un échec soit diagnostiquable sans réexécuter le test ?

Reportingsenior

Concevez pour le lecteur de 3 h du matin : des assertions précises avec attendu/réel/contexte dans le message ; des hooks d'échec attachant capture d'écran, console, réseau et trace ; des noms de…

Concevez pour le lecteur de 3 h du matin : des assertions précises avec attendu/réel/contexte dans le message ; des hooks d'échec attachant capture d'écran, console, réseau et trace ; des noms de test qui énoncent le scénario ; des étapes annotées pour que le rapport se lise comme un récit ; et le build/commit testé estampillé sur l'exécution.

Métrique : quelle fraction des rouges est diagnostiquée depuis le seul rapport. Ce chiffre est la qualité du reporting.

Exemple concret

Avant/après un échec : « AssertionError: expected true » vs « Écart de total de commande : attendu 49.99, obtenu 54.99 — commande #1042, coupon SAVE10, trace attachée ». Le second n'a demandé zéro relance : la trace montrait l'endpoint du coupon en 500. Même bug, trente secondes au lieu d'un après-midi.

Points clés
  • Messages : attendu/réel/contexte
  • Artefacts auto-attachés en cas d'échec
  • Le rapport se lit comme un récit
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

« Un bon reporting = Allure installé » — l'outil affiche ce que vos assertions et hooks fournissent ; ordures en entrée, jolies ordures en sortie.

Copier le lien

Un test passe en local mais échoue en CI. Comment enquêtez-vous ?

Tests instablesmidsenior

Comparez les deux mondes, les preuves d'abord : récupérez les artefacts de la CI (capture d'écran, trace, logs) — généralement la réponse est visible.

Comparez les deux mondes, les preuves d'abord : récupérez les artefacts de la CI (capture d'écran, trace, logs) — généralement la réponse est visible. Puis les suspects habituels dans l'ordre : timing (la CI est plus lente — les courses surgissent), environnement (headless, viewport, polices, locale, fuseau horaire, versions), données (tests parallèles en collision, état sale), secrets/config.

Puis reproduisez les conditions de la CI en local — même headless, viewport, BD — plutôt que de deviner.

Exemple concret

Le nôtre était le fuseau horaire : un test de sélecteur de date affirmant « demain » — machine locale UTC+4, runner CI UTC. À 21 h en local, « demain » différait entre les deux mondes et le test n'échouait qu'en CI, seulement le soir. TZ épinglé en config ; le fantôme est mort.

Points clés
  • Artefacts CI d'abord
  • Suspects : timing, env, données, config
  • Reproduire le monde de la CI en local
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

« Relance-le en CI et vois » — c'est espérer, pas enquêter. Les artefacts et la comparaison sont la méthode.

Copier le lien

Comment testez-vous une fonctionnalité qui dépend d'un service tiers que vous ne contrôlez pas ?

Conception de frameworkmidsenior

Répartissez le risque : votre logique d'intégration — testez contre des mocks/stubs pilotant chaque réponse qui vous importe : succès, chaque erreur documentée, timeout, succès lent, corps mal formé.

Répartissez le risque : votre logique d'intégration — testez contre des mocks/stubs pilotant chaque réponse qui vous importe : succès, chaque erreur documentée, timeout, succès lent, corps mal formé. Leur service réel — une fine vérification de contrat/santé planifiée contre le sandbox, isolée pour que ses échecs ne rougissent pas votre suite.

Ne laissez jamais le sandbox instable d'un partenaire gater vos merges.

Exemple concret

Le sandbox du prestataire de paiement est tombé un après-midi — avant la répartition, 40 tests rouges et PR bloquées dans toute l'entreprise ; le code de personne n'était faux. Après : suite verte contre WireMock, et une vérification « sandbox prestataire » en quarantaine rapportant honnêtement LEUR incident. Même après-midi, zéro drame.

Points clés
  • Mock pour la logique, toutes les réponses
  • Vérification de contrat live séparée
  • Instabilité partenaire ≠ suite rouge
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

« Tester contre leur sandbox » comme réponse complète — vous avez rendu votre build dépendant de la disponibilité de quelqu'un d'autre.

Copier le lien

Qu'est-ce que le test de régression visuelle et quand en vaut-il la peine ?

Outils modernesmidsenior

Un test par diff de captures d'écran : capturer des pages/composants contre des références approuvées, échouer sur une dérive pixel ou perceptuelle — attrapant ce que les tests fonctionnels ne voient…

Un test par diff de captures d'écran : capturer des pages/composants contre des références approuvées, échouer sur une dérive pixel ou perceptuelle — attrapant ce que les tests fonctionnels ne voient pas : CSS cassé, éléments qui se chevauchent, boutons invisibles-mais-présents.

En vaut la peine pour des surfaces stables et critiques pour le design (pages marketing, design systems, checkout). N'en vaut pas la peine pour des UIs en évolution — chaque changement légitime devient une corvée de référence, et le bruit enterre le signal.

Exemple concret

Un refactoring CSS a cassé le bouton de checkout — encore dans le DOM, encore « cliquable » pour Selenium, visuellement blanc-sur-blanc pour les humains. Chaque test fonctionnel passait. Le diff de capture d'écran l'a attrapé dans la PR. Cette seule sauvegarde est tout l'argument ; la contre-histoire est l'équipe qui a abandonné les tests visuels sous 30 faux diffs par semaine.

Points clés
  • Attrape ce que le fonctionnel ne voit pas
  • Surfaces stables uniquement
  • L'évolution des références = la mort
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

« Capturez tout ! » — le mode de défaillance du test visuel est du bruit auto-infligé, et l'examinateur l'a vécu.

Copier le lien

Comment aborderiez-vous l'automatisation d'une application que vous n'avez jamais vue ?

Stratégie d'automatisationmidsenior

Apprenez avant d'automatiser : explorez l'app, cartographiez les parcours utilisateurs critiques et le chemin de l'argent, inventoriez la testabilité (test ids ? APIs stables ? options d'auth ?

Apprenez avant d'automatiser : explorez l'app, cartographiez les parcours utilisateurs critiques et le chemin de l'argent, inventoriez la testabilité (test ids ? APIs stables ? options d'auth ? environnements ?). Puis commencez délibérément petit — le smoke sur le chemin critique d'abord, câblé dans la CI dès le premier jour, puis grandissez vers l'extérieur par le risque.

Objectif de la première semaine : cinq tests solides tournant à chaque build — pas cinquante specs sur un portable.

Exemple concret

Premier jour sur un nouveau produit : deux heures d'exploratoire avec l'onglet réseau ouvert m'ont appris que l'app était API-first avec une UI fine — ce qui a basculé le plan vers une couverture lourde en API plus une poignée de parcours UI. La décision de framework est venue de la forme de l'app, pas de mes habitudes.

Points clés
  • Explorer + cartographier les parcours d'abord
  • Inventaire de testabilité
  • Petit smoke en CI, dès le premier jour
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Commencer par « d'abord je choisirais Playwright » — parler d'outil avant de comprendre l'app est le signe junior que cette question traque.

Copier le lien

Comment gardez-vous une suite d'automatisation maintenable quand elle grandit à des milliers de tests ?

Conception de frameworksenior

Architecture plus gouvernance. Architecture : couches strictes (tests fins, logique dans pages/clients/fixtures), données isolées parallèle-safe, tagging pour des exécutions sélectives, vérifications…

Architecture plus gouvernance. Architecture : couches strictes (tests fins, logique dans pages/clients/fixtures), données isolées parallèle-safe, tagging pour des exécutions sélectives, vérifications poussées à la couche la moins chère. Gouvernance : standards de revue pour le code de test, un budget d'instabilité avec quarantaine, la suppression comme activité de première classe, et des métriques de santé de suite (temps d'exécution, taux d'instabilité) surveillées comme des métriques produit.

Les suites meurent d'économie de négligence, pas de taille.

Exemple concret

À ~2000 tests notre nocturne atteignait trois heures. Le correctif n'était pas le matériel : 300 tests UI re-vérifiant des règles vérifiables par API sont descendus d'une couche, 150 tests redondants/morts ont été supprimés après un audit de couverture, le tagging a séparé le smoke de PR de la profondeur nocturne. Temps d'exécution divisé par deux ; la confiance a MONTÉ après suppression de tests — c'est la partie contre-intuitive qui vaut la peine d'être dite.

Points clés
  • Couches + données isolées + tags
  • Budget d'instabilité, quarantaine, suppression
  • Surveiller temps/instabilité comme des KPI produit
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Seulement l'architecture, pas de gouvernance — les suites de mille tests pourrissent d'instabilité sans responsable et de code de test non relu, pas de la structure de dossiers.

Copier le lien

Quelle est la différence entre un test qui échoue et un test qui est cassé ?

Tests instablesmidsenior

Un test qui échoue marche parfaitement : le produit a cassé, le test l'a attrapé — c'est la suite qui fait son travail.

Un test qui échoue marche parfaitement : le produit a cassé, le test l'a attrapé — c'est la suite qui fait son travail. Un test cassé échoue pour ses propres raisons — locator mort, mauvaise attente, données périmées — et ne dit rien sur le produit.

Le triage, c'est les distinguer vite : artefacts d'abord, comportement produit derrière l'échec vérifié à la main ou par API. Corrigez les tests cassés ; ouvrez des bugs depuis ceux qui échouent. Confondre les deux dans un sens ou l'autre est coûteux.

Exemple concret

Deux rouges, même matin : une trace montrait le 500 de l'app au checkout — test qui échoue, vrai bug, escaladé. L'autre montrait un bouton renommé — test cassé, locator mis à jour en cinq minutes. Traiter le rouge n°1 comme « probablement instable » aurait livré le 500 ; traiter le n°2 comme un bug aurait brûlé l'après-midi d'un dev.

Points clés
  • Échoue = bug produit, le test a marché
  • Cassé = défaut propre au test
  • Les artefacts décident, vite
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Traiter chaque rouge comme « instable, relance-le » — l'habitude que cette question existe pour écarter.

Copier le lien

Qu'est-ce que Git, et pourquoi la gestion de versions compte-t-elle pour un testeur ?

Gestion de versionsjunior

Git est un système de gestion de versions distribué — il suit chaque changement de votre code, permet de brancher et merger, et donne à chacun une copie complète de l'historique.

Git est un système de gestion de versions distribué — il suit chaque changement de votre code, permet de brancher et merger, et donne à chacun une copie complète de l'historique. La gestion de versions est ce qui permet à une équipe de travailler sur la même base de code sans s'écraser mutuellement, et de revenir en arrière quand quelque chose casse.

Pour un testeur c'est de la plomberie du premier jour : votre automatisation vit dans Git, vous branchez pour ajouter des tests, ouvrez une pull request, et l'historique de votre framework fait partie du GitHub qu'un examinateur fait défiler avant de vous rencontrer.

Points clés
  • VCS distribué : suit l'historique, branches, merges, copie locale complète
  • Permet à une équipe de partager une base de code en sécurité et de revenir en arrière
  • Votre automatisation de test vit ici — branche, PR, revue, merge
Ils demanderont ensuite · touchez-en un pour la réponse
Copier le lien

Quelle est la différence entre merge et rebase ?

Gestion de versionsmid

Merge combine deux branches et enregistre un commit de merge — l'historique montre exactement ce qui s'est passé, branches comprises.

Merge combine deux branches et enregistre un commit de merge — l'historique montre exactement ce qui s'est passé, branches comprises. Rebase rejoue vos commits par-dessus la branche cible, produisant un historique droit et linéaire mais réécrivant vos hashes de commit.

Les deux sont corrects ; les équipes en choisissent un. La règle qui compte : ne jamais rebaser une branche sur laquelle d'autres travaillent — réécrire l'historique partagé casse la copie de tout le monde. Rebasez votre propre branche locale pour la nettoyer avant une PR ; mergez pour intégrer. Savoir pourquoi les équipes ont une opinion ici est le signal senior.

Points clés
  • Merge : garde le vrai historique + un commit de merge
  • Rebase : historique linéaire, mais réécrit les commits
  • Ne jamais rebaser une branche que d'autres partagent — ça casse leur historique
Ils demanderont ensuite · touchez-en un pour la réponse
Le piège

Le force-push d'une branche partagée rebasée est le désastre classique — ça réécrit un historique que d'autres ont, et leur prochain pull entre en conflit avec tout. Rebase en local, merge le partagé.

Copier le lien

Comment résolvez-vous un conflit de merge ?

Gestion de versionsmid

Un conflit veut dire que deux branches ont changé les mêmes lignes et que Git ne devinera pas. Il marque le fichier avec <<<<<<< les vôtres, ======= et >>>>>>> les leurs.

Un conflit veut dire que deux branches ont changé les mêmes lignes et que Git ne devinera pas. Il marque le fichier avec <<<<<<< les vôtres, ======= et >>>>>>> les leurs. Vous l'ouvrez, décidez quel est le bon résultat — garder un côté, l'autre, ou combiner — supprimez les lignes de marqueur, puis stagez le fichier et continuez le merge ou le rebase.

La discipline est de comprendre les deux changements avant de choisir, pas d'accepter aveuglément un côté. Un conflit n'est pas une erreur ; c'est Git demandant à un humain de prendre une décision qu'il ne peut pas prendre.

Points clés
  • Deux branches ont touché les mêmes lignes — Git a besoin d'un humain
  • Éditer le fichier marqué, supprimer les marqueurs <<< === >>>, stager, continuer
  • Comprendre les deux côtés avant de choisir — pas d'acceptation aveugle
Ils demanderont ensuite · touchez-en un pour la réponse
Copier le lien

Qu'est-ce qu'un bon historique de commits — et pourquoi un examinateur s'en soucierait-il ?

Gestion de versionsmid

Des commits petits et ciblés, chacun une étape cohérente, avec un message disant ce qui a changé et pourquoi à l'impératif — « Ajouter des tests de smoke pour le checkout », pas « fix » ou « final ».

Des commits petits et ciblés, chacun une étape cohérente, avec un message disant ce qui a changé et pourquoi à l'impératif — « Ajouter des tests de smoke pour le checkout », pas « fix » ou « final ». Un inconnu devrait lire votre git log et suivre comment le travail a été construit.

Les examinateurs s'en soucient parce qu'ils font défiler votre GitHub avant l'entretien, et votre historique est un échantillon d'écriture que vous ne saviez pas avoir soumis. Un dépôt de cinq commits significatifs se lit comme un ingénieur ; un seul commit appelé « solution » invite des questions sur d'où vient le code.

Points clés
  • Commits petits et ciblés, messages à l'impératif, quoi + pourquoi
  • Le log devrait raconter l'histoire de comment ça a été construit
  • Votre historique est un échantillon d'écriture que les examinateurs lisent vraiment
Ils demanderont ensuite · touchez-en un pour la réponse
Copier le lien

Quelle est la différence entre git fetch et git pull ?

Gestion de versionsjuniormid

git fetch télécharge les derniers commits du remote mais ne touche pas à votre branche de travail — vous pouvez inspecter ce qui a changé avant d'intégrer.

git fetch télécharge les derniers commits du remote mais ne touche pas à votre branche de travail — vous pouvez inspecter ce qui a changé avant d'intégrer. git pull est un fetch plus un merge (ou rebase) immédiat dans votre branche courante.

Le pull est la commodité du quotidien ; fetch-puis-regarder est plus sûr quand vous voulez voir ce qui arrive avant que ça atterrisse sur votre travail — surtout avant un rebase, ou quand vous soupçonnez que le remote a bougé d'une façon qui entrera en conflit.

Points clés
  • fetch : télécharge les changements du remote, ne merge pas — inspecter d'abord
  • pull : fetch + merge/rebase dans votre branche courante en une étape
  • fetch-puis-relire quand vous voulez voir avant d'intégrer
Ils demanderont ensuite · touchez-en un pour la réponse
Copier le lien
Ils demanderont ensuite