0 added
0 removed
Original
2026-01-01
Modified
2026-03-10
1
<ul><li><a>Датаклассы в Python</a></li>
1
<ul><li><a>Датаклассы в Python</a></li>
2
<li><a>Функционал библиотеки Pydantic</a><ul><li><a>Возможности Pydantic</a></li>
2
<li><a>Функционал библиотеки Pydantic</a><ul><li><a>Возможности Pydantic</a></li>
3
<li><a>Недостатки </a></li>
3
<li><a>Недостатки </a></li>
4
</ul></li>
4
</ul></li>
5
<li><a>Функционал библиотеки Faker</a><ul><li><a>Формат JSON</a></li>
5
<li><a>Функционал библиотеки Faker</a><ul><li><a>Формат JSON</a></li>
6
<li><a>Faker легко установить и использовать</a></li>
6
<li><a>Faker легко установить и использовать</a></li>
7
<li><a>Дополнительно</a></li>
7
<li><a>Дополнительно</a></li>
8
</ul></li>
8
</ul></li>
9
</ul><p><em>По материалам открытых уроков и выступлений Светланы Лебедевой, старшего инженера по тестированию ПО и преподавателя OTUS</em></p>
9
</ul><p><em>По материалам открытых уроков и выступлений Светланы Лебедевой, старшего инженера по тестированию ПО и преподавателя OTUS</em></p>
10
<h2><strong>Датаклассы в Python</strong></h2>
10
<h2><strong>Датаклассы в Python</strong></h2>
11
<p><strong>Словари и дата-классы</strong><strong></strong>Перед тем как перейти к обзору библиотек, рассмотрим различия словарей и датаклассов.</p>
11
<p><strong>Словари и дата-классы</strong><strong></strong>Перед тем как перейти к обзору библиотек, рассмотрим различия словарей и датаклассов.</p>
12
<p><strong>Словарь (dictionary):</strong>структура данных, которая позволяет хранить пары "ключ-значение". Ключ - неизменяемый тип данных, обычно - строка, но ключом может быть и целое число, число с точкой или даже "кортеж". Данные из словаря мы извлекаем по ключу. Скажем сразу: в этой статье речь идёт о базовом словаре (dict), а не о более продвинутой структуре данных TypedDict. </p>
12
<p><strong>Словарь (dictionary):</strong>структура данных, которая позволяет хранить пары "ключ-значение". Ключ - неизменяемый тип данных, обычно - строка, но ключом может быть и целое число, число с точкой или даже "кортеж". Данные из словаря мы извлекаем по ключу. Скажем сразу: в этой статье речь идёт о базовом словаре (dict), а не о более продвинутой структуре данных TypedDict. </p>
13
<p>Обычно инженеры по автоматизации тестирования работают со структурой JSON, которая проще всего конвертируется в обычный dict. У dict нет чёткой структуры и валидации типов данных; значения могут быть самых разных типов: как изменяемых, так и неизменяемых, и при инициализации словаря мы не можем задать ограничения по добавляемым в него типам данным. </p>
13
<p>Обычно инженеры по автоматизации тестирования работают со структурой JSON, которая проще всего конвертируется в обычный dict. У dict нет чёткой структуры и валидации типов данных; значения могут быть самых разных типов: как изменяемых, так и неизменяемых, и при инициализации словаря мы не можем задать ограничения по добавляемым в него типам данным. </p>
14
<p><strong>Датаклассы</strong>: сравнительно новая фича в Python. Как видно из названия, эти классы представляют набор инструментов для хранения и обработки данных.</p>
14
<p><strong>Датаклассы</strong>: сравнительно новая фича в Python. Как видно из названия, эти классы представляют набор инструментов для хранения и обработки данных.</p>
15
<p>Вот основные отличия датаклассов от обычных классов:</p>
15
<p>Вот основные отличия датаклассов от обычных классов:</p>
16
<ul><li>При использовании датаклассов не нужно думать о методе __init__ (метод, который вызывается при создании объекта класса).</li>
16
<ul><li>При использовании датаклассов не нужно думать о методе __init__ (метод, который вызывается при создании объекта класса).</li>
17
<li>Не нужно думать о методах, которые позволяют сравнивать два объекта одного класса.</li>
17
<li>Не нужно думать о методах, которые позволяют сравнивать два объекта одного класса.</li>
18
<li>Код становится чище и красивее.</li>
18
<li>Код становится чище и красивее.</li>
19
<li>Чтобы создать датакласс, нужно просто использовать декоратор @dataclass.</li>
19
<li>Чтобы создать датакласс, нужно просто использовать декоратор @dataclass.</li>
20
<li>Есть метод __post_init__, который позволяет добавить данные уже после инициализации объекта этого класса.</li>
20
<li>Есть метод __post_init__, который позволяет добавить данные уже после инициализации объекта этого класса.</li>
21
</ul><p>Модуль dataclasses также включает в себя функцию field, которая позволяет более гибко настраивать поля датаклассов. С помощью field можно задавать параметры по умолчанию, функции для создания значений по умолчанию (или "фабрики") и параметры, которые влияют на генерацию методов.</p>
21
</ul><p>Модуль dataclasses также включает в себя функцию field, которая позволяет более гибко настраивать поля датаклассов. С помощью field можно задавать параметры по умолчанию, функции для создания значений по умолчанию (или "фабрики") и параметры, которые влияют на генерацию методов.</p>
22
<p><strong>Пример использования датакласса и функции field: </strong></p>
22
<p><strong>Пример использования датакласса и функции field: </strong></p>
23
from dataclasses import dataclass, field from typing import List @dataclass class Student: name: str age: int grades: List[int] = field(default_factory=list)<p>Здесь мы создаём класс для хранения данных ученика, где поле grades по умолчанию - пустой список. </p>
23
from dataclasses import dataclass, field from typing import List @dataclass class Student: name: str age: int grades: List[int] = field(default_factory=list)<p>Здесь мы создаём класс для хранения данных ученика, где поле grades по умолчанию - пустой список. </p>
24
<p>Для валидации данных в датаклассах можно использовать метод __post_init__, который вызывается сразу после генерации __init__. Это позволяет выполнять дополнительную логику. Например, проверку типов и значений:</p>
24
<p>Для валидации данных в датаклассах можно использовать метод __post_init__, который вызывается сразу после генерации __init__. Это позволяет выполнять дополнительную логику. Например, проверку типов и значений:</p>
25
from dataclasses import dataclass, field @dataclass class Product: name: str price: float quantity: int = field(default=0) def __post_init__(self): if self.price <= 0: raise ValueError("Цена должна быть больше 0") if self.quantity < 0: raise ValueError("Количество должно быть больше 0") # Правильное использование product = Product(name="Laptop", price=1000.0, quantity=5) # Неправильное использование вызовет исключение try: product_with_negative_price = Product(name="Laptop", price=-1000.0) except ValueError as e: print(e) # Цена должна быть больше 0<p><strong>Библиотеки Faker и Pydantic упрощают процесс валидации и генерации данных, а потому - очень полезны в процессе автоматизации тестирования</strong>.</p>
25
from dataclasses import dataclass, field @dataclass class Product: name: str price: float quantity: int = field(default=0) def __post_init__(self): if self.price <= 0: raise ValueError("Цена должна быть больше 0") if self.quantity < 0: raise ValueError("Количество должно быть больше 0") # Правильное использование product = Product(name="Laptop", price=1000.0, quantity=5) # Неправильное использование вызовет исключение try: product_with_negative_price = Product(name="Laptop", price=-1000.0) except ValueError as e: print(e) # Цена должна быть больше 0<p><strong>Библиотеки Faker и Pydantic упрощают процесс валидации и генерации данных, а потому - очень полезны в процессе автоматизации тестирования</strong>.</p>
26
<h2><strong>Функционал библиотеки Pydantic</strong></h2>
26
<h2><strong>Функционал библиотеки Pydantic</strong></h2>
27
<p>Pydantic - библиотека, в основе которой лежит концепция датаклассов или "моделей". Библиотека позволяет удобно хранить и валидировать данные прямо в момент создания объекта класса. Кроме того, в Pydantic можно превращать данные, как из модели данных - в JSON, так и наоборот: из JSON - в модель данных. </p>
27
<p>Pydantic - библиотека, в основе которой лежит концепция датаклассов или "моделей". Библиотека позволяет удобно хранить и валидировать данные прямо в момент создания объекта класса. Кроме того, в Pydantic можно превращать данные, как из модели данных - в JSON, так и наоборот: из JSON - в модель данных. </p>
28
<p>Pydantic широко используется не только в автоматизированном тестировании, но и в бэкенд-разработке для валидации данных с сервера. Поэтому у Pydantic огромное сообщество: всегда найдётся кто-то, кто поможет вам решить вопрос.</p>
28
<p>Pydantic широко используется не только в автоматизированном тестировании, но и в бэкенд-разработке для валидации данных с сервера. Поэтому у Pydantic огромное сообщество: всегда найдётся кто-то, кто поможет вам решить вопрос.</p>
29
<h3><strong>Возможности Pydantic</strong></h3>
29
<h3><strong>Возможности Pydantic</strong></h3>
30
<p><strong>Поддержка аннотаций типов</strong>: в Pydantic можно управлять валидацией схем и сериализацией. Это упрощает изучение, уменьшает количество кода и обеспечивает интеграцию с IDE.</p>
30
<p><strong>Поддержка аннотаций типов</strong>: в Pydantic можно управлять валидацией схем и сериализацией. Это упрощает изучение, уменьшает количество кода и обеспечивает интеграцию с IDE.</p>
31
<p><strong>Скорость:</strong>логика валидации Pydantic написана на Rust. Поэтому Pydantic - одна из самых быстрых библиотек для валидации данных в Python.</p>
31
<p><strong>Скорость:</strong>логика валидации Pydantic написана на Rust. Поэтому Pydantic - одна из самых быстрых библиотек для валидации данных в Python.</p>
32
<p><strong>JSON Schema:</strong>модели Pydantic могут генерировать JSON Schema, что облегчает интеграцию с другими инструментами.</p>
32
<p><strong>JSON Schema:</strong>модели Pydantic могут генерировать JSON Schema, что облегчает интеграцию с другими инструментами.</p>
33
<p><strong>Строгий и гибкий режимы:</strong>Pydantic может работать в строгом режиме (strict=True), где данные не преобразуются, или в гибком режиме (strict=False), где Pydentic при необходимости пытается привести данные к правильному типу.</p>
33
<p><strong>Строгий и гибкий режимы:</strong>Pydantic может работать в строгом режиме (strict=True), где данные не преобразуются, или в гибком режиме (strict=False), где Pydentic при необходимости пытается привести данные к правильному типу.</p>
34
<p><strong>Настройка:</strong>Pydantic позволяет применять пользовательские валидаторы и сериализаторы для изменения обработки данных разными способами.</p>
34
<p><strong>Настройка:</strong>Pydantic позволяет применять пользовательские валидаторы и сериализаторы для изменения обработки данных разными способами.</p>
35
<p><strong>Экосистема:</strong>около 8000 пакетов на PyPI используют Pydantic.</p>
35
<p><strong>Экосистема:</strong>около 8000 пакетов на PyPI используют Pydantic.</p>
36
<p><strong>Распространение:</strong>Pydantic скачивается более 70 миллионов раз в месяц; используется всеми компаниями FAANG и 20 из 25 крупнейших компаний NASDAQ</p>
36
<p><strong>Распространение:</strong>Pydantic скачивается более 70 миллионов раз в месяц; используется всеми компаниями FAANG и 20 из 25 крупнейших компаний NASDAQ</p>
37
<p><strong>Подробнее о возможностях библиотеки Pydantic:</strong><a>смотреть фрагмент конференции "OTUS CONF: Тестирование" </a></p>
37
<p><strong>Подробнее о возможностях библиотеки Pydantic:</strong><a>смотреть фрагмент конференции "OTUS CONF: Тестирование" </a></p>
38
<h3><strong>Недостатки </strong></h3>
38
<h3><strong>Недостатки </strong></h3>
39
<ul><li>Не входит в стандартную библиотеку Python</li>
39
<ul><li>Не входит в стандартную библиотеку Python</li>
40
<li>Требует много времени на освоение из-за обширной документации</li>
40
<li>Требует много времени на освоение из-за обширной документации</li>
41
</ul><p>Чтобы использовать модель Pydantic, достаточно "унаследовать" новый класс от класса BaseModel, после чего обширный функционал библиотеки станет доступен. </p>
41
</ul><p>Чтобы использовать модель Pydantic, достаточно "унаследовать" новый класс от класса BaseModel, после чего обширный функционал библиотеки станет доступен. </p>
42
<p>Пример:</p>
42
<p>Пример:</p>
43
from pydantic import BaseModel, Field, field_validator from typing import List class Product(BaseModel): name: str price: float = Field(..., gt=0, description="Price must be greater than zero") quantity: int = Field(default=0, ge=0, description="Quantity must be greater than zero") tags: List[str] = [] @field_validator('name') @classmethod def name_must_not_be_empty(cls, v): if not v.strip(): raise ValueError('Name must not be empty') return v @field_validator('tags') @classmethod def tags_must_be_non_empty(cls, v): if not v: raise ValueError('Tags must not be empty') return v # Правильное использование try: product = Product(name="Laptop", price=1000.0, quantity=5, tags=["electronics", "computers"]) print(product) except ValueError as e: print(e) # Неправильное использование вызовет исключение try: invalid_product = Product(name=" ", price=-1000.0, quantity=-1, tags=[]) except ValueError as e: print(e)<p><strong>В этом примере:</strong></p>
43
from pydantic import BaseModel, Field, field_validator from typing import List class Product(BaseModel): name: str price: float = Field(..., gt=0, description="Price must be greater than zero") quantity: int = Field(default=0, ge=0, description="Quantity must be greater than zero") tags: List[str] = [] @field_validator('name') @classmethod def name_must_not_be_empty(cls, v): if not v.strip(): raise ValueError('Name must not be empty') return v @field_validator('tags') @classmethod def tags_must_be_non_empty(cls, v): if not v: raise ValueError('Tags must not be empty') return v # Правильное использование try: product = Product(name="Laptop", price=1000.0, quantity=5, tags=["electronics", "computers"]) print(product) except ValueError as e: print(e) # Неправильное использование вызовет исключение try: invalid_product = Product(name=" ", price=-1000.0, quantity=-1, tags=[]) except ValueError as e: print(e)<p><strong>В этом примере:</strong></p>
44
<ul><li>Класс Product наследуется от BaseModel Pydantic.</li>
44
<ul><li>Класс Product наследуется от BaseModel Pydantic.</li>
45
<li>Поля price и quantity используют встроенные валидаторы gt (greater than) и ge (greater or equal) для проверки значений.</li>
45
<li>Поля price и quantity используют встроенные валидаторы gt (greater than) и ge (greater or equal) для проверки значений.</li>
46
<li>Пользовательский валидатор для поля name проверяет, что имя не пустое.</li>
46
<li>Пользовательский валидатор для поля name проверяет, что имя не пустое.</li>
47
<li>Пользовательский валидатор для поля tags проверяет, что каждый тег не пустой.</li>
47
<li>Пользовательский валидатор для поля tags проверяет, что каждый тег не пустой.</li>
48
</ul><h2><strong>Функционал библиотеки Faker</strong></h2>
48
</ul><h2><strong>Функционал библиотеки Faker</strong></h2>
49
<p>Faker - библиотека, которая генерирует реалистичные тестовые данные с разной локализацией. У этой библиотеки много провайдеров: провайдер адреса, провайдер номеров автомобилей, банковской информации, штрихкодов, эмоджи, текстовый провайдер, провайдер для генерации географических данных и проч.</p>
49
<p>Faker - библиотека, которая генерирует реалистичные тестовые данные с разной локализацией. У этой библиотеки много провайдеров: провайдер адреса, провайдер номеров автомобилей, банковской информации, штрихкодов, эмоджи, текстовый провайдер, провайдер для генерации географических данных и проч.</p>
50
<p>Также у Faker много локализаций с данными, специфичными для конкретной страны.</p>
50
<p>Также у Faker много локализаций с данными, специфичными для конкретной страны.</p>
51
<h3><strong>Формат JSON</strong></h3>
51
<h3><strong>Формат JSON</strong></h3>
52
<p>Часто в проекте нужно сгенерировать какой-то JSON, который должен содержать данные о пользователе. И вам приходится придумывать фамилию, имя, отчество, номер карты, адрес, email. Чтобы не тратить время, вы можете сделать всё это с помощью библиотеки Faker. Кроме того, с помощью Faker можно наполнять базы данных и делать тестовые файлы.</p>
52
<p>Часто в проекте нужно сгенерировать какой-то JSON, который должен содержать данные о пользователе. И вам приходится придумывать фамилию, имя, отчество, номер карты, адрес, email. Чтобы не тратить время, вы можете сделать всё это с помощью библиотеки Faker. Кроме того, с помощью Faker можно наполнять базы данных и делать тестовые файлы.</p>
53
<p><strong>Подробнее про использование Faker:</strong><a>смотреть запись вебинара на Youtube</a></p>
53
<p><strong>Подробнее про использование Faker:</strong><a>смотреть запись вебинара на Youtube</a></p>
54
<h3><strong>Faker легко установить и использовать</strong></h3>
54
<h3><strong>Faker легко установить и использовать</strong></h3>
55
->стандартная команда !pip install Faker Пишем код с использованием Faker: from faker import Faker faker = Faker() print(f'name: {faker.name()}') # name: Arthur Patton print(f'address: {faker.address()}') # address: 0638 Larsen Way, Tylermouth, CA 48344 print(f'text: {faker.sentence()}') # text: While per budget up technology design.<p>Теперь объединим две библиотеки, чтобы сгенерировать простой JSON-объект:</p>
55
->стандартная команда !pip install Faker Пишем код с использованием Faker: from faker import Faker faker = Faker() print(f'name: {faker.name()}') # name: Arthur Patton print(f'address: {faker.address()}') # address: 0638 Larsen Way, Tylermouth, CA 48344 print(f'text: {faker.sentence()}') # text: While per budget up technology design.<p>Теперь объединим две библиотеки, чтобы сгенерировать простой JSON-объект:</p>
56
from pydantic import BaseModel, Field from faker import Faker from typing import List # Инициализация Faker faker = Faker() # Функции для генерации данных с помощью Faker def fake_name(): return faker.name() def fake_age(): return faker.random_int(min=18, max=25) def fake_grades(): return [faker.random_int(min=60, max=100) for _ in range(5)] # Определение модели данных с использованием Pydantic class Student(BaseModel): name: str = Field(default_factory=fake_name) age: int = Field(default_factory=fake_age) grades: List[int] = Field(default_factory=fake_grades) # Создание экземпляра модели Student с автоматической генерацией данных и их валидация try: student = Student() print(student) except ValueError as e: print(e) # Конвертация объекта Pydantic в JSON student_json = student.model_dump() print(student_json) >>> {'name': 'Maria Riddle', 'age': 23, 'grades': [81, 87, 74, 92, 92]}<h3><strong>Дополнительно</strong></h3>
56
from pydantic import BaseModel, Field from faker import Faker from typing import List # Инициализация Faker faker = Faker() # Функции для генерации данных с помощью Faker def fake_name(): return faker.name() def fake_age(): return faker.random_int(min=18, max=25) def fake_grades(): return [faker.random_int(min=60, max=100) for _ in range(5)] # Определение модели данных с использованием Pydantic class Student(BaseModel): name: str = Field(default_factory=fake_name) age: int = Field(default_factory=fake_age) grades: List[int] = Field(default_factory=fake_grades) # Создание экземпляра модели Student с автоматической генерацией данных и их валидация try: student = Student() print(student) except ValueError as e: print(e) # Конвертация объекта Pydantic в JSON student_json = student.model_dump() print(student_json) >>> {'name': 'Maria Riddle', 'age': 23, 'grades': [81, 87, 74, 92, 92]}<h3><strong>Дополнительно</strong></h3>
57
<ul><li>В качестве функции-аргумента для default_factory нужно использовать функцию, не принимающую аргументы. Если аргументы всё-таки нужно передать, можно воспользоваться lambda-функцией. Например: Field(default_factory=lambda: faker.random_int(min=60, max=100))</li>
57
<ul><li>В качестве функции-аргумента для default_factory нужно использовать функцию, не принимающую аргументы. Если аргументы всё-таки нужно передать, можно воспользоваться lambda-функцией. Например: Field(default_factory=lambda: faker.random_int(min=60, max=100))</li>
58
<li>Датакласс можно превратить в словарь с помощью функции asdict. В модели Pydantic для этого используется метод model_dump()</li>
58
<li>Датакласс можно превратить в словарь с помощью функции asdict. В модели Pydantic для этого используется метод model_dump()</li>
59
<li>Faker и Pydantic не входят в стандартный пакет Python</li>
59
<li>Faker и Pydantic не входят в стандартный пакет Python</li>
60
</ul><p><strong>Больше о полезных библиотеках для автоматизации тестирования - на курсе</strong><a>Python QA Engineer</a></p>
60
</ul><p><strong>Больше о полезных библиотеках для автоматизации тестирования - на курсе</strong><a>Python QA Engineer</a></p>
61
61