QA Family by Alexey – Telegram
QA Family by Alexey
1.55K subscribers
99 photos
6 videos
219 links
Команда:
- Иванов Алексей 2ГИС @alexey_qa
- Иванова Ксения Wink

Этот канал из моего лично трансформируется в канал онлайн сообщества QA Family

👥 Делаем митап @moscowqa
🎙Подкаст family-qa.mave.digital
Download Telegram
Давайте разберем конкретные примеры тестирования компонентов React для каждого из принципов FIRST ☝️

Источник: https://github.com/tekguard/Principles-of-Unit-Testing
Теги: #react #тестирование #FIRST
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👎59👍9
Рассказал о MemLab (спойлер: это инструмент для анализа и оптимизации потребления памяти вашими веб-приложениями) ➡️читать здесь.

Ранее уже писал о потреблении памяти веб-приложения:
🔵часть 1
🔵часть 2

👍 — если полезно, 👎 — ничего нового

Теги: #tools
Please open Telegram to view this post
VIEW IN TELEGRAM
👎64👍113
Так выглядит тест будущего, и это не bdd

test('Fill form', async ({ page }) => {
const aiArgs = { page, test };
await page.goto('/landings/open-account-and-invest/');
await ai(`Click the 'Открыть счет' button`, aiArgs);

await ai(`Wait until the form is fully loaded`, aiArgs);
await ai(`Fill the 'name' field with realistic data`, aiArgs);
await ai(`Fill the 'phone' field with the complete phone number '9195562010'`, aiArgs);
await ai(`Fill the 'email' field with realistic data`, aiArgs);
await ai(`Click the 'отправить' button`, aiArgs);

await ai(`Verify that a popup appears with the text 'Зарегистрироваться по номеру телефона'`, aiArgs);
});


ZeroStep — это инструмент, который улучшает тестирование с использованием Playwright, интегрируя искусственный интеллект, в частности, GPT-3.5 и GPT-4. Это позволяет сократить время на подготовку и исполнение тестов, а также уменьшить количество ошибок, связанных с изменениями в интерфейсе тестируемых приложений.

Я попробовал написать и автоматизировать тест, что мне показалось достаточно трудозатратным, требующим постоянного дебаггинга и проверки того, что именно тестирует мой тест.

Интересное представление о том, как будет выглядеть автоматизация будущего в виде промпт инженеринга, открывает новые перспективы в разработке тестов. Теперь вместо того, чтобы писать сложные и запутанные селекторы, можно использовать обычный разговорный язык для описания действий, которые должен выполнить тест. Кроме того, применение ИИ позволяет адаптироваться к изменениям в интерфейсе без необходимости переписывать тесты.

Хотя в настоящее время массовое использование таких инструментов, как ZeroStep, может быть ограничено из-за вопросов безопасности и недостаточного уровня доверия к автоматизации на основе ИИ, трудно предсказать, что будет через год. Технологии развиваются быстро, и возможности искусственного интеллекта в тестировании могут значительно расшириться, когда я начинал работать в далеком 2017 году я не мог представить о появлении ChatGPT, а сейчас это повседневный инструмент в работе.

Теги: #playwright #automation
👎61👍152
🤓 Всем привет!
Я решил более регулярно вести канал, и мне интересно, что вам интересно и в каком виде — поучаствуйте в опросе, а если что-то хочется добавить, напишите в комментариях👇
Please open Telegram to view this post
VIEW IN TELEGRAM
👎55🔥3
Как вам удобнее читать материал?
Anonymous Poll
71%
в сообщении
29%
карточками-картинками
👎52
Какой контент на моем канале для вас более полезный/интересный?
Anonymous Poll
77%
образовательный
71%
кейсы
27%
рассказы про конфы, доклады, митапы
👎62
🟢Что такое юнит тест? 🧩

🔎 Юнит тест — это тест, который проверяет правильность работы небольшого фрагмента кода (юнита).

🚩Особенности юнит тестов
1️⃣. Проверка небольших фрагментов кода.
2️⃣. Быстрая проверка.
3️⃣. Изоляция от остального кода.

🔍 Способы изоляции кода в юнит тестах
Тесты можно разделить на две школы по способу изоляции кода:
🔵Детройтская школа (классический подход)
🔵Лондонская школа

📘 Классический подход:
☑️Юнит тесты проверяют код с минимальной изоляцией.
☑️Интеграция с реальными зависимостями.

🎓 Лондонская школа:
☑️Сильная изоляция кода.
☑️Использование заглушек и моков для имитации зависимостей.


⚖️ Разница в подходах
🔵 Классический подход: Реальные зависимости, меньше моков.
🔵 Лондонская школа: Полная изоляция, много моков и заглушек.


💻 Примеры кода
Тестируемый код

// orderService.js
class OrderService {
constructor(paymentService) {
this.paymentService = paymentService;
}

placeOrder(order) {
if (this.paymentService.processPayment(order)) {
return 'Order placed';
} else {
return 'Payment failed';
}
}
}

// paymentService.js
class PaymentService {
processPayment(order) {
// Логика обработки платежа
return true; // Или false в случае ошибки
}
}


Классический подход 📘

test('placeOrder returns "Order placed" when payment is successful', () => {
const paymentService = new PaymentService();
const orderService = new OrderService(paymentService);
const order = { amount: 100 };

const result = orderService.placeOrder(order);

expect(result).toBe('Order placed');
});


Лондонская школа
🎓
test('placeOrder returns "Order placed" when payment is successful', () => {
const paymentService = { processPayment: jest.fn().mockReturnValue(true) };
const orderService = new OrderService(paymentService);
const order = { amount: 100 };

const result = orderService.placeOrder(order);

expect(result).toBe('Order placed');
expect(paymentService.processPayment).toHaveBeenCalledWith(order);
});


💡Вывод:
Выбор подхода зависит от конкретного проекта и предпочтений команды.

Теги: #unitTests #testing #cleanСode
Please open Telegram to view this post
VIEW IN TELEGRAM
👎63👍83
🤔А какой подход используете вы?
Anonymous Poll
74%
Классический подход 📘
31%
Лондонская школа 🎓
👎65
🍔Метрика покрытия кода: ограничения и примеры

Метрика покрытия кода показывает, какая доля исходного кода была выполнена в тестах.

Однако стопроцентное покрытие кода не гарантирует идеальное качество или отсутствие ошибок. Давайте рассмотрим два основных типа метрик покрытия кода и их ограничения.

Типы метрик покрытия кода
1️⃣ Code Coverage (Покрытие кода)
2️⃣ Branch Coverage (Покрытие ветвей)

Code Coverage
Code Coverage измеряет отношение количества выполненных строк кода к общему количеству строк кода. На первый взгляд, кажется логичным стремиться к максимальному покрытию, но этот подход имеет свои недостатки.

Пример:
const evaluate = (x) => {
if (x > 10) {
return "Greater";
} else {
return "Lesser";
}
};

// Тесты
assert(evaluate(5) == "Lesser");


В этом примере тесты покрывают 50% строк кода.


Теперь рассмотрим пример рефакторинга кода:
const evaluateRefactor = (x) => (x > 10) ? "Greater" : "Lesser";

// Тесты
assert(evaluateRefactor(5) == "Lesser");


В этом примере тесты покрывают только одну строку, что соответствует 100% покрытия


Проблемы с таким подходом:
1️⃣ Тесты могут выполнять строки кода без проверки их корректности.
2️⃣ Тесты не обязательно покрывают все возможные крайние случаи.
3️⃣ Высокий процент покрытия может создать иллюзию надежности.

Branch Coverage
Branch Coverage измеряет отношение количества покрытых ветвей к общему количеству ветвей в коде. Ветви – это управляющие структуры, такие как if, switch, и циклы.

Пример:
const evaluate = (x) => {
if (x > 10) {
return "Greater";
} else if (x < 5) {
return "Lesser";
} else {
return "Equal";
}
};

// Тесты
assert(evaluate(15) == "Greater");
assert(evaluate(3) == "Lesser");
assert(evaluate(7) == "Equal");


В этом примере тесты покрывают все возможные ветви: if (x > 10), else if (x < 5) и else. Таким образом, достигается стопроцентное покрытие ветвей. Однако это не гарантирует, что все граничные условия, такие как точные значения 10 и 5, были протестированы.

Проблемы с таким подходом:
1️⃣ Неполное покрытие сценариев
2️⃣ Упущенные граничные случаи

Заключение:
➡️Метрика покрытия кода, будь то code coverage или branch coverage, является полезным инструментом, и они могут говорить о проблемах
➡️Низкие показатели говорят о проблема с тестами, однако высокие показатели не гарантируют что с тестами все в порядке
➡️Метрики покрытия - начальный этап на пути к хорошим тестам.

Ставьте 👍 👎

Теги: #code_coverage #branch_coverage #automation
Please open Telegram to view this post
VIEW IN TELEGRAM
👎56👍143
Cors и как его обойти

Представьте, что вы тестируете веб-приложение. Ваше приложение может обращаться к данным с другого сервера (например, API или статики). Однако, по умолчанию браузеры блокируют такие запросы, если они идут с одного домена на другой.
Access to fetch at 'https://api.example.com/data' from origin 'https://myapp.com' 
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present
on the requested resource.


🔎CORS (Cross-Origin Resource Sharing) позволяет настроить разрешения, чтобы ваш браузер мог безопасно запрашивать данные с других доменов.

Если CORS настроен неправильно, вы можете столкнуться с ситуацией, когда ваш тестируемый веб-сайт пытается получить данные с другого домена, а браузер блокирует запрос. Вы увидите ошибку в консоли разработчика, что "доступ запрещен из-за политики CORS".

Как обойти CORS при тестировании?
Иногда, для тестирования или разработки, нужно временно обойти CORS. Вот несколько способов:

1️⃣ Запуск браузера без проверки CORS:
🟣Вы можете запустить Chrome с флагом -disable-web-security, чтобы отключить проверку CORS. Это быстрое решение, когда вам нужно протестировать что-то без лишних препятствий.
🟣Например, запустите Chrome с командой:
➡️На Windows: start chrome --disable-web-security --user-data-dir="C:/chrome_dev"
➡️На macOS: open -na "Google Chrome" --args --disable-web-security --user-data-dir="/tmp/chrome_dev"

2️⃣ Использование прокси-сервера(fiddler, charles):
🟣Вы можете настроить прокси-сервер, который будет делать запросы к другому домену от имени вашего приложения. Таким образом, ваш браузер общается только с вашим сервером, и CORS не мешает.

3️⃣ Установка расширений для браузера:
🟣Есть расширения для Chrome и других браузеров, которые позволяют временно отключить проверку CORS. Однако их стоит использовать с осторожностью.

4️⃣Настройка CORS на сервере:
🟣Если у вас есть доступ к серверу, с которого делаются запросы, можно настроить его так, чтобы он разрешал запросы с вашего домена, добавив правильные заголовки CORS. Например, Access-Control-Allow-Origin: * разрешает запросы со всех доменов.

😉Важно помнить
Обходить CORS можно только в процессе тестирования или разработки. В реальных условиях его следует настраивать правильно, чтобы сохранить безопасность приложения и данных.

Ставьте 👍 👎
Теги: #cors #security #tools
Please open Telegram to view this post
VIEW IN TELEGRAM
👎61👍144
🖥Тестирование тригеров GTM

Если вы занимаетесь тестированием веб-сайтов, то, вероятно, вам приходилось тестировать триггеры в Google Tag Manager и отправлять события аналитики.

Почему это важно? Дело в том, что большинство таких событий имеют прямое отношение к маркетингу. Маркетологи используют различные метрики продаж, чтобы понять, как лучше продавать. В общем, это напрямую связано с деньгами.💸

Как тестировать события

1⃣ для ручного тестирования и самый удобный способ это использовать https://tagassistant.google.com/
Там просто вставляете url, и проходите тест кейсы, а в другом окне наблюдаете события (рекомендуем)

2⃣ Использовать консоли разработчика
все события пушится в переменную dataLayer

3⃣ Тестирование через Network-панель браузера, можно наблюдать был ли отправлен запрос на нужный сервер (например, на сервер Google Analytics).


Для автоматизированного тестирования на Playwright, вы можете использовать несколько подходов👇

*️⃣ отслеживание через запросы
test('Track network request and verify payload', async ({ page }) => {
await page.goto('https://your-website.com');

// Перехват и проверка сетевых запросов
const [response] = await Promise.all([
page.waitForResponse(response => response.url().includes('www.google-analytics.com/collect') && response.status() === 200),
// Выполняем действие на странице, которое должно вызвать запрос
page.click('button')
]);

const requestPayload = JSON.parse(response.request().postData());

expect(requestPayload).toHaveProperty('event', 'yourExpectedEvent');
expect(requestPayload).toHaveProperty('gtm', 'expectedGtmId');
});


*️⃣проверка данных в dataLayer
test('Check dataLayer for specific event', async ({ page }) => {
await page.goto('https://your-website.com');

// Выполняем действие на странице
await page.click('button#yourButton');

// Получаем значение dataLayer из контекста страницы
const dataLayer = await page.evaluate(() => window.dataLayer);

// Проверка, что dataLayer содержит ожидаемое событие
const eventData = dataLayer.find(event => event.event === 'yourExpectedEvent');

expect(eventData).not.toBeNull();
expect(eventData).toHaveProperty('gtm', 'yourExpectedGtm');
});

Отслеживание сетевых запросов через Network-панель полно и надежно, но тесты получаются менее стабильны. Проверка данных в dataLayer проста и быстро настраивается, но может пропускать события при перезагрузке страницы или изменениях в dataLayer.

Ставьте 👍 👎


Теги: #testing #playwright #automation #dataLayer #GTM #тестирование #разработка
Please open Telegram to view this post
VIEW IN TELEGRAM
👎66👍112
#дайджест 📢


⚡️ В nodeJS 22.6 добавили поддержку typenoscript

⚡️ Playwright в 👩‍💻 версии **1.46
🌟 позволяет указывать клиентские сертификаты, теперь не надо игнорировать https
🌟 новая опция CLI --only-changed позволяет запускать только тестовые файлы, которые изменились с момента последней фиксации git
🌟 Обновление UI Mode / Trace Viewer
🌟 В APIRequestContext.fetch() появилась новая опция maxRetries. Она позволяет повторять попытку при возникновении сетевой ошибки ECONNRESET.
🌟 Опция Box в фикстурах уменьшает мусор в отчетах

⚡️👩‍💻 k6 v0.53.0
Добавили поддержку нативных ECMAScript модулей
и другие улучшения

⚡️ WebdriverIO 👩‍💻 v9
Все сеансы будут автоматически использовать протокол Bidi
Подробнее

Теги: #updates
Please open Telegram to view this post
VIEW IN TELEGRAM
👎56👍64
👨‍💻Скрипты в консоль
В основном консоль используют для отслеживания ошибок на сайте.

Я предлагаю открыть консоль по новому для обычного QA.

Когда я только начинал свой путь в IT, я играл в одну браузерную игру. Тогда я и представить не мог, что существует автоматизация. Мой первый код на JavaScript был связан со сбором подарков в игре.

Чтобы собрать раньше всех в игре я использовал самый примитивный код, который вставлял в консоль
setInterval(()=> {
$('#gift').click()
}, 150)


Суть кода понятна каждому, где мы просто кликаем по селекту каждые 150 мс.


Давайте я подскажу кейсы где еще можно использовать простые скриптики для ускорения ручного регресса.

В основном консоль используют для отслеживания ошибок, но мало кто знает, что ее можно использовать для простой автоматизации или в качестве помощника.

Кейс 1: Подсчёт элементов на странице📝
Этот кейс вы уже упомянули, и он действительно полезен для быстрой оценки, например, количества отображаемых элементов.
const countElement = $$('[class^="_ObjectsListCard"]').length;
console.log(`Количество проектов: ${countElement}`);


Кейс 2: Парсинг данных со страницы (ссылки)🔗
Иногда нужно собрать все ссылки со страницы, например, для проверки их на работоспособность или для подготовки тест-кейсов.
const links = [...document.querySelectorAll('a')].map(link => link.href);
console.log('Все ссылки на странице:', links);


Кейс 3: Парсинг данных с таблицы (таблицу)🫥
Недавно я работал над задачей, связанной с таблицей, чтобы получить данные о списках поступающих и оценить вероятность поступления своего брата. Данные из таблицы для дальнейшего анализа, можно использовать следующий скрипт:
const tableRows = [...document.querySelectorAll('table tbody tr')];
const data = tableRows.map(row => {
const columns = row.querySelectorAll('td');
return {
column1: columns[0].innerText,
column2: columns[1].innerText,
column3: columns[2].innerText,
};
});
console.log('Данные из таблицы:', data);


Кейс 4: Парсинг данных и выполнение вычислений 🎙
Можно не только парсить данные, но и сразу выполнять вычисления. Например, если нужно суммировать значения в колонке:
const tableRows = [...document.querySelectorAll('table tbody tr')];
const total = tableRows.reduce((sum, row) => {
const value = parseFloat(row.querySelector('td:nth-child(3)').innerText);
return sum + (isNaN(value) ? 0 : value);
}, 0);
console.log(`Сумма значений в третьей колонке: ${total}`);


Кейс 5: Отправка запросов для подготовки данных🟢
Иногда требуется подготовить данные или проверить API без использования Postman или других инструментов. Это можно сделать прямо из консоли:
fetch('<https://example.com/api/data>', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ key: 'value' }),
})
.then(response => response.json())
.then(data => console.log('Ответ от сервера:', data))
.catch(error => console.error('Ошибка:', error));


Кейс 6: Подключение к сокетам
Если ваш проект использует WebSocket, можно подключиться к сокету и прослушивать события прямо в консоли:
const socket = new WebSocket('wss://example.com/socket');

socket.onopen = () => {
console.log('Соединение установлено');
socket.send(JSON.stringify({ action: 'subscribe', channel: 'updates' }));
};

//далее отправляем различные запросы


Кейс 7: Заполнение форм
Для ускорения тестирования форм можно использовать автоматическое заполнение и отправку данных:
document.querySelector('#name').value = 'Тестовое имя';
document.querySelector('#email').value = 'test@example.com';
document.querySelector('form').submit();
console.log('Форма заполнена и отправлена');

Теги: #tools
Please open Telegram to view this post
VIEW IN TELEGRAM
👎58👍166
Важное замечание👆
Однако стоит отметить, что не всегда удается просто кликнуть или заполнить поля формы через консоль. Это может быть связано с использованием сложных UI-фреймворков, которые добавляют валидацию или управляют состоянием элементов на странице. Например, в некоторых случаях элемент может не воспринимать ввод значения через value, так как внутренние скрипты фреймворка могут ожидать определенных событий или использовать собственные механизмы управления состоянием.

В таких ситуациях можно попытаться вызвать соответствующие события вручную:
const nameInput = document.querySelector('#name');
nameInput.value = 'Тестовое имя';
nameInput.dispatchEvent(new Event('input', { bubbles: true }));
nameInput.dispatchEvent(new Event('change', { bubbles: true }));


Если и это не помогает, стоит рассмотреть использование других инструментов для автоматизации, таких как Selenium или Cypress, которые могут эмулировать взаимодействие пользователя с элементами страницы на более глубоком уровне.

О хранении и управлении скриптами будет завтра. Было полезно? Ставьте 👍👎

Теги: #automation #tools
Please open Telegram to view this post
VIEW IN TELEGRAM
2👎60👍152