Учебное пособие по Pytest для начинающих: фикстуры, параметризация и реальные примеры

  1. Главная
  2. Блог
  3. Автоматизация тестирования

Автоматизация тестирования

Учебное пособие по Pytest для начинающих: Фикстуры, параметризация и реальные примеры

Pytest позволяет писать тесты Python с простыми функциями и простыми утверждениями. Шаг за шагом создайте небольшой набор тестов, прочитайте реальные результаты ошибок и изучите функции, которые вы будете использовать каждый день.

10 мин чтения
Учебник по Pytest для начинающих: фикстуры, параметризация и реальные примеры

Главное

  • Pytest находит функции с именем test_* и проверяет их с помощью простых операторов assert.
  • Фикстуры обеспечивают возможность повторного использования настройки и очистки, для чего требуется просто назвать их в качестве аргументов.
  • @pytest.mark.parametrize запускает один тест со многими входными данными.
  • Поместите общие приборы в conftest.py, и вам не нужно их импортировать.

Если вы избегали написания тестов, потому что это кажется рутинной работой, это руководство по pytest должно изменить ваше мнение. Pytest устраняет большую часть церемоний: нет классов для наследования и специальных методов утверждения, которые нужно запомнить. Тест может состоять всего из двух строк.

Мы построим небольшую тележку для покупок и протестируем ее шаг за шагом. Мы запустили все на Python 3.13 с помощью pytest 9.2, и показанный результат является реальным, хотя мы сократили пути к файлам и детали синхронизации, которые могут отличаться на вашем компьютере.

Почему pytest?

Python поставляется с unittest, который работает хорошо, но обычно более удобным выбором является pytest. Вот одна и та же проверка в каждом:

Задача юниттест pytest
Проверить равенство self.assertEqual(a, b) утверждать а == б
Проверить исключение self.assertRaises(...) pytest.raises(...)
Структура теста Класс, который наследуется от TestCase Простая функция
Настройка и очистка setUp и tearDown методы Многоразовые приспособления
Множество входов subTest петли параметризовать

Pytest также может запускать существующие тесты unittest, поэтому вы можете переключаться постепенно. Он также имеет большую экосистему плагинов, включая pytest-cov для покрытия и pytest-xdist для параллельных запусков.

Установить pytest

Сначала создайте виртуальную среду, как описано в нашем руководстве по виртуальной среде Python, а затем установите ее:

pip install pytest
pytest --version

# pytest 9.2.0

Создайте папку проекта, содержащую два файла: cart.py и test_cart.py. Pytest находит тесты автоматически по следующим правилам именования: файлы с именем test_*.py или *_test.py, функции, начинающиеся с test, и классы, начинающиеся с Test. Если тест не принимается, в первую очередь нужно проверить несоответствие имен.

Код для тестирования

# cart.py
class Cart:
    def __init__(self):
        self.items = []

    def add(self, name, price, qty=1):
        if qty < 1:
            raise ValueError("qty must be at least 1")
        self.items.append((name, price, qty))

    def total(self, discount=0):
        subtotal = sum(price * qty for _, price, qty in self.items)
        return round(subtotal * (1 - discount / 100), 2)

Ваши первые тесты

# test_cart.py
from cart import Cart

def test_empty_cart_is_free():
    assert Cart().total() == 0

Это полноценное испытание. Запустите pytest из папки проекта, и он сообщит об одном пройденном тесте. Если вы получите сообщение об ошибке импорта, запустите его как python -m pytest, при этом текущая папка будет добавлена ​​в путь импорта.

Сбои чтения

Именно здесь pytest действительно проявляет себя. Вот тест с заведомо неправильным ожидаемым значением:

def test_wrong_total():
    c = Cart()
    c.add("Keyboard", 1500)
    assert c.total() == 1400

И вот что он напечатал, когда мы его запустили:

    def test_wrong_total():
        c = Cart()
        c.add("Keyboard", 1500)
>       assert c.total() == 1400
E       assert 1500.0 == 1400
E        +  where 1500.0 = total()

FAILED fail_example.py::test_wrong_total - assert 1500.0 == 1400
============================== 1 failed in 0.12s ==============================

> обозначает линию сбоя, а строки E показывают фактические значения. Вам не нужно было добавлять собственное сообщение, поскольку pytest переписывает операторы assert, чтобы они могли сообщать о том, что они сравнивали. То же самое он делает со списками и словарями, точно указывая, какие элементы отличаются.

Исключения тестирования

Обработка ошибок — это тоже поведение, и оно заслуживает тестов. pytest.raises проходит, только если блок вызывает ожидаемое исключение:

import pytest

def test_rejects_zero_qty():
    with pytest.raises(ValueError, match="at least 1"):
        Cart().add("Pen", 10, qty=0)

Необязательный аргумент match проверяет сообщение с использованием регулярного выражения, поэтому другой аргумент ValueError не пройдет случайно. Чтобы узнать, как вызывать и обрабатывать подобные ошибки, прочитайте наше руководство по Обработке исключений Python.

Светильники: многоразовая установка

Для большинства тестов необходимо сначала что-то подготовить. фикстура — это функция, которая ее предоставляет. Украсьте его @pytest.fixture, и любой тест, который называет его аргументом, получит результат:

@pytest.fixture
def cart():
    c = Cart()
    c.add("Keyboard", 1500)
    c.add("Mouse", 500, qty=2)
    return c

def test_total(cart):
    assert cart.total() == 2500

По умолчанию каждый тест получает новую корзину, поэтому тесты не могут влиять друг на друга. Pytest сопоставляет имя аргумента с именем прибора, и вы никогда не вызываете его самостоятельно. @pytest.fixture — это декоратор, который мы объясним в Описание декораторов Python.

Очистка с выходом

Используйте yield вместо return, если вам нужно будет потом почистить. Код после yield запускается после завершения теста, даже если он не пройден:

@pytest.fixture
def temp_db():
    print("\nopen db")
    yield {"users": []}
    print("close db")

def test_db(temp_db):
    assert temp_db["users"] == []

Запуск с помощью -s для отображения распечатанных результатов подтвердил, что ордер открыт, проверьте, затем закройте.

Область действия фикстуры и conftest.py

По умолчанию прибор запускается один раз за тест. Для дорогостоящей установки, например базы данных или браузера, измените срок службы с помощью scope:

Область применения Создается один раз в
function (по умолчанию) Тест
класс Тестовый класс
модуль Файл
пакет Пакет
сессия Весь тестовый прогон

Поместите фикстуры, используемые несколькими файлами, в файл с именем conftest.py. Pytest загружает его автоматически, поэтому тесты могут использовать его фикстуры без импорта. Однако будьте осторожны с общими областями, поскольку изменения, внесенные в ходе одного теста, могут попасть в следующий.

Параметризация: один тест, много входных данных

Вместо того чтобы копировать тест для каждого значения, перечислите случаи:

@pytest.mark.parametrize("discount, expected", [
    (0, 2500),
    (10, 2250),
    (100, 0),
])
def test_discount(cart, discount, expected):
    assert cart.total(discount) == expected

Каждая строка становится отдельным тестом, и вы можете увидеть это в подробном выводе при запуске всего файла:

test_cart.py::test_total PASSED                        [ 16%]
test_cart.py::test_discount[0-2500] PASSED             [ 33%]
test_cart.py::test_discount[10-2250] PASSED            [ 50%]
test_cart.py::test_discount[100-0] PASSED              [ 66%]
test_cart.py::test_rejects_zero_qty PASSED             [ 83%]
test_cart.py::test_empty_cart_is_free PASSED           [100%]

============================== 6 passed in 0.05s ==============================

Если одна строка выходит из строя, остальные продолжают работать, и имя точно указывает, какие значения вызвали проблему. Обратите внимание, что мы объединили параметризацию с приспособлением cart. Чтобы выбрать значения, которые могут обнаружить ошибки, используйте анализ граничных значений.

Совет. Если ваши параметры длинные или неясные, введите ids=["none", "ten", "full"], чтобы дать каждому случаю читаемое имя в отчете.

Полезная встроенная фурнитура.

Pytest включает в себя несколько готовых приспособлений. Эти два особенно удобны, и оба прошли в нашем прогоне:

def test_write_report(tmp_path):
    report = tmp_path / "report.txt"
    report.write_text("passed")
    assert report.read_text() == "passed"

def read_mode():
    return os.environ.get("APP_MODE", "dev")

def test_mode(monkeypatch):
    monkeypatch.setenv("APP_MODE", "staging")
    assert read_mode() == "staging"

tmp_path предоставляет каждому тесту уникальную временную папку, поэтому тесты никогда не затрагивают реальные файлы. monkeypatch изменяет переменные или атрибуты среды и отменяет изменения после завершения теста. Еще один полезный вариант — capsys, который записывает распечатанные данные, чтобы вы могли их проверить.

Маркеры: пропустить и xfail

Маркеры добавляют метки и поведение к тестам:

@pytest.mark.skip(reason="payment sandbox is down")
def test_payment():
    assert False

@pytest.mark.xfail(reason="floating point")
def test_rounding():
    assert 0.1 + 0.2 == 0.3

skip вообще не запускает тест. xfail запускает его, но ожидает сбоя, поэтому известная проблема не нарушит вашу сборку. С учетом других дополнительных тестов в том же файле наш прогон суммировался как 3 passed, 1 skipped, 1 xfailed. Кстати, этот тест на округление действительно терпит неудачу: в арифметике с плавающей запятой 0,1 + 0,2 не совсем равно 0,3. Используйте pytest.approx(0.3) при сравнении десятичных дробей.

Вы также можете создать свои собственные маркеры, например @pytest.mark.slow, и запускать только те, у которых есть pytest -m slow, или исключить их с помощью -m "not slow". Зарегистрируйте собственные маркеры в файле конфигурации, чтобы избежать предупреждений.

Полезные флаги командной строки

Команда Что он делает
pytest -v Показать название каждого теста
pytest -q Показать более краткое описание
pytest -x Остановитесь при первой неудаче
pytest -k скидка Запуск тестов, имена которых соответствуют слову
pytest -s Показать print вывод
pytest --lf Повторно запускать только последние неудачи
pytest --pdb Открыть отладчик при сбое
pytest test_cart.py::test_total Запустите один конкретный тест

Запуск pytest в CI

Тесты наиболее ценны, когда они запускаются автоматически при каждом изменении. Минимальное задание GitHub Actions выглядит так:

steps:
  - uses: actions/checkout@v4
  - uses: actions/setup-python@v5
    with:
      python-version: "3.13"
  - run: pip install -r requirements.txt
  - run: python -m pytest

Pytest завершает работу с ненулевым кодом, когда тесты терпят неудачу, что приводит к остановке конвейера. Мы не выполняли этот файл рабочего процесса, поэтому адаптируйте его к своему проекту. Подробности объясняется в нашем руководстве по GitHub Actions CI/CD. Pytest также хорошо работает для браузерных тестов, как показывают наши руководство по Selenium Python и руководство по объектной модели страницы.

Итоги

Теперь у вас есть все, что нужно для большинства наборов тестов Python: простые утверждения, приспособления для настройки, параметризация для вариантов и несколько флагов для скорости. Начните с малого. Выберите одну функцию, в которой вы недавно исправили ошибку, и сначала напишите тест для этой ошибки. Если вы не знаете, что тестировать на каждом уровне, прочитайте о модульном и интеграционном тестировании.

Часто задаваемые вопросы

Для чего используется pytest?

Pytest — это среда тестирования Python. Он используется для модульных, интеграционных и API-тестов, а также хорошо работает с такими браузерными инструментами, как Selenium и Playwright.

Pytest лучше, чем unittest?

Многие команды предпочитают его из-за более простого синтаксиса, настроек и более четких ошибок. unittest не требует установки, а pytest также может запускать существующие тесты unittest.

Что такое приспособление в pytest?

Фикстура — это функция, которая подготавливает что-то, необходимое для теста, например данные или соединение. Тесты получают его, называя его в качестве аргумента.

Что такое conftest.py?

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

Почему pytest не находит мои тесты?

Обычно это проблема именования. Файлы должны называться test_*.py или *_test.py, а функции должны начинаться с test. Также проверьте, что вы запустили его из правильной папки.

Продолжайте учиться

Работайте с Stack Quora

Нужна помощь с тестированием, WordPress или SEO?

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

Продолжайте читать

Больше руководств по тестирование, искусственный интеллект и современные разработки

Понравилась эта статья? Выберите тему и сразу приступайте к нашим новейшим руководствам.

Искусственный интеллект

Объяснение галлюцинаций искусственного интеллекта: почему языковые модели все выдумывают и как их уменьшить

Галлюцинации ИИ объяснили: что это такое, почему языковые модели их создают, распространенные типы, как уменьшить их с помощью заземления и подсказо…

Читать статью →
DevOps

Объяснение переменных среды: файлы .env, секреты и правильно выполненная конфигурация

Переменные среды объясняются на примерах Python, которые мы запускали: их чтение и установка, почему каждое значение является строкой, файлы .env, н…

Читать статью →
Разработка ПО

Объяснение ограничения скорости API: алгоритмы, заголовки и обработка ошибок 429

Ограничение скорости API объясняется с помощью проведенного нами моделирования: сегмент токенов, фиксированное окно, скользящее окно, 429 ответов, з…

Читать статью →
Автоматизация тестирования

Издевательство в Python: unittest.mock, патч и ошибки, из-за которых тесты лгут

Издевательство на Python с помощью unittest.mock, протестировано: Mock и return_value, Side_effect, исправление использования имени, спецификация и …

Читать статью →
Тестирование ПО

Объяснение покрытия кода: покрытие линий или ветвей и что на самом деле означает 100%

Покрытие кода объяснено с помощью реального запуска покрытия.py: покрытие строк, ветвей и условий, чтение отчета, почему 100%-ное покрытие все еще м…

Читать статью →
Базы данных и SQL

DELETE, TRUNCATE и DROP в SQL: различия, откат и когда использовать каждый из них

Объяснение DELETE, TRUNCATE и DROP на примере протестированного SQL: что каждый из них удаляет, откат, триггеры, сброс идентификаторов, скорость и ч…

Читать статью →
Базы данных и SQL

Объяснение представлений SQL: создавайте, используйте и избегайте ловушек, с примерами

Представления SQL, объясненные с помощью запросов, которые мы выполняли: создание представления, результаты в реальном времени, скрытие столбцов, пр…

Читать статью →
Разработка ПО

Интерфейс TypeScript и тип: реальные различия, протестированные с помощью компилятора

Интерфейс TypeScript против типа, проверенный реальным компилятором: что могут делать оба, что может делать только один, слияние объявлений, расшире…

Читать статью →
Разработка ПО

Объяснение Python *args и **kwargs: гибкие функции с понятными примерами

Python *args и **kwargs, объясненные с помощью кода, который мы запускали: упаковка и распаковка, порядок параметров, аргументы только по ключевым с…

Читать статью →
Разработка ПО

Лямбда-функции Python: синтаксис, реальное использование и когда их не следует использовать

Лямбда-функции Python, объясненные с помощью кода, который мы запускали: синтаксис, сортировка с помощью ключа, карты и фильтра, замыкания, ловушка …

Читать статью →
Искусственный интеллект

Что такое ИИ-агенты? Как они работают: можно запустить простой цикл агента

Что такое агенты ИИ? Простое руководство по циклу агента, инструментам, памяти и ограничениям, с небольшим циклом Python, который мы запустили, реал…

Читать статью →
DevOps

Мониторинг и наблюдаемость: реальная разница с журналами, метриками и трассировками

Объяснение мониторинга и наблюдаемости: известные и неизвестные сбои, журналы, метрики и трассировки, пошаговое руководство по инцидентам при оформл…

Читать статью →
DevOps

Docker Volumes против Bind Mounts: правильное сохранение данных контейнера

Объяснение томов Docker и монтирования привязки: почему исчезают данные контейнера, именованные тома, монтирование привязки, tmpfs, примеры создания…

Читать статью →
Автоматизация тестирования

TDD против BDD: ключевые различия, одна функция, созданная для обоих способов, и когда использовать каждый

TDD и BDD объясняются с помощью одной функции скидки, созданной в обоих направлениях: красно-зеленый рефакторинг с кодом, который мы запускали, сцен…

Читать статью →
Тестирование ПО

Пользовательское приемочное тестирование (UAT): процесс, контрольный список и реальные примеры

Приемочное тестирование пользователей объяснило: кто его проводит, чем оно отличается от контроля качества, семиэтапный процесс, шаблон тестового сц…

Читать статью →
Базы данных и SQL

Объяснение значений NULL в SQL: IS NULL, COALESCE, NULLIF и ловушки, которых следует избегать

Значения SQL NULL объяснены с помощью запросов, которые мы выполнили: трехзначная логика, IS NULL, COALESCE, NULLIF, как агрегаты, соединения и сорт…

Читать статью →
Базы данных и SQL

Оператор SQL CASE WHEN: синтаксис, реальные примеры и распространенные ошибки

SQL CASE WHEN объяснен с помощью запросов, которые мы выполняли: простые формы и формы для поиска, порядок условий, повороты с помощью SUM, трюки CO…

Читать статью →
Разработка ПО

Что такое JWT? Веб-токены JSON, объясненные на рабочем примере

Что такое JWT? Объяснение JSON Web Tokens: три части: токен, созданный и измененный в коде, который мы запускали, JWT и сеансы, хранилище, токены об…

Читать статью →
Разработка ПО

Объяснение цикла событий JavaScript: стек вызовов, микрозадачи и таймеры с примерами

Цикл событий JavaScript объясняется с помощью кода, который мы запускали: стек вызовов, очереди задач и микрозадач, почему setTimeout 0 не является …

Читать статью →
Разработка ПО

Генераторы Python и объяснение доходности: экономьте память с помощью реальных примеров

Генераторы Python и доходность, объясненные с помощью кода, который мы запускали: как они приостанавливаются и возобновляются, измеряют экономию пам…

Читать статью →
Искусственный интеллект

Что такое вложения? Простое объяснение векторов и косинусного сходства

Что такое вложения? Простое руководство по векторам, косинусному подобию и семантическому поиску с небольшим примером, который мы использовали, общи…

Читать статью →
DevOps

Сине-зеленое и канареечное развертывание: различия, компромиссы и как выбрать

Объяснение сине-зеленого и канареечного развертывания: как каждый из них работает, стоимость, риски и откат, стабильное группирование пользователей,…

Читать статью →
Автоматизация тестирования

Ненадежные тесты: что их вызывает и как их исправить навсегда

Ненадежные тесты объясняются на демонстрациях, которые мы запускали: основные причины, способы подтверждения и диагностики, правильные исправления в…

Читать статью →
Тестирование ПО

Нагрузочное тестирование и стресс-тестирование: различия, метрики и примеры k6

Объяснение нагрузочного и стресс-тестирования: что доказывает каждое из них, тесты на всплески и выдержки, важные метрики, почему средние значения в…

Читать статью →
Тестирование ПО

Тестовый пример и тестовый сценарий: ключевые различия, примеры и когда использовать каждый

Объяснение тестового случая и тестового сценария: четкие определения, параллельная таблица, одна функция сброса пароля, взятая из сценариев в случаи…

Читать статью →
Базы данных и SQL

Оптимизация SQL-запросов: чтение планов выполнения и исправление медленных запросов с указанием времени

Оптимизация SQL-запросов проверена на миллионе строк: читайте планы выполнения, добавляйте правильные индексы, исправляйте неразмещаемые фильтры, ис…

Читать статью →
Базы данных и SQL

SQL UNION против UNION ALL: различия, примеры и проверка производительности

SQL UNION и UNION ALL объяснены с помощью запросов, которые мы выполнили: дубликаты, правила, которым следуют оба, реальная ошибка данных, измеренна…

Читать статью →
Разработка ПО

Учебное пособие по API JavaScript Fetch: GET, POST, обработка ошибок и тайм-ауты

Учебное пособие по API JavaScript Fetch, протестированное на локальном сервере: GET и POST, почему не выдается ошибка 404, многоразовый помощник, ст…

Читать статью →
Разработка ПО

Обработка файлов Python: чтение, запись, CSV, JSON и pathlib с примерами

Обработка файлов Python объясняется с помощью кода, который мы запускали: открытые режимы, чтение больших файлов, CSV, JSON, pathlib, двоичные файлы…

Читать статью →
Разработка ПО

Классы и объекты Python: учебник ООП с реальными примерами

Классы и объекты Python, объясненные с помощью кода, который мы запускали: __init__, методы, атрибуты класса и экземпляра, наследование, свойства, м…

Читать статью →
Искусственный интеллект

Что такое большая языковая модель? Как работают LLM, объяснено без шумихи

Что такое большая языковая модель? LLM объясняется простым языком: токены, встраивания, внимание, обучение, температурные и контекстные окна, крошеч…

Читать статью →
DevOps

Команды Linux для начинающих: основное руководство по терминалу с примерами

Команды Linux для начинающих, сгруппированные по задачам: навигация, файлы, просмотр журналов, grep, каналы, разрешения, процессы и архивы, с практи…

Читать статью →
Автоматизация тестирования

Selenium vs Playwright: ключевые различия, сравнение кода и что выбрать

Сравнение Selenium и Playwright: архитектура, ожидание, поддержка браузера и языка, отладка, одинаковый тест в обоих инструментах, советы по миграци…

Читать статью →
Тестирование ПО

Разделение эквивалентности: метод проектирования тестов, объясненный на рабочих примерах

Объяснение эквивалентного разделения: как найти действительные и недействительные разделы, рабочие примеры для возрастов, паролей и купонов, проведе…

Читать статью →
Тестирование ПО

Серьезность и приоритет в тестировании программного обеспечения: различия, матрица и реальные примеры

Объяснение серьезности и приоритета при тестировании программного обеспечения: четкие определения, четырехсторонняя матрица с примерами, шкалы уровн…

Читать статью →
Базы данных и SQL

Учебное пособие по подзапросам SQL: типы, коррелирующие подзапросы и EXISTS с примерами

Руководство по подзапросам SQL с выполненными нами запросами: скалярные подзапросы, IN, FROM и SELECT, коррелированные подзапросы, EXISTS, ловушка N…

Читать статью →
Базы данных и SQL

Объяснение транзакций SQL и ACID: COMMIT, ROLLBACK и уровни изоляции

Транзакции SQL и ACID, объясненные с помощью банковского перевода, который мы выполнили: COMMIT, ROLLBACK, точки сохранения, блокировки, уровни изол…

Читать статью →
Разработка ПО

Git Commands Cheat Sheet: The Commands You Actually Use, With Examples

Шпаргалка по командам Git, сгруппированная по задачам: настройка, промежуточный этап, ветки, удаленные устройства, тайник, история и исправление оши…

Читать статью →
Разработка ПО

Объяснение промисов в JavaScript: then, catch, Promise.all и распространенные ошибки

Обещания JavaScript, объясненные с помощью кода, который мы запускали: состояния, цепочки then и catch, обработка ошибок, Promise.all, allSettled, R…

Читать статью →
Разработка ПО

Учебное пособие по словарю Python: методы, примеры и общие шаблоны

Учебное пособие по словарю Python с кодом, который мы выполнили: создание, чтение и обновление словарей, ключевые методы, слияние, понимание, шаблон…

Читать статью →
Искусственный интеллект

Что такое РАГ? Генерация с расширенным поиском, объясненная на рабочем примере

Что такое РАГ? Retrieval-augmented generation explained step by step: indexing, chunking, embeddings, retrieval, a small working Python example, eva…

Читать статью →
DevOps

Учебное пособие по Terraform для начинающих: инфраструктура как код от первого файла до модулей

Учебное пособие по Terraform для начинающих: начните без облачной учетной записи, изучите инициализацию, планирование и применение, затем переменные…

Читать статью →
DevOps

Docker и Kubernetes: ключевые различия, как они работают вместе и что вам нужно

Объяснение Docker и Kubernetes: что делает каждый из них, одно и то же приложение работает с обоими, сравнение Docker Compose и Swarm, изменение doc…

Читать статью →
Автоматизация тестирования

Учебное пособие по Pytest для начинающих: фикстуры, параметризация и реальные примеры

Учебное пособие по pytest для начинающих с тестами, которые мы запускали на pytest 9.2: утверждения, фикстуры, параметризация, conftest, маркеры, tm…

Читать статью →
Тестирование ПО

Жизненный цикл тестирования программного обеспечения (STLC): 6 этапов, критерии входа и выхода, пример

Объясняется жизненный цикл тестирования программного обеспечения: шесть этапов STLC с критериями входа и выхода, результаты, пример проработанной фу…

Читать статью →
Разработка ПО

Git merge vs rebase: отличия, примеры и когда что использовать

Git merge vs rebase с реальным выводом log, сравнительной таблицей, золотым правилом rebase и безопасным рабочим процессом для команды.

Читать статью →
Разработка ПО

Генераторы списков в Python: синтаксис, примеры и когда их избегать

Генераторы списков в Python: синтаксис, фильтры, if-else, вложенные циклы, измеренное время и случаи, когда обычный цикл for лучше.

Читать статью →
Базы данных и SQL

SQL JOIN: объяснение с примерами (Inner, Left, Right, Full)

Разберите SQL JOIN шаг за шагом на примерах таблиц и запросов: INNER, LEFT, RIGHT, FULL, CROSS и SELF, а также частые ошибки и советы по производите…

Читать статью →