1. Что такое SQL?
SQL (Structured Query Language) — это язык структурированных запросов, который используется для общения с реляционными базами данных. С его помощью тестировщик может:
- Проверять, корректно ли сохранились данные после действий в интерфейсе.
- Создавать тестовые данные (например, новых пользователей или заказы).
- Находить специфические данные для сложных тест-кейсов.
- Удалять "мусорные" данные после прогона автотестов.
Структура запроса
Любой SQL-запрос состоит из "команд" или операторов. Наведите на них, чтобы узнать больше.
SELECT first_name, email FROM employees WHERE department_id = 1;
Порядок выполнения
Хотя мы пишем SELECT
вначале, база данных выполняет операторы в другом, логическом порядке:
2. Типы данных
Каждый столбец в таблице имеет строго определенный тип данных. Это обеспечивает целостность и предсказуемость хранения информации.
- INTEGER (INT): Целые числа (
1
,100
,-50
). - VARCHAR(n): Текстовая строка переменной длины до n символов (
'Иван'
). Экономит место. - CHAR(n): Текстовая строка фиксированной длины n символов (
'M'
,'F'
). Быстрее для полей с одинаковой длиной. - TEXT: Для хранения длинных текстов (описания товаров, статьи).
- DECIMAL(p, s) / NUMERIC: Числа с фиксированной точностью (
199.99
). Идеальны для денег, чтобы избежать ошибок округления. - FLOAT / REAL: Числа с плавающей точкой. Используются для научных расчетов.
- DATE: Дата (
'2025-10-03'
). - TIMESTAMP / DATETIME: Дата и время (
'2025-10-03 17:00:00'
).TIMESTAMP
часто хранит время в UTC. - BOOLEAN: Логические значения (
true
илиfalse
). - NULL: Специальное значение, означающее "нет данных" или "неприменимо". Не путать с пустой строкой
''
или нулем0
.
3. Создание и управление (DDL & DML)
Это команды для работы со структурой базы (DDL - Data Definition Language) и манипулирования самими данными (DML - Data Manipulation Language). Для всех примеров ниже мы будем использовать тестовую таблицу employees
.
Работа с базами данных
SHOW DATABASES: Показать все БД
QA-кейс: Убедиться, что вы подключились к правильному серверу и видите нужную тестовую базу данных.
SHOW DATABASES;
CREATE/DROP DATABASE: Создать/Удалить БД
QA-кейс: Создание полностью изолированной базы данных для прогона набора автотестов с последующим её удалением.
-- Создаем новую БД CREATE DATABASE test_automation_db;
-- Удаляем БД после тестов DROP DATABASE test_automation_db;
USE: Выбрать БД для работы
QA-кейс: Перед выполнением любых запросов к таблицам, нужно "активировать" базу данных, с которой вы будете работать.
USE main_project_db;
Работа с таблицами
CREATE TABLE: Создать таблицу
QA-кейс: Создание временной таблицы для хранения промежуточных результатов сложного теста.
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) UNIQUE,
birthdate DATE
);
INSERT INTO: Добавить данные
QA-кейс: Создать нового тестового пользователя перед проверкой логина.
INSERT INTO employees (first_name, last_name, email, department_id, salary)
VALUES ('Тест', 'Тестов', 'test@example.com', 2, 55000.00);
UPDATE: Изменить данные
QA-кейс: Изменить статус заказа на "Доставлен" для проверки отображения в личном кабинете.
UPDATE employees SET email = 'new_email@example.com' WHERE id = 2;
DELETE: Удалить данные
QA-кейс: "Почистить" базу данных, удалив тестового пользователя, созданного во время теста.
DELETE FROM employees WHERE email = 'test@example.com';
ALTER TABLE: Изменить структуру таблицы
QA-кейс: Проверить миграцию базы данных: после того как разработчики добавили новое поле, убедиться, что оно действительно появилось в таблице.
-- Добавление нового столбца ALTER TABLE employees ADD COLUMN phone_number VARCHAR(20);
-- Изменение типа столбца ALTER TABLE employees MODIFY COLUMN phone_number INT;
-- Удаление столбца ALTER TABLE employees DROP COLUMN birthdate;
4. Выборка данных (SELECT)
SELECT
— самая частая команда в работе тестировщика. Она позволяет "доставать" нужные данные для проверки. Для всех примеров будем использовать эту таблицу:
id | first_name | last_name | department_id | salary |
---|---|---|---|---|
1 | Иван | Петров | 1 | 70000.00 |
2 | Анна | Сидорова | 2 | 65000.00 |
3 | Сергей | Иванов | 1 | 72000.00 |
4 | Елена | Смирнова | 3 | 80000.00 |
5 | Дмитрий | Кузнецов | 2 | 60000.00 |
SELECT *: Выбрать все столбцы
QA-кейс: Посмотреть всю информацию о сотрудниках, чтобы убедиться, что тестовые данные на месте.
SELECT * FROM employees;
Результат:
id | first_name | last_name | department_id | salary |
---|---|---|---|---|
1 | Иван | Петров | 1 | 70000.00 |
2 | Анна | Сидорова | 2 | 65000.00 |
3 | Сергей | Иванов | 1 | 72000.00 |
4 | Елена | Смирнова | 3 | 80000.00 |
5 | Дмитрий | Кузнецов | 2 | 60000.00 |
SELECT DISTINCT: Уникальные значения
QA-кейс: Получить список всех уникальных ID отделов, в которых есть сотрудники, для проверки фильтра в UI.
SELECT DISTINCT department_id FROM employees;
Результат:
department_id |
---|
1 |
2 |
3 |
LIMIT: Ограничить количество записей
QA-кейс: Проверить пагинацию. Запросить первые 3 записи для первой страницы списка сотрудников.
SELECT * FROM employees LIMIT 3;
Результат:
id | first_name | last_name | department_id | salary |
---|---|---|---|---|
1 | Иван | Петров | 1 | 70000.00 |
2 | Анна | Сидорова | 2 | 65000.00 |
3 | Сергей | Иванов | 1 | 72000.00 |
AS: Переименовать столбец
QA-кейс: Подготовить данные для отчета, где названия столбцов должны быть на русском языке.
SELECT first_name AS "Имя", last_name AS "Фамилия" FROM employees;
Результат:
Имя | Фамилия |
---|---|
Иван | Петров |
Анна | Сидорова |
Сергей | Иванов |
Елена | Смирнова |
Дмитрий | Кузнецов |
WHERE: Фильтрация по условию
QA-кейс: Найти всех сотрудников из отдела с ID=1.
SELECT * FROM employees WHERE department_id = 1;
Результат:
id | first_name | last_name | department_id | salary |
---|---|---|---|---|
1 | Иван | Петров | 1 | 70000.00 |
3 | Сергей | Иванов | 1 | 72000.00 |
WHERE ... AND / OR: Комбинирование условий
QA-кейс (AND): Найти сотрудников из отдела 1, которые зарабатывают больше 71000.
SELECT * FROM employees WHERE department_id = 1 AND salary > 71000;
Результат (AND):
id | first_name | last_name | department_id | salary |
---|---|---|---|---|
3 | Сергей | Иванов | 1 | 72000.00 |
QA-кейс (OR): Найти всех сотрудников из отдела 1 или отдела 3.
SELECT * FROM employees WHERE department_id = 1 OR department_id = 3;
Результат (OR):
id | first_name | last_name | department_id | salary |
---|---|---|---|---|
1 | Иван | Петров | 1 | 70000.00 |
3 | Сергей | Иванов | 1 | 72000.00 |
4 | Елена | Смирнова | 3 | 80000.00 |
LIKE: Фильтр по шаблону
QA-кейс: Найти всех сотрудников, чья фамилия заканчивается на "ов".
-- % означает любое количество символов SELECT * FROM employees WHERE last_name LIKE '%ов';
Результат:
id | first_name | last_name | department_id | salary |
---|---|---|---|---|
1 | Иван | Петров | 1 | 70000.00 |
3 | Сергей | Иванов | 1 | 72000.00 |
QA-кейс: Найти всех, чье имя состоит из 4 букв и начинается на "Ива".
-- _ означает ровно один любой символ SELECT * FROM employees WHERE first_name LIKE 'Ива_';
Результат:
id | first_name | last_name | department_id | salary |
---|---|---|---|---|
1 | Иван | Петров | 1 | 70000.00 |
BETWEEN / IN / NOT: Диапазоны, списки и отрицание
BETWEEN: Найти сотрудников с зарплатой от 65000 до 75000 включительно.
SELECT * FROM employees WHERE salary BETWEEN 65000.00 AND 75000.00;
IN: Найти сотрудников из отделов 2 и 3.
SELECT * FROM employees WHERE department_id IN (2, 3);
NOT: Найти всех сотрудников НЕ из отдела 1.
SELECT * FROM employees WHERE NOT department_id = 1;
ORDER BY: Сортировка результатов
QA-кейс: Проверить правильность сортировки по зарплате в UI. Сначала по убыванию (DESC), потом по возрастанию (ASC).
-- Сортировка по убыванию SELECT * FROM employees ORDER BY salary DESC;
Результат (DESC):
id | first_name | last_name | department_id | salary |
---|---|---|---|---|
4 | Елена | Смирнова | 3 | 80000.00 |
3 | Сергей | Иванов | 1 | 72000.00 |
1 | Иван | Петров | 1 | 70000.00 |
2 | Анна | Сидорова | 2 | 65000.00 |
5 | Дмитрий | Кузнецов | 2 | 60000.00 |
5. Агрегация и Группировка
Агрегатные функции выполняют вычисления на наборе значений и возвращают одно-единственное значение. Они почти всегда используются с GROUP BY
.
COUNT: Подсчет количества
QA-кейс: После создания 5 пользователей через API, проверить, что в таблице `employees` действительно стало на 5 записей больше.
SELECT COUNT(*) AS total_employees FROM employees;
Результат:
total_employees |
---|
5 |
MIN / MAX / AVG / SUM: Минимум, максимум, среднее, сумма
QA-кейс: Проверить статистический виджет на дашборде, который должен показывать минимальную, максимальную и среднюю зарплату по компании.
SELECT MIN(salary) AS min_salary,
MAX(salary) AS max_salary,
AVG(salary) AS avg_salary,
SUM(salary) AS total_salary_fund
FROM employees;
Результат:
min_salary | max_salary | avg_salary | total_salary_fund |
---|---|---|---|
60000.00 | 80000.00 | 69400.00 | 347000.00 |
GROUP BY и HAVING: Группировка и фильтрация групп
QA-кейс: Найти отделы, в которых работает более одного сотрудника, чтобы проверить логику начисления бонусов руководителям этих отделов.
SELECT department_id,
COUNT(id) AS employee_count
FROM employees GROUP BY department_id HAVING COUNT(id) > 1;
Результат:
department_id | employee_count |
---|---|
1 | 2 |
2 | 2 |
Ключевое отличие: WHERE vs HAVING
WHERE
фильтрует строки до того, как они будут сгруппированы.HAVING
фильтрует группы после того, как они были созданы с помощьюGROUP BY
.
6. Объединение результатов
Операторы UNION
и UNION ALL
объединяют результаты двух или более SELECT
запросов в один набор данных.
Правила применения UNION:
- Каждый
SELECT
запрос вUNION
должен иметь одинаковое количество столбцов. - Столбцы также должны иметь совместимые типы данных (например, нельзя объединять число со строкой).
- Столбцы в каждом
SELECT
запросе должны быть в одинаковом порядке. - Названия столбцов в итоговом результате берутся из первого
SELECT
запроса.
UNION: Объединение с удалением дубликатов
QA-кейс: Получить единый список email'ов из таблицы сотрудников и таблицы клиентов для общей рассылки, избегая повторной отправки одному и тому же адресату.
SELECT email FROM employees UNION SELECT email FROM customers;
UNION ALL: Объединение всех записей
QA-кейс: Собрать полный лог всех действий (входы и выходы) из двух разных таблиц для анализа активности пользователя, сохраняя хронологию и все события.
SELECT user_id,
action,
timestamp FROM login_logs UNION ALL SELECT user_id,
action,
timestamp FROM action_logs;
7. JOIN'ы
JOIN'ы позволяют объединять строки из двух или более таблиц по связанным столбцам (ключам). Это одна из самых мощных концепций в SQL.
Таблицы для примеров:
id | name |
---|---|
1 | Иван |
2 | Анна |
3 | Петр |
order_id | user_id | item |
---|---|---|
101 | 1 | Книга |
102 | 2 | Телефон |
103 | 1 | Мышь |
104 | 4 | Лампа |
INNER JOIN: Только совпадения
Возвращает только те строки, для которых есть совпадение в обеих таблицах. Пользователи без заказов (Петр) и заказы без пользователей (заказ 104) не попадут в результат.
SELECT u.name, o.item FROM users u
INNER JOIN orders o ON u.id = o.user_id;
Результат:
name | item |
---|---|
Иван | Книга |
Анна | Телефон |
Иван | Мышь |
LEFT JOIN: Все из левой таблицы
Возвращает все строки из левой таблицы (users
) и совпавшие строки из правой (orders
). Если для пользователя нет заказа (как для Петра), в столбцах из правой таблицы будет NULL
.
SELECT u.name, o.item FROM users u
LEFT JOIN orders o ON u.id = o.user_id;
Результат:
name | item |
---|---|
Иван | Книга |
Иван | Мышь |
Анна | Телефон |
Петр | NULL |
RIGHT JOIN: Все из правой таблицы
Возвращает все строки из правой таблицы (orders
) и совпавшие строки из левой (users
). Если для заказа нет пользователя (как для заказа 104), в столбцах из левой таблицы будет NULL
.
SELECT u.name, o.item FROM users u
RIGHT JOIN orders o ON u.id = o.user_id;
Результат:
name | item |
---|---|
Иван | Книга |
Анна | Телефон |
Иван | Мышь |
NULL | Лампа |
8. Продвинутые темы
Транзакции
Транзакция — это последовательность операций, которая выполняется как единое целое по принципу "всё или ничего". Либо все операции успешны и сохраняются (COMMIT
), либо все отменяются (ROLLBACK
). Это гарантирует целостность данных.
START TRANSACTION;
-- Снимаем 100$ со счета A UPDATE Accounts SET balance = balance - 100 WHERE id = 'A';
-- Добавляем 100$ на счет B UPDATE Accounts SET balance = balance + 100 WHERE id = 'B';
-- Если обе операции успешны, сохраняем изменения COMMIT;
Зачем тестировщику дампы?
Дамп (dump) — это файл, содержащий структуру и данные базы данных в виде набора SQL-команд. QA-инженер использует дампы для:
- Воспроизведения багов. Если на продакшене произошел баг, связанный с данными, разработчики могут прислать "обезличенный" дамп (без персональных данных), чтобы QA мог локально развернуть копию БД и точно воспроизвести проблему.
- Настройки тестового окружения. Вместо ручного создания сотен тестовых записей, можно один раз развернуть готовый дамп с преднастроенными данными, что экономит массу времени.
- Тестирования миграций. Чтобы проверить, что скрипт обновления структуры БД (миграция) работает корректно, QA может взять дамп старой версии, "накатить" на него миграцию и проверить, что все данные на месте и структура обновилась правильно.
- Анализа данных от клиента. Иногда клиенты присылают дампы своих данных для анализа сложных проблем. QA может развернуть их на тестовом стенде и исследовать, не затрагивая "боевую" систему клиента.
9. Практический SQL для QA
SQL — это не теория, а ежедневный инструмент тестировщика. Вот как выглядит типичный рабочий процесс.
Шаг 0: Получение доступа
Прежде чем начать, вам понадобятся доступы к базе данных. Запросите у системного администратора или тимлида следующие данные:
- Хост (Host/Server): Адрес сервера, где находится БД (например,
db-test.myproject.com
). - Порт (Port): Обычно
5432
для PostgreSQL или3306
для MySQL. - Имя базы данных (Database Name): Например,
myproject_test_db
. - Имя пользователя (Username) и Пароль (Password).
- Клиент для подключения: Уточните, какой программой пользоваться (DBeaver, DataGrip, pgAdmin).
Пример: Тестирование регистрации нового пользователя
Представим, что мы тестируем форму регистрации на сайте.
- Подготовка:
Убедимся, что пользователя с нашим тестовым email еще не существует.
SELECT * FROM users WHERE email = 'qa-test-user@example.com';
Ожидаемый результат: запрос вернет 0 строк.
- Действие: Идем в интерфейс нашего приложения и регистрируем нового пользователя с данными: Имя - "Тестовый", Фамилия - "Пользователь", Email - "qa-test-user@example.com".
- Проверка:
Теперь ищем этого пользователя в базе данных.
SELECT * FROM users WHERE email = 'qa-test-user@example.com';
Ожидаемый результат: запрос вернет 1 строку.
- Валидация:
Внимательно проверяем все поля в полученной строке:
first_name
должен быть 'Тестовый'.last_name
должен быть 'Пользователь'.is_active
должен быть 'true' (или 1), если пользователь сразу активен.created_at
должен быть примерно равен текущему времени.
- Очистка:
Чтобы не оставлять тестовые данные в базе и иметь возможность повторить тест, удаляем созданную запись.
DELETE FROM users WHERE email = 'qa-test-user@example.com';
Этот шаг особенно важен для автотестов.