Architec.Ton is a ecosystem on the TON chain with non-custodial wallet, swap, apps catalog and launchpad.
Main app: @architec_ton_bot
Our Chat: @architec_ton
EU Channel: @architecton_eu
Twitter: x.com/architec_ton
Support: @architecton_support
Last updated 1 month, 1 week ago
Канал для поиска исполнителей для разных задач и организации мини конкурсов
Last updated 1 month, 4 weeks ago
Фремворк vs библиотека 🙌
В чем разница между библиотекой и фреймворком?👀
Если коротко и просто👇
*📌 *Библиотека — это набор инструментов, функций или классов, которые вы сами подключаете и вызываете в своём коде, когда это нужно. Вы полностью управляете процессом и решаете, как именно эти инструменты использовать.
📌 Фреймворк — это уже целая структура, которая задаёт правила и порядок работы. Вы добавляете свой код внутрь этой структуры, но основная логика и жизненный цикл уже управляются фреймворком.
Представьте стройку 🔨
🛠 Библиотека — это как набор инструментов: молоток, пила, шуруповёрт. Вы решаете, какие из них и когда использовать.
🏠 Фреймворк — это как готовый каркас дома. Вам остаётся добавить окна, двери и мебель, но основные правила и процесс строительства уже заданы.
Playwright как пример:
Playwright сам по себе — это библиотека. Он предоставляет API для управления браузерами (запуск, навигация по страницам, работа с элементами). Вы решаете, как и где его использовать, а сам Playwright не навязывает структуру.
Playwright Test — это уже фреймворк. Он добавляет тестовый раннер, готовый жизненный цикл тестов, параллельный запуск, ассерты и отчёты. С ним вам не нужно думать о базовой организации тестов — фреймворк берёт это на себя.
Ключевое различие👇
В библиотеке вы управляете всем сами. В фреймворке — вы следуете его правилам и структуре.
Какие еще примеры библиотеки/фреймворка знаете?🤔
Архитектура playwright🏠
Когда ты работаешь с инструментом важно исследовать его внутренности и понимать как он работает
Давайте разберем playwright
Корневая директория*📝
В корневой директории мы находим следующие папки:
🌸playwright/
🌸browser_patches/
🌸docs/
🌸examples/
🌸packages/
🌸tests/
🌸***utils/
А также файл package.json
, который включает следующие ключи:
{
"name": "playwright\-internal",
"private": true,
"workspaces": ["packages/*"]
}
Файл package.json
намекает, что основная функциональность находится внутри директории packages/
, поскольку корневой файл помечен как private
, имеет в названии "internal" и использует ключ "workspaces"
, который сообщает Node.js, что проект имеет несколько пакетов. Давайте быстро рассмотрим другие директории верхнего уровня перед тем, как углубиться в папку packages/
👇
✳️browser_patches
— эта папка содержит патчи для браузеров, добавляющие дополнительные элементы управления и функции к некоторым движкам браузеров, используемых в этом проекте. Интересно, что здесь есть патч для WebKit, позволяющий ему работать на Windows.
✳️ docs
— папка docs
содержит файлы Markdown, которые компилируются в документацию, представленную на сайте Playwright.
✳️ examples
— здесь находятся примеры тестовых скриптов, к которым можно обратиться при начале работы с проектом Playwright.
✳️ tests
— даже библиотеки для тестирования должны иметь автоматизированные тесты, которые написаны с использованием Playwright.
✳️ utils
— директория utils
содержит различные инструменты, используемые во время сборки, Docker-образы, функциональность для Azure, генератор файлов типов и многое другое.
Директория packages*✏️***
Директория packages
содержит более 20 отдельных пакетов, что усложняет понимание. Мы разделим этот список на понятные категории.
Пакеты для отчётности и генерации тестов
Playwright содержит множество различных пакетов для отчётности о тестах, каждый со своим набором функций. Кратко, список пакетов в этой категории:
✳️html\-reporter/
✳️recorder/
✳️trace\-viewer/
✳️trace/
✳️web/
Эти пакеты содержат код, связанный с обработкой отчётов о тестах или их генерацией с помощью пакета recorder
. Кроме того, есть trace
и trace\-viewer
, которые могут записываться во время выполнения тестов Playwright. Пакет web/
предоставляет утилиты, общие для различных веб-инструментов, перечисленных здесь.
Пакеты, специализированные для браузеров
Каждый из этих пакетов просто экспортирует пакет playwright\-core
вместе со скриптом установки только для соответствующего браузера. Вы можете найти их на npmjs, например, playwright\-chromium
— это отдельный пакет, который имеет Playwright, специализированный только для автоматизации Chromium.
✳️ playwright\-chromium/
✳️ playwright\-firefox/
✳️ playwright\-webkit/
Пакеты для установки браузеров
Эти пакеты включают только скрипты установки для каждого из браузеров. Например, playwright-browser-chromium соответствует пакету @playwright/browser-chromium на npmjs.
✳️playwright\-browser\-chromium/
✳️playwright\-browser\-firefox/
✳️playwright\-browser\-webkit/
Пакеты для тестирования компонентов
Эти пакеты связаны с экспериментальной системой тестирования компонентов в Playwright. Они предоставляют функциональность, аналогичную тому, как Jest может рендерить отдельные компоненты для разных библиотек.
✳️playwright\-ct\-core/
✳️playwright\-ct\-react/
✳️playwright\-ct\-react17/
✳️playwright\-ct\-solid/
✳️playwright\-ct\-svelte/
✳️playwright\-ct\-vue/
✳️playwright\-ct\-vue2/
Автоматизация тестирования:
#automation
#playwright
#cypress
#selenium
Инструменты:
#tools
#postman
#k6
#grafana
Процессы тестирования:
#process
#agile
#TDD
#BDD
Обучение и рекомендации:
#learning
#recommendation
#books
Практики:
#practices
#cleanСode
#unitTests
?Мокирование конкретных классов вместо интерфейсов
Приложение отправляет уведомления пользователям через SMS.
```
class SmsService {
sendSms(number: string, message: string): void {
// Логика отправки SMS
}
}
class NotificationManager {
constructor(private smsService: SmsService) {}
notifyUser(user: User, message: string): void {
this.smsService.sendSms(user.phoneNumber, message);
}
}
```
Антипаттерн:
В тестах мокируется конкретный класс SmsService
.
describe('NotificationManager', () => {
it('should send SMS notification', () => {
const smsService = new SmsService();
spyOn(smsService, 'sendSms');
const manager = new NotificationManager(smsService);
manager.notifyUser({ phoneNumber: '1234567890' }, 'Test Message');
expect(smsService.sendSms).toHaveBeenCalledWith('1234567890', 'Test Message');
});
});
Почему это плохо:
✖️Привязывает тест к конкретной реализации.
✖️Трудно заменить SmsService на другую реализацию (например, для разных стран).
✅Решение:
Использовать интерфейс для абстракции сервиса отправки сообщений.
```
interface IMessageService {
sendMessage(recipient: string, message: string): void;
}
class SmsService implements IMessageService {
sendMessage(recipient: string, message: string): void {
// Логика отправки SMS
}
}
class NotificationManager {
constructor(private messageService: IMessageService) {}
notifyUser(user: User, message: string): void {
this.messageService.sendMessage(user.phoneNumber, message);
}
}
```
?Тестирование с мокированием интерфейса:
describe('NotificationManager', () => {
it('should send message notification', () => {
const messageService: IMessageService = {
sendMessage: jasmine.createSpy('sendMessage'),
};
const manager = new NotificationManager(messageService);
manager.notifyUser({ phoneNumber: '1234567890' }, 'Test Message');
expect(messageService.sendMessage).toHaveBeenCalledWith('1234567890', 'Test Message');
});
});
?Что-то вроде выводов:
Стремитесь писать тесты, которые проверяют поведение через публичный интерфейс и фокусируются на результатах, а не на деталях реализации. Это сделает ваш код более надежным, а тесты — более ценными инструментами в процессе разработки.
Было полезно? Ставьте *?*?****
Выход playwright 1.47
⚡ Обновления Playwright:
1⃣ Network Tab (небольшие улучшения в UI mode и trace viewer)
⚪ Фильтрация по типу запроса и URL
⚪ Улучшенное отображения query parameters
⚪ Превью для шрифтов
*2⃣ *Опция — tsconfig
Теперь можно указать конкретный tsconfig для всех импортируемых файлов:
npx playwright test \-\-tsconfig tsconfig.test.json
3⃣ APIRequestContext
Поддержка URLSearchParams в query параметрах:
const response = await request.get('url', { params: 'userId=1' });
https://github.com/microsoft/playwright/releases/tag/v1.47.0
?Структура юнит тестов
Меня читают много разработчиков и скорее всего это пост для них.
При написании юнит тестов возникает необходимость структурировать код таким образом, чтобы он был понятным, легко поддерживаемым и эффективно выявлял ошибки. Один из наиболее популярных подходов для достижения этих целей — паттерн AAA (Arrange-Act-Assert).
Патерн делит процесс написание тестов на 3 логические части:
⚪️ Arrange (Подготовка) — вы готовите все необходимые данные и зависимости для теста
⚪️ Act (Действие) — выполняете основное действие, которое хотите протестировать
⚪️ Assert (Проверка) — на заключительном этапе вы проверяете результаты действия.
Пример прям из тестов текущего проекта:
```
test('Закрывает Drawer при вызове onClose', () => {
// Arrange
render();
const closeButton = screen.getByRole('button', { name: 'close' });
// Act
fireEvent.click(closeButton);
TypeScript
// Assert
expect(mockedUseStore().services.comments.close).toHaveBeenCalled();
});
```
Рекомендации?
Почти все эти рекомендации можно соблюдать автоматически настроив правила
eslint-a с плагином eslint-plugin-jest.
✖️ Избегайте тесты где используются несколько секций Arrange, Act, Assert.
Например:
```
test('Закрывает и открывает Drawer при вызове onClose', () => {
// Arrange
render();
const closeButton = screen.getByRole('button', { name: 'close' });
// Act
fireEvent.click(closeButton);
// Assert
expect(mockedUseStore().services.comments.close).toHaveBeenCalled();
// Arrange
const openCommentButton = screen.getByRole('button', { name: 'Комментарии' });
// Act
fireEvent.click(openCommentButton);
// Assert
expect(modal).toBeVisible();
});
```
✖️ Избегайте if в тестах.
Тесты должны быть последовательны и без ветвлений.
Включите правило линтера: no-conditional-in-test.
✔️ Один тест — одно действие
✔️ Один тест — одно утверждение, это не всегда возможно, старайтесь, чтобы в каждом тесте проверялось одно конкретное поведение. Это упрощает диагностику при возникновении ошибок.
Можно использовать правила линтера:
➡️ expect-expect — правило следит, что во всех тестах есть expect
➡️ max-expects — максимальное число expect в тестах
По мотивам книги Принципы юнит-тестирования?
Как сделать так, чтобы в ветку попадал только чистый и рабочий код?*??***
В разработке важно, чтобы в ветку попадал код, который соответствует стандартам и не ломает приложение или на код-ревью не писали ? Один из эффективных способов это обеспечить — использование Git хуков, особенно pre\-commit
. Этот хук запускает проверки до того, как изменения будут зафиксированы, и позволяет автоматизировать запуск линтера и тестов перед каждым коммитом.
Для упрощения этого процесса есть масса различных библиотек?:
?husky (nodejs)
?pre-commit (python)
?использовать нативные (для любого проекта)
Пример настройки для nodejs husky?
Прежде чем приступать к настройки у нас должны быть установлены linter, prettier
Пример package.json
{
"scripts": {
"lint": "eslint .",
"format": "prettier . \-\-write",
"test": "jest"
}
}
Команда init упрощает настройку husky в проекте. Он создает pre\-commit
в .husky/ и обновляет сценарий для подготовки в package.json.
npx husky init
Дальше просто добавляем наши скрипты проверки качества кода
echo "npm prettier && npm lint && npm test" > .husky/pre\-commit
После можно попробовать сделать коммит и наши скрипты запустятся
Если вам надо закоммитить быстро можно отключить запуск хуков
git commit \-m "..." \-n
Было полезно? Ставьте *?*?****
Локаторы vs селекторы??
Что такое селекторы и локаторы в Playwright?
? Селекторы — это строки, которые используются для сопоставления элементов в DOM страницы. Playwright поддерживает различные типы селекторов, включая поиск по тексту, CSS, XPath и другие.
? Локаторы — это абстракция, построенная на основе селекторов, которая позволяет находить любые элементы на странице, а также обеспечивает "умные" ожидания, являющиеся ключевой функцией Playwright.
Я планирую написать подробное руководство о том, как и какой локатор лучше использовать. Вот выдержка из документации по рекомендуемым локаторам. Если ни одна из функций не подходит, можно добавить атрибут data-testid:
?page.getByRole()
для поиска по явным и неявным атрибутам доступности.
?page.getByText()
для поиска по текстовому содержимому.
?page.getByLabel()
для поиска по лейблу
?page.getByPlaceholder()
для поиска поля ввода по плейсхолдеру.
?page.getByAltText()
для поиска элемента, по альтернативному тексту.
?page.getByTitle()
для поиска элемента по его атрибуту title.
?page.getByTestId()
для поиска элемента по атрибуту data-testid.
Было полезно? Ставьте *?*?****
Architec.Ton is a ecosystem on the TON chain with non-custodial wallet, swap, apps catalog and launchpad.
Main app: @architec_ton_bot
Our Chat: @architec_ton
EU Channel: @architecton_eu
Twitter: x.com/architec_ton
Support: @architecton_support
Last updated 1 month, 1 week ago
Канал для поиска исполнителей для разных задач и организации мини конкурсов
Last updated 1 month, 4 weeks ago