La connaissance de SQL distingue les ingénieurs QA capables de vérifier les données de ceux qui ne peuvent vérifier que l'interface.

Pourquoi les ingénieurs QA ont besoin de SQL

Les tests UI vérifient ce que l'utilisateur voit. SQL vérifie ce qui s'est réellement passé.

Quand un test clique sur "Passer la commande" et voit un écran de confirmation, vous savez que l'UI a répondu. Vous ne savez pas si la commande a été sauvegardée. Vous ne savez pas si le bon statut a été défini. Vous ne savez pas si la clé étrangère a été écrite correctement. La seule façon de le vérifier, c'est de regarder directement en base de données.

Cas d'usage SQL pour le QA :

  • Vérifier que les données ont été sauvegardées après une action UI (soumission de formulaire, upload de fichier, paiement)
  • Configurer des données de test directement au lieu de passer par 10 clics dans l'interface
  • Vérifier des données que l'UI n'expose pas (journaux d'audit, flags internes, enregistrements soft-supprimés)
  • Reproduire des bugs en vérifiant l'état de la base de données quand quelque chose a échoué
  • Valider les migrations après qu'un déploiement a modifié le schéma

Quand une offre d'emploi dit "expérience SQL requise", voilà ce qu'ils veulent dire. Pas des procédures stockées, pas l'optimisation des requêtes, pas l'administration de bases de données. Des instructions SELECT avec des conditions.

L'outil : n'importe quel client SQL

Vous n'avez pas besoin de connaître un produit de base de données spécifique. La syntaxe des requêtes est presque identique entre PostgreSQL, MySQL et SQLite. Pour pratiquer :

  • TablePlus (Mac/Windows) : interface claire, la version gratuite suffit
  • DBeaver : gratuit, fonctionne avec tous les types de bases de données
  • psql : ligne de commande PostgreSQL, toujours disponible
  • Tout test Playwright avec un package pg ou mysql2 peut aussi exécuter des requêtes directement

Pour les exemples ci-dessous, la structure est basée sur le schéma de base de données de lab.becomeqa.com.

Pattern 1 : SELECT

La chose la plus courante que vous ferez :

-- Obtenir tous les utilisateurs
SELECT * FROM users;

-- Obtenir des colonnes spécifiques
SELECT id, email, created_at FROM users;

-- Obtenir un utilisateur par e-mail
SELECT * FROM users WHERE email = 'admin@becomeqa.com';

-- Obtenir les utilisateurs créés dans les 7 derniers jours
SELECT * FROM users WHERE created_at > NOW() - INTERVAL '7 days';

SELECT * récupère toutes les colonnes. SELECT id, email récupère uniquement ces colonnes. WHERE filtre les lignes. C'est 90 % de ce dont vous avez besoin. En contexte QA :

-- Après un test d'inscription, vérifier que l'utilisateur a été créé
SELECT id, email, role, is_active 
FROM users 
WHERE email = 'testuser_1234567@test.com';

Si ça retourne une ligne, l'utilisateur a été sauvegardé. Si ça ne retourne rien, l'inscription a silencieusement échoué même si l'UI a affiché un succès.

Pattern 2 : WHERE avec conditions

Combiner des conditions :

-- AND : les deux conditions doivent être vraies
SELECT * FROM items 
WHERE status = 'completed' AND user_id = 42;

-- OR : l'une ou l'autre condition doit être vraie
SELECT * FROM items 
WHERE status = 'pending' OR status = 'in_progress';

-- IN : correspondre à n'importe quelle valeur dans une liste
SELECT * FROM items 
WHERE status IN ('pending', 'in_progress', 'completed');

-- NOT : exclure des lignes
SELECT * FROM items WHERE status != 'deleted';

-- LIKE : correspondance partielle de chaîne (% est le wildcard)
SELECT * FROM users WHERE email LIKE '%@test.com';

-- IS NULL : vérifier les valeurs manquantes
SELECT * FROM items WHERE deleted_at IS NULL;
SELECT * FROM items WHERE deleted_at IS NOT NULL;

En contexte QA :

-- Vérifier que la soft-suppression a fonctionné (deleted_at doit être défini)
SELECT id, title, deleted_at 
FROM items 
WHERE id = 99;

-- Trouver toutes les données de test à nettoyer après une exécution
SELECT * FROM users WHERE email LIKE '%testuser_%@test.com';

Pattern 3 : JOIN

Les données réelles se trouvent dans plusieurs tables. Un élément de voyage appartient à un utilisateur. Une commande appartient à un client et contient des produits. Vous avez besoin de JOIN pour avoir la vue complète.

-- JOIN de base : éléments avec l'e-mail de leur propriétaire
SELECT items.id, items.title, items.status, users.email
FROM items
JOIN users ON items.user_id = users.id;

-- Filtrer le résultat jointé
SELECT items.id, items.title, users.email
FROM items
JOIN users ON items.user_id = users.id
WHERE users.email = 'admin@becomeqa.com';

Le patron est toujours :

SELECT [colonnes souhaitées]
FROM [table principale]
JOIN [table liée] ON [comment elles se connectent]
WHERE [filtre optionnel]

En contexte QA :

-- Après avoir ajouté un élément en tant qu'admin, vérifier qu'il est lié au bon utilisateur
SELECT items.title, items.status, users.email AS owner
FROM items
JOIN users ON items.user_id = users.id
WHERE items.title = 'Tokyo'
ORDER BY items.created_at DESC
LIMIT 1;

Pattern 4 : COUNT et fonctions d'agrégation

Quand vous avez besoin de chiffres, pas de lignes :

-- Combien d'utilisateurs y a-t-il ?
SELECT COUNT(*) FROM users;

-- Combien d'utilisateurs actifs ?
SELECT COUNT(*) FROM users WHERE is_active = true;

-- Combien d'éléments par statut ?
SELECT status, COUNT(*) AS total
FROM items
GROUP BY status;

-- Date de création du dernier élément
SELECT MAX(created_at) FROM items;

-- Nombre total d'éléments par utilisateur
SELECT user_id, COUNT(*) AS item_count
FROM items
GROUP BY user_id
ORDER BY item_count DESC;

En contexte QA :

-- Après un test d'import en masse, vérifier que le bon nombre d'enregistrements a été créé
SELECT COUNT(*) FROM items WHERE created_at > '2026-05-15 10:00:00';

-- Vérifier que les données de test sont isolées (pas de contamination croisée entre les exécutions)
SELECT user_id, COUNT(*) FROM items GROUP BY user_id;

Pattern 5 : ORDER BY et LIMIT

Contrôler quelles lignes vous obtenez et dans quel ordre :

-- Éléments créés le plus récemment en premier
SELECT * FROM items ORDER BY created_at DESC;

-- Les plus anciens en premier
SELECT * FROM items ORDER BY created_at ASC;

-- Seulement les 5 plus récents
SELECT * FROM items ORDER BY created_at DESC LIMIT 5;

-- Page 2 des résultats (lignes 11 à 20)
SELECT * FROM items ORDER BY id LIMIT 10 OFFSET 10;

En contexte QA :

-- Après qu'un test crée un élément, récupérer celui qui vient d'être créé
SELECT * FROM items 
WHERE user_id = 42 
ORDER BY created_at DESC 
LIMIT 1;

Tout assembler : une requête de vérification complète

Un flux de test : un utilisateur se connecte, ajoute un élément de voyage nommé "Paris", le marque comme "Terminé". Voici comment vérifier l'opération complète en SQL.

SELECT 
    items.id,
    items.title,
    items.status,
    items.created_at,
    users.email AS owner
FROM items
JOIN users ON items.user_id = users.id
WHERE items.title = 'Paris'
    AND items.status = 'completed'
    AND users.email = 'admin@becomeqa.com'
ORDER BY items.created_at DESC
LIMIT 1;

Si ça retourne une ligne, tout le flux a fonctionné de bout en bout. Si ça ne retourne rien, quelque chose a silencieusement échoué entre la connexion et la mise à jour du statut.

Utiliser SQL dans les tests Playwright

Vous pouvez exécuter du SQL directement depuis votre code de test avec une bibliothèque client de base de données :

import { test, expect } from '@playwright/test';
import { Client } from 'pg'; // npm install pg

test('item is saved to database after creation', async ({ page }) => {
    // Effectuer l'action UI
    await page.goto('/');
    // ... connexion, ajout d'un élément nommé 'Tokyo' ...

    // Vérifier en base de données
    const db = new Client({ connectionString: process.env.DATABASE_URL });
    await db.connect();

    const result = await db.query(
        'SELECT * FROM items WHERE title = $1 ORDER BY created_at DESC LIMIT 1',
        ['Tokyo']
    );

    expect(result.rows.length).toBe(1);
    expect(result.rows[0].status).toBe('planned');

    await db.end();
});

Ce patron est puissant : action UI et vérification en base de données dans un seul test. Le test UI prouve que l'application a répondu correctement ; la requête SQL prouve que les données ont réellement été persistées.

Erreurs courantes

Utiliser SELECT dans les tests de production. Correct pour le débogage, mais nommez les colonnes explicitement dans les tests automatisés. Quand une colonne est ajoutée ou supprimée, SELECT masque le changement. Oublier WHERE dans un DELETE. Si vous nettoyez des données de test avec DELETE FROM items WHERE email LIKE '%test%', vérifiez toujours le WHERE avant d'exécuter. DELETE FROM items sans WHERE supprime tout. Ne pas utiliser de requêtes paramétrées dans le code. Ne construisez jamais des chaînes SQL en concaténant des entrées utilisateur. Utilisez les placeholders $1 comme montré ci-dessus pour prévenir les injections SQL. Lire des données obsolètes. Certaines bases de données ont une isolation de transaction qui signifie que vous devez COMMIT une transaction avant qu'une autre connexion puisse voir les changements. Si votre test écrit des données puis les interroge depuis une connexion différente, vérifiez que la transaction a été commitée.

Ce dont vous n'avez pas besoin (encore)

  • Sous-requêtes
  • Fonctions fenêtre (ROW_NUMBER, RANK)
  • CTEs (clauses WITH)
  • Procédures stockées et fonctions
  • Index de base de données et planification des requêtes
  • Conception de schéma et normalisation

Ces éléments comptent pour les développeurs de bases de données. Pour le QA, vous lisez des données. Les cinq patterns ci-dessus représentent 95 % du travail.

FAQ

Sur quelle base de données apprendre le SQL ?

PostgreSQL. C'est la plus courante dans les applications web modernes, la mieux outillée, et la syntaxe est suffisamment standard pour qu'en passer à MySQL ou SQLite prenne quelques minutes. Installez TablePlus, connectez-vous à n'importe quelle instance PostgreSQL, et pratiquez-y.

Puis-je pratiquer le SQL sans application réelle ?

Oui. Des sites comme sqlfiddle.com et db-fiddle.com vous permettent de créer des tables et d'exécuter des requêtes dans le navigateur sans rien installer. Créez une table users et une table items, insérez quelques lignes, et pratiquez les cinq patterns ci-dessus.

Dois-je écrire des tests SQL ou juste les utiliser pour déboguer ?

Les deux. SQL est précieux pour le débogage manuel. Quand vous ne comprenez pas pourquoi un test échoue, vérifiez la base de données. C'est aussi utile dans les tests automatisés pour les vérifications de données que l'UI ne peut pas fournir. Commencez par le débogage, ajoutez des assertions de base de données automatisées une fois à l'aise avec les requêtes.

Quelle est la différence entre les bases de données SQL ?

Pour les besoins du QA, presque rien. PostgreSQL utilise $1 pour les paramètres, MySQL utilise ?, mais la syntaxe SELECT/WHERE/JOIN est identique. Les cinq patterns ci-dessus fonctionnent dans les trois.

→ See also: Comment Fonctionne Internet pour les Testeurs | Tests d'API avec Playwright: Au-delà de l'Interface