<!DOCTYPE html>
<html class="h-100" data-bs-theme="light" data-mantine-color-scheme="light" lang="ru" prefix="og: https://ogp.me/ns#">
<head>
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<link crossorigin="true" href="https://cdn.hexlet.io" rel="preconnect">
<link href="https://mc.yandex.ru" rel="preconnect">
<meta content="aa2vrdtq64dub8knuf83lwywit311w" name="facebook-domain-verification">
<link href="/favicon.ico" rel="icon" sizes="any">
<link href="/favicon.svg" rel="icon" type="image/svg+xml">
<link href="/apple-touch-icon.png" rel="apple-touch-icon">
<link href="/manifest.webmanifest" rel="manifest">
<script>
//<![CDATA[
window.gon={};gon.ym_counter="25559621";gon.is_bot=true;gon.applications={};gon.current_user={"id":null,"last_viewed_notification_id":null,"email":null,"state":null,"first_name":"","last_name":"","created_at":"2026-02-26 19:52:44 UTC","current_program":null,"current_team":null,"full_name":"","guest":true,"can_use_paid_features":false,"is_hexlet_employee":false,"sanitized_phone_number":"","can_subscribe":true,"can_renew_education":false};gon.token="envWdqSbx2mOjFtgsr30SV0dDXIp5oGBH2NWj5-f3DGVqh1BVuVqCTjPf_i-sgQ-nRQg2CHRfyOig8zbzZg7Xw";gon.locale="ru";gon.language="ru";gon.theme="light";gon.rails_env="production";gon.mobile=false;gon.google={"analytics_key":"UA-1360700-51","optimize_key":"GTM-5QDVFPF"};gon.captcha={"google_v3_site_key":"6LenGbgZAAAAAM7HbrDbn5JlizCSzPcS767c9vaY","yandex_site_key":"ysc1_Vyob5ZPPUdPBsu0ykt8bVFdzsfpoVjQChLGl2b4g19647a89","verification_failed":null};gon.social_signin=false;gon.typoreporter_google_form_id="1FAIpQLSeibfGq-KvWQ2Fyru-zkFFRVTLBuzXAHAoEyN1p49FtDmNoNA";
//]]>
</script>
<meta charset="utf-8">
<title>Система тестирования | Этап тестирования</title>
<meta name="description" content="Система тестирования / Этап тестирования: Обсуждаем, что такое уровни тестирования и система тестирования, из чего она состоит и какие варианты представления бывают">
<link rel="canonical" href="https://ru.hexlet.io/courses/testing-phase/lessons/testing-system/theory_unit">
<meta name="robots" content="noarchive">
<meta property="og:title" content="Система тестирования">
<meta property="og:title" content="Этап тестирования">
<meta property="og:description" content="Система тестирования / Этап тестирования: Обсуждаем, что такое уровни тестирования и система тестирования, из чего она состоит и какие варианты представления бывают">
<meta property="og:url" content="https://ru.hexlet.io/courses/testing-phase/lessons/testing-system/theory_unit">
<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="2CkPMxC8Pufh6fN0bz-FogyNckKU_-AsI3p1y5u4-4g3-MQE4sKTh1eq1-xjMHXVzIRf6JzIHo6emu-fyb8c5g" />
<script src="/vite/assets/inertia-DfXos102.js" crossorigin="anonymous" type="module"></script><link rel="modulepreload" href="/vite/assets/chunk-DsPFFUou.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/preload-helper-BJ4cLWpC.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/init-BrRXra1y.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/ahoy-DrlRQ-1D.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/analytics-cb8xch9l.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/ErrorFallbackBlock-naDSYSy9.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Surface-DL2bpZA-.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/gon-D3e4yh1x.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/mantine-CGMYrt2Y.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/utils-DRqSHbQE.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/routes-CCH8ilKF.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/extends-C-EagtpE.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/inheritsLoose-BBd-DCVI.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/objectWithoutPropertiesLoose-DRHXDhjp.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/index.esm-DAqKOkZ0.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Button-CGPUux8l.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/CloseButton-D1euiPao.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Group-BX48WcuU.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Loader-BQEY8g6v.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Modal-Cy3HByv7.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/OptionalPortal-1Hza5P2w.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Stack-CtjJzfw4.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Textarea-Ck64llAy.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Box-B5-OOzBf.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/DirectionProvider-Dc9zdUke.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/events-DJQOhap0.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/use-reduced-motion-D2owz4wa.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/use-disclosure-zKtK5W1r.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/use-hotkeys-Cnc_Rwkb.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/random-id-DOQyszCZ.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/notifications.store-C-3AFSMn.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/exports-C_MrNx_T.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/axios-BEvgo0ym.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/dayjs.min-BkKovM-s.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/i18next-BlSq9s7B.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/client-U9M77rxp.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-dom-DaLxUz_h.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/useTranslation-Bx1Cdrkz.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/compiler-runtime-6XxiPFnt.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/jsx-runtime-CwjcCKJi.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-CkL4ZRHB.js" as="script" crossorigin="anonymous">
<link rel="stylesheet" href="/vite/assets/application-BqhCP46M.js" />
<script src="/vite/assets/application-Df9RExpe.js" crossorigin="anonymous" type="module"></script><link rel="modulepreload" href="/vite/assets/chunk-DsPFFUou.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/autocomplete-VMNbxKGl.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/routes-CCH8ilKF.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/createPopper-C3aM9r1M.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/js.cookie-D1-O8zkX.js" as="script" crossorigin="anonymous"><link rel="stylesheet" href="/vite/assets/application-C8HjmMaq.css" media="screen" />
<script>
window.ym = function(){(ym.a=ym.a||[]).push(arguments)};
window.addEventListener('load', function() {
setTimeout(function() {
ym.l = 1*new Date();
ym(window.gon.ym_counter, "init", {
clickmap: true,
trackLinks: true,
accurateTrackBounce: true,
webvisor: true
});
// Загружаем скрипт
var k = document.createElement('script');
k.async = 1;
k.src = 'https://mc.yandex.ru/metrika/tag.js';
document.head.appendChild(k);
ym(window.gon.ym_counter, 'getClientID', function(clientID) {
window.ymClientId = clientID;
});
}, 1500);
});
</script>
<!-- Google Tag Manager - deferred -->
<script>
// dataLayer stub сразу — пуши работают до загрузки скрипта
window.dataLayer = window.dataLayer || [];
// Сам скрипт — отложенно после load
window.addEventListener('load', function() {
setTimeout(function() {
dataLayer.push({'gtm.start': new Date().getTime(), event: 'gtm.js'});
var j = document.createElement('script');
j.async = true;
j.src = 'https://www.googletagmanager.com/gtm.js?id=GTM-WK88TH';
document.head.appendChild(j);
}, 1500);
});
</script>
<!-- End Google Tag Manager -->
</head>
<body>
<noscript>
<div>
<img alt="" src="https://mc.yandex.ru/watch/25559621" style="position:absolute; left:-9999px;">
</div>
</noscript>
<header class="sticky-top bg-body">
<nav class="navbar navbar-expand-lg">
<div class="container-xxl">
<a class="navbar-brand" href="/"><img alt="Логотип Хекслета" height="24" src="https://ru.hexlet.io/vite/assets/logo_ru_light-BpiEA1LT.svg" width="96">
</a><button aria-controls="collapsable" aria-expanded="false" aria-label="Меню" class="navbar-toggler border-0 mb-0 mt-1" data-bs-target="#collapsable" data-bs-toggle="collapse">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="collapsable">
<ul class="navbar-nav mb-lg-0 mt-lg-1">
<li class="nav-item dropdown">
<button aria-haspopup class="btn nav-link" data-bs-toggle="dropdown" type="button">
Все курсы
<span class="bi bi-chevron-down align-middle ms-1"></span>
</button>
<ul class="dropdown-menu">
<li>
<a class="dropdown-item d-flex py-2" href="/courses"><div class="fw-bold me-auto">Все что есть</div>
<div class="text-muted">117</div>
</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li class="dropdown-item">
<b>Популярные категории</b>
</li>
<li>
<a class="dropdown-item py-2" href="/courses_devops">Курсы по DevOps
</a></li>
<li>
<a class="dropdown-item py-2" href="/courses_data_analytics">Курсы по аналитике данных
</a></li>
<li>
<a class="dropdown-item py-2" href="/courses_programming">Курсы по программированию
</a></li>
<li>
<a class="dropdown-item py-2" href="/courses_testing">Курсы по тестированию
</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li class="dropdown-item">
<b>Популярные курсы</b>
</li>
<li>
<a class="dropdown-item py-2" href="/programs/devops-engineer-from-scratch">DevOps-инженер с нуля
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/go">Go-разработчик
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/java">Java-разработчик
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/python">Python-разработчик
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/qa-auto-engineer-java">Автоматизатор тестирования на Java
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/data-analytics">Аналитик данных
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/frontend">Фронтенд-разработчик
</a></li>
</ul>
</li>
<li class="nav-item dropdown">
<button aria-haspopup class="btn nav-link" data-bs-toggle="dropdown" type="button">
О Хекслете
<span class="bi bi-chevron-down align-middle"></span>
</button>
<ul class="dropdown-menu bg-body">
<li>
<a class="dropdown-item py-2" href="/pages/about">О нас
</a></li>
<li>
<a class="dropdown-item py-2" href="/blog">Блог
</a></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://special.hexlet.io/hse-research" role="button">Результаты (Исследование)
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://career.hexlet.io" role="button">Хекслет Карьера
</span></li>
<li>
<a class="dropdown-item py-2" href="/testimonials">Отзывы студентов
</a></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://t.me/hexlet_help_bot" role="button">Поддержка (В ТГ)
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://special.hexlet.io/referal-program/?promo_creative=priglasite-druzei&promo_name=referal-program&promo_position=promo_position&promo_start=010724&promo_type=link" role="button">Реферальная программа
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://special.hexlet.io/certificate" role="button">Подарочные сертификаты
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://hh.ru/employer/4307094" role="button">Вакансии
</span></li>
<li>
<span class="dropdown-item d-flex external-link" rel="noopener noreferrer nofollow" data-href="https://b2b.hexlet.io" data-target="_blank" role="button">Компаниям
</span></li>
<li>
<span class="dropdown-item d-flex external-link" rel="noopener noreferrer nofollow" data-href="https://hexly.ru/" data-target="_blank" role="button">Колледж
</span></li>
<li>
<span class="dropdown-item d-flex external-link" rel="noopener noreferrer nofollow" data-href="https://hexlyschool.ru/" data-target="_blank" role="button">Частная школа
</span></li>
</ul>
</li>
<li><a class="nav-link" href="/subscription/new">Подписка</a></li>
</ul>
<ul class="navbar-nav flex-lg-row align-items-lg-center gap-2 ms-auto">
<li>
<a class="nav-link" aria-label="Переключить тему" href="/theme/switch?new_theme=dark"><span aria-hidden="true" class="bi bi-moon"></span>
</a></li>
<li>
<span data-target="_self" class="nav-link external-link" data-href="/u/new" role="button"><span>Регистрация</span>
</span></li>
<li>
<span data-target="_self" class="nav-link external-link" data-href="https://ru.hexlet.io/session/new" role="button"><span>Вход</span>
</span></li>
</ul>
</div>
</div>
</nav>
</header>
<div class="x-container-xxxl">
</div>
<main class="mb-6 min-vh-100 h-100">
<link rel="preload" as="image" href="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Mzk1MCwicHVyIjoiYmxvYl9pZCJ9fQ==--4a16fe638654fb8d5ae09d7e8ab8e16ff228214f/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Bug%20fixing-amico.png"/><link rel="preload" as="image" href="/vite/assets/development-BVihs_d5.png"/><div id="app" data-page="{"component":"web/courses/lessons/theory_unit","props":{"errors":{},"locale":"ru","language":"ru","httpsHost":"https://ru.hexlet.io","host":"ru.hexlet.io","colorScheme":"light","auth":{"user":{"id":null,"last_viewed_notification_id":null,"email":null,"state":null,"first_name":"","last_name":"","created_at":"2026-02-26T19:52:44.827Z","current_program":null,"current_team":null,"full_name":"","guest":true,"can_use_paid_features":false,"is_hexlet_employee":false,"sanitized_phone_number":"","can_subscribe":true,"can_renew_education":false}},"cloudflareTurnstileSiteKey":"0x4AAAAAAA15KmeFXzd2H0Xo","vkIdClientId":"51586979","yandexIdClientId":"88d071f1d3384eb4bd1deb37910235c7","formAuthToken":"BTF_Ds6Nmn_FkGmNmBtqQUaLz1wiPCMexrAlJlVxdYjq4LQ5PPM3H3PTTRWUFJo2hoLi9ioL3bx7UL9yB3aS5g","topics":[{"id":86391,"title":"Скажите пожалуйста, уважаемые разработчики...зачем вы изменили(упростили) задание в упражнении и убрали пункт про Postman!Просто, я потратил время на изучение этой платформой, чтоб понять, как правильно выполнить упражнение, точнее прежнюю версию! Можно было не убирать, а добавить вводный урок для понимания этой программой!","plain_title":"Скажите пожалуйста, уважаемые разработчики...зачем вы изменили(упростили) задание в упражнении и убрали пункт про Postman!Просто, я потратил время на изучение этой платформой, чтоб понять, как правильно выполнить упражнение, точнее прежнюю версию! Можно было не убирать, а добавить вводный урок для понимания этой программой! ","creator":{"public_name":"Фаррух Шадманов","id":590245,"is_tutor":false},"comments":[{"creator":{"public_name":"Фаррух Шадманов","id":590245,"is_tutor":false},"id":174256,"body":"**Nikolai Gagarinov**, спасибо что ответили)","topic_id":86391},{"creator":{"public_name":"Nikolai Gagarinov","id":104929,"is_tutor":true},"id":174258,"body":"Добрый день.\n\nЗадание переместили сюда, в курс по HTTP API.\nhttps://ru.hexlet.io/challenges/http_api_postman_exercise","topic_id":86391},{"creator":{"public_name":"Nikolai Gagarinov","id":104929,"is_tutor":true},"id":173733,"body":"Фаррух, добрый день.\n\nМы стараемся создавать уроки таким образом, чтобы они шли последовательно. И если что-то добавляется, то оно объясняется. \n\nПостман вы изучали не зря - он используется тестировщиками и будет у вас в следующем модуле в курсе HTTP API. ","topic_id":86391}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Система тестирования","entity_url":null,"active":true}},{"id":85954,"title":"Привет! Не очень понимаю как нужно протестировать запросы в devtools. Поясню: я копирую запрос \"GET /api/products\", ввожу в консоль, мне выдает ошибку \"ReferenceError: Can't find variable: GET\"\nПробовала вводить без гет, выдает синтаксическую ошибку (что логично). Полазала по по вкладке нетворк, нашла там файлы с этими путями и методами, но понятнее все равно не стало. Почему выдает ошибку? Что я делаю не так?","plain_title":"Привет! Не очень понимаю как нужно протестировать запросы в devtools. Поясню: я копирую запрос \"GET /api/products\", ввожу в консоль, мне выдает ошибку \"ReferenceError: Can't find variable: GET\" Пробовала вводить без гет, выдает синтаксическую ошибку (что логично). Полазала по по вкладке нетворк, нашла там файлы с этими путями и методами, но понятнее все равно не стало. Почему выдает ошибку? Что я делаю не так? ","creator":{"public_name":"Алла Нестерова","id":425285,"is_tutor":false},"comments":[{"creator":{"public_name":"Ivan Gagarinov","id":75907,"is_tutor":true},"id":173049,"body":"**Алла Нестерова**, здравствуйте! Вам не нужно выполнять запросы, за вас это делает приложение. Откройте девтулз, затем выполняйте действия в приложении (попробуйте создать несколько заказов, просмотрите их). В devtools в нетворке будут появляться указанные запросы в зависимости от действия.\n","topic_id":85954}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Система тестирования","entity_url":null,"active":true}},{"id":85578,"title":"> Интеграционное тестирование\nИнтеграционное тестирование (в контексте системы тестирования) предназначено для проверки взаимодействия между модулями.\nПример интеграционного теста – проверка того, что колесо приводится в движение с помощью цепи.\nПример интеграционного теста – проверка того, что API отдаёт общую стоимость заказа (взаимодействие модуля, реализующего интерфейс с модулем, реализующим функцию \nподсчёта).\n\n[Виды API](https://ru.hexlet.io/courses/http-api/lessons/kinds/theory_unit\n)\nБыло бы неплохо для выполнения упражнения прикрепить ссылку на этот урок в теорию. И по [постману](https://ru.hexlet.io/courses/http-api/lessons/postman/theory_unit) тоже, который находится во втором модуле обучения. Порядок какой-то вперемешку. Причём само упражнение отлично от темы. Мне было очень сложно, подробное штудирование в чате группы в Slack ни к чему не привело, нужна хотя бы вводная видеолекция, как мне кажется, а не скриншоты и максимальная лишь в этом помощь куратора. Не все имеют начальные навыки по работе с js. Был огромнейший ступор. Благо, мне было к кому обратиться за помощью из вне. Но столько времени и нервов потратила, оставляя это упражнение на самый конец курса. ","plain_title":"Интеграционное тестирование Интеграционное тестирование (в контексте системы тестирования) предназначено для проверки взаимодействия между модулями. Пример интеграционного теста – проверка того, что колесо приводится в движение с помощью цепи. Пример интеграционного теста – проверка того, что API отдаёт общую стоимость заказа (взаимодействие модуля, реализующего интерфейс с модулем, реализующим функцию подсчёта). Виды API (https://ru.hexlet.io/courses/http-api/lessons/kinds/theory_unit) Было бы неплохо для выполнения упражнения прикрепить ссылку на этот урок в теорию. И по постману (https://ru.hexlet.io/courses/http-api/lessons/postman/theory_unit) тоже, который находится во втором модуле обучения. Порядок какой-то вперемешку. Причём само упражнение отлично от темы. Мне было очень сложно, подробное штудирование в чате группы в Slack ни к чему не привело, нужна хотя бы вводная видеолекция, как мне кажется, а не скриншоты и максимальная лишь в этом помощь куратора. Не все имеют начальные навыки по работе с js. Был огромнейший ступор. Благо, мне было к кому обратиться за помощью из вне. Но столько времени и нервов потратила, оставляя это упражнение на самый конец курса. ","creator":{"public_name":"Anastasia Glazova","id":587471,"is_tutor":false},"comments":[{"creator":{"public_name":"Sergey revyagin","id":530358,"is_tutor":false},"id":172542,"body":"Согласен, не совсем понимаю как проверить некоторый функционал.","topic_id":85578},{"creator":{"public_name":"Nikolai Gagarinov","id":104929,"is_tutor":true},"id":172584,"body":"Анастасия, добрый день.\n\nСпасибо, что поделились обратной связью. Да, Postman изучается позже. Попробуем улучшить описание упражнения\n\nПри возникновении трудностей с упражнениями, пожалуйста, задавайте вопросы наставнику, чтобы он мог вам помочь и передать нам вашу обратную связь по материалам курса.","topic_id":85578}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Система тестирования","entity_url":null,"active":true}},{"id":90396,"title":"Мне кажется, задача проверяется некорректно.\n\nФактически **некорректных методов намного больше**, чем система полагает.\n\n### Ошибки в теле запроса\n### Метод `POST /api/cart`\n**Самая большая ошибка**, в том что по условию задачи, у нас в теле запроса должен быть объект вида:\n`{\"id\":8,\"title\":\"Кефир\",\"description\":\"Кисломолочный продукт\",\"price\":68,\"count\":2}`\n\nА фактически уходит **вложенный** в `product` объект, и тело запроса выглядит так:\n`{\"product\":{\"id\":8,\"title\":\"Кефир\",\"description\":\"Кисломолочный продукт\",\"price\":68,\"count\":2}}`\n\nТакже в теле запроса, по условию задачи, идентификатор это число `\"id\": 8`, \nно фактически уходит строка `\"id\": \"8\"` (внимание на кавычки)\n\n\n### Ошибки в теле ответа\n### Методы `GET /api/cart`, `POST /api/orders`, `GET /api/orders`\nВ задаче в теле ответа идентификатор продукта возвращается как число:\n `\"id\": 8`\n\nФактически, идентификатор продукта возвращается как строка, в кавычках: `\"id\": \"8\"`\n \nВсе это явные ошибки, но система почему-то считает их корректными.","plain_title":"Мне кажется, задача проверяется некорректно. Фактически некорректных методов намного больше, чем система полагает. Ошибки в теле запроса Метод POST /api/cart Самая большая ошибка, в том что по условию задачи, у нас в теле запроса должен быть объект вида: {\"id\":8,\"title\":\"Кефир\",\"description\":\"Кисломолочный продукт\",\"price\":68,\"count\":2} А фактически уходит вложенный в product объект, и тело запроса выглядит так: {\"product\":{\"id\":8,\"title\":\"Кефир\",\"description\":\"Кисломолочный продукт\",\"price\":68,\"count\":2}} Также в теле запроса, по условию задачи, идентификатор это число \"id\": 8, но фактически уходит строка \"id\": \"8\" (внимание на кавычки) Ошибки в теле ответа Методы GET /api/cart, POST /api/orders, GET /api/orders В задаче в теле ответа идентификатор продукта возвращается как число: \"id\": 8 Фактически, идентификатор продукта возвращается как строка, в кавычках: \"id\": \"8\" Все это явные ошибки, но система почему-то считает их корректными. ","creator":{"public_name":"Алёна Светикова","id":658898,"is_tutor":false},"comments":[{"creator":{"public_name":"Ivan Gagarinov","id":75907,"is_tutor":true},"id":179579,"body":"**Алёна Светикова**, здравствуйте. Спасибо, все поправил!","topic_id":90396}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Система тестирования","entity_url":null,"active":true}},{"id":82324,"title":"как же отвратительно работает у вас веб-доступ... ","plain_title":"как же отвратительно работает у вас веб-доступ... ","creator":{"public_name":"Алексей Филин","id":544993,"is_tutor":false},"comments":[{"creator":{"public_name":"Ivan Gagarinov","id":75907,"is_tutor":true},"id":167796,"body":"**Alexey Filin**, вы можете проверить изменения точно так же через POSTMAN сделав get-запрос на получение списка. Белый экран в веб-доступе может быть по нескольким причинам:\n\n- устаревшая ссылка веб-доступа. Каждый раз, когда вы сбрасываете упражнение, ссылка на веб-доступ меняется. В таком случае приложение по старой ссылке через некоторое время станет недоступным. Проверьте, что вы не открываете приложение по старой ссылке\n- проблема с сетевыми запросами. Возможно провайдер или что-то другое блокирует соединение, это еще может быть из-за VPN, если вы его используете. Проверьте на вкладке network в devtools какие запросы выполняются и не приходит ответ. Скиньте сюда информацию об этих запросах, я постараюсь помочь\n- может быть проблема в браузере. Проверьте, что вы используете последнюю версию браузера google-chrome или firefox. Попробуйте открыть упражнение в режиме инкогнито\n\nЕщё вопрос: проблема только с этим заданием или во всех заданиях не открывается веб-доступ?","topic_id":82324},{"creator":{"public_name":"Ivan Gagarinov","id":75907,"is_tutor":true},"id":167698,"body":"**Alexey Filin**, подскажите, с какими проблемами вы столкнулись? Приложение долго загружается при первом запуске? После загрузки приложение плохо работает?","topic_id":82324},{"creator":{"public_name":"Алексей Филин","id":544993,"is_tutor":false},"id":167743,"body":"Приложение не хочет обновляться и выдает белый экран. \nЯ элементарно не могу проверить вступили в силу изменения, которые я ввожу через POSTMAN или нет. Браузер 100500 раз очищал, как дурачек на этом задании повис.\nКогда по новой веб-доступ открываю -та же история, белый экран и ничего","topic_id":82324}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Система тестирования","entity_url":null,"active":true}},{"id":88875,"title":"Добрый день, у вас в примерах в теле ответа count все время вынесен на один и тот же уровень, что и products в json-е\nЭто я вижу в devtools\n{\"product\":{\"id\":\"6\",\"title\":\"Носки\",\"description\":\"Чтобы ваши ноги не мерзли\",\"price\":50},\"count\":\"10\"}\nЭто в примерах ответов.\nproducts\": [\n {\n \"id\": 8,\n \"title\": \"Кефир\",\n \"description\": \"Кисломолочный продукт\",\n \"price\": 68,\n \"count\": 2\n }\n\nЭто же ошибка, но почему-то это не считается ошибкой. \nКроме того добавление товара в корзину работает неправильно. Если два раза добавлять автомобиль по одной штуке, то в корзине будет 2 строки с автомобилями. И тоже самое повторится с заказом - в нем также будет 2 строки для товара Автомобиль. Не совсем ясно, почему все методы, кроме авторизации, регистрации, списка товаров на продажу не считаются неправильно работающими методами?","plain_title":"Добрый день, у вас в примерах в теле ответа count все время вынесен на один и тот же уровень, что и products в json-е Это я вижу в devtools {\"product\":{\"id\":\"6\",\"title\":\"Носки\",\"description\":\"Чтобы ваши ноги не мерзли\",\"price\":50},\"count\":\"10\"} Это в примерах ответов. products\": [ { \"id\": 8, \"title\": \"Кефир\", \"description\": \"Кисломолочный продукт\", \"price\": 68, \"count\": 2 } Это же ошибка, но почему-то это не считается ошибкой. Кроме того добавление товара в корзину работает неправильно. Если два раза добавлять автомобиль по одной штуке, то в корзине будет 2 строки с автомобилями. И тоже самое повторится с заказом - в нем также будет 2 строки для товара Автомобиль. Не совсем ясно, почему все методы, кроме авторизации, регистрации, списка товаров на продажу не считаются неправильно работающими методами? ","creator":{"public_name":"Александр Агаджанов","id":160838,"is_tutor":false},"comments":[{"creator":{"public_name":"Ivan Gagarinov","id":75907,"is_tutor":true},"id":177324,"body":"**Александр Агаджанов**, здравствуйте! Спасибо, что обратили на это внимание! Это ошибка, я уже поправил. Сделайте, пожалуйста, сброс упражнения, чтобы правки вступили в силу.","topic_id":88875}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Система тестирования","entity_url":null,"active":true}},{"id":89397,"title":"Значение поля \"id\" во многих примерах в задании указано в кавычках, что обычно подразумевает строковый тип. С сервера же приходят числовые значения. В рамках данного задания такие значение считаются эквивалентными независимо от типа (число/строка). Тем не менее, это несколько сбивает с толку.","plain_title":"Значение поля \"id\" во многих примерах в задании указано в кавычках, что обычно подразумевает строковый тип. С сервера же приходят числовые значения. В рамках данного задания такие значение считаются эквивалентными независимо от типа (число/строка). Тем не менее, это несколько сбивает с толку. ","creator":{"public_name":"Evgeniy Filatov","id":182823,"is_tutor":false},"comments":[{"creator":{"public_name":"Ivan Gagarinov","id":75907,"is_tutor":true},"id":178031,"body":"**Evgeniy Filatov**, изменил на строки","topic_id":89397}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Система тестирования","entity_url":null,"active":true}},{"id":95292,"title":"Выходит ошибка 502 в упражнение, при загрузки веб-доступа ","plain_title":"Выходит ошибка 502 в упражнение, при загрузки веб-доступа ","creator":{"public_name":"Анжела","id":401489,"is_tutor":false},"comments":[{"creator":{"public_name":"Ivan Gagarinov","id":75907,"is_tutor":true},"id":185976,"body":"**Анжела**, здравствуйте. Проверил, все работает. Попробуйте сделать сбро упражнения и повторно открыть веб-доступ. Ошибка осталась?","topic_id":95292}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Система тестирования","entity_url":null,"active":true}},{"id":96025,"title":"Добрый день.\nНе очень поняла задания, что и с чем нужно сопоставлять? Чему должны соответсвовать возвращаемые данные? \n\"В запросе на получение заказа вместо :id подставляется идентификатор сущности\" - как куда его подставлять?\nГде можно более подробно почитать про GET и POST?\nРешение должно быть втаком формате или должны быть указаны id https://ru.hexlet.io/code_reviews/1275526 ?\n","plain_title":"Добрый день. Не очень поняла задания, что и с чем нужно сопоставлять? Чему должны соответсвовать возвращаемые данные? \"В запросе на получение заказа вместо :id подставляется идентификатор сущности\" - как куда его подставлять? Где можно более подробно почитать про GET и POST? Решение должно быть втаком формате или должны быть указаны id https://ru.hexlet.io/code_reviews/1275526 ? ","creator":{"public_name":"Svetlana Moiseenko","id":471668,"is_tutor":false},"comments":[{"creator":{"public_name":"Ivan Gagarinov","id":75907,"is_tutor":true},"id":186942,"body":"**Svetlana Moiseenko**, у вас указан правильный формат, такой и должен быть. Id нужно подставлять в сам запрос, чтобы проверить его. Например get-запрос `/api/orders/7`","topic_id":96025},{"creator":{"public_name":"Ivan Gagarinov","id":75907,"is_tutor":true},"id":186792,"body":"**Svetlana Moiseenko**, здравствуйте. Более подробно про get и post можно посмотреть в этом курсе https://ru.hexlet.io/courses/http_protocol. Но сейчас вам достаточно не знать про них подробно, а проверять запросы через devtools, где на каждое действие будет выполняться запрос на сервер.","topic_id":96025},{"creator":{"public_name":"Svetlana Moiseenko","id":471668,"is_tutor":false},"id":186940,"body":"Решение должно быть втаком формате или должны быть указаны id https://ru.hexlet.io/code_reviews/1275526 ?","topic_id":96025}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Система тестирования","entity_url":null,"active":true}},{"id":96646,"title":"Добрый день! В этом и предыдущем задании в файле с тест-кейсами лишняя 61 строчка. Ее нужно просто удалить","plain_title":"Добрый день! В этом и предыдущем задании в файле с тест-кейсами лишняя 61 строчка. Ее нужно просто удалить ","creator":{"public_name":"Елена Войнова","id":623065,"is_tutor":false},"comments":[{"creator":{"public_name":"Olga Pejenkova","id":364375,"is_tutor":true},"id":187581,"body":"**Елена Войнова**, \n\nСпасибо, поправила!","topic_id":96646}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Система тестирования","entity_url":null,"active":true}}],"lesson":{"exercise":{"id":2331,"slug":"testing_phase_testing_system","name":null,"state":"active","kind":"exercise","language":"javascript","locale":"ru","has_web_view":true,"has_test_view":false,"reviewable":true,"readme":"Продолжаем тестировать интернет-магазин. Веб-приложение обычно состоит из двух частей: бэкенд и фронтенд. Умение тестировать их по отдельности позволяет более точно понять, в каком месте ошибка.\n\nНиже список запросов, которые есть в бэкенд-приложении и используются фронтенд-приложением:\n\n* `GET /api/products` — возвращает список товаров на продажу\n\n Пример возвращаемых данных:\n\n ```json\n [\n {\n \"id\": \"1\",\n \"title\": \"Автомобиль\",\n \"description\": \"Эффективное средство передвижения\",\n \"price\": 999999\n },\n {\n \"id\": \"2\",\n \"title\": \"Компьютер\",\n \"description\": \"Электронно-вычислительная машина, помогает в различных задачах\",\n \"price\": 25000\n }\n ]\n ```\n\n * `POST /api/login` — аутентификация\n\n Пример тела запроса:\n\n ```json\n { \"username\":\"111111\", \"password\":\"111111\" }\n ```\n Пример ответа:\n\n ```json\n {\n \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjcsImlhdCI6MTY3MjMxNjU0Nn0.d58qv6_e6QWJev4OqEtLTriSzMmqnWY2ltFA8ilwY6M\",\n \"username\": \"111111\"\n }\n ```\n\n* `POST /api/signup` — создание нового пользователя\n\n Пример тела запроса:\n\n ```json\n {\"username\":\"111111\",\"password\":\"111111\",\"phoneNumber\":\"111111\"}\n ```\n\n Пример ответа:\n\n ```json\n {\n \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjcsImlhdCI6MTY3MjMxNjU0Nn0.d58qv6_e6QWJev4OqEtLTriSzMmqnWY2ltFA8ilwY6M\",\n \"username\": \"111111\"\n }\n ```\n\n* `POST /api/cart` — добавление товара в корзину (требуется авторизация)\n\n Пример тела запроса:\n\n ```json\n {\n \"id\": \"8\",\n \"title\": \"Кефир\",\n \"description\": \"Кисломолочный продукт\",\n \"price\": 68,\n \"count\": 2\n }\n ```\n\n* `GET /api/cart` — получение корзины (требуется авторизация)\n\n Пример ответа:\n\n ```json\n {\n \"userId\": \"7\",\n \"products\": [\n {\n \"id\": \"8\",\n \"title\": \"Кефир\",\n \"description\": \"Кисломолочный продукт\",\n \"price\": 68,\n \"count\": 2\n }\n ]\n }\n ```\n\n* `POST /api/orders` — добавление заказа (требуется авторизация). В заказ попадают товары, которые были добавлены в корзину авторизованного пользователя\n\n Пример ответа:\n\n ```json\n {\n \"userId\": \"7\",\n \"id\": \"10\",\n \"date\": \"2022-12-29T12:33:34.842Z\",\n \"products\": [\n {\n \"id\": \"8\",\n \"title\": \"Кефир\",\n \"description\": \"Кисломолочный продукт\",\n \"price\": 68,\n \"count\": 2\n }\n ]\n }\n ```\n\n* `GET /api/orders` — получение списка заказов авторизованного пользователя (требуется авторизация)\n\n Пример ответа:\n\n ```json\n [\n {\n \"userId\": \"7\",\n \"id\": \"10\",\n \"date\": \"2022-12-29T12:33:34.842Z\",\n \"products\": [\n {\n \"id\": \"8\",\n \"title\": \"Кефир\",\n \"description\": \"Кисломолочный продукт\",\n \"price\": 68,\n \"count\": 2\n }\n ]\n }\n ]\n ```\n\n* `GET /api/orders/:id` — получение заказа\n\n Пример ответа:\n\n ```json\n {\n \"userId\": \"7\",\n \"id\": \"10\",\n \"date\": \"2022-12-29T12:33:34.842Z\",\n \"products\": [\n {\n \"id\": \"8\",\n \"title\": \"Кефир\",\n \"description\": \"Кисломолочный продукт\",\n \"price\": 68,\n \"count\": 2\n }\n ]\n }\n ```\n\nПротестируйте приложение и проверьте через devtools, как отрабатывают запросы во фронтенд-приложении.\n\nВ запросе на получение заказа вместо `:id` подставляется идентификатор сущности. Например, запрос `GET /api/orders/7` вернет заказ с идентификатором 7.\n\n## solution\n\nЗапишите в файл **solution** запросы, которые не работают или работают неправильно. Каждый запрос запишите на отдельной строке.\n\nНапример:\n\n```text\nGET /api/products\nGET /api/orders/:id\n```\n","prepared_readme":"Продолжаем тестировать интернет-магазин. Веб-приложение обычно состоит из двух частей: бэкенд и фронтенд. Умение тестировать их по отдельности позволяет более точно понять, в каком месте ошибка.\n\nНиже список запросов, которые есть в бэкенд-приложении и используются фронтенд-приложением:\n\n* `GET /api/products` — возвращает список товаров на продажу\n\n Пример возвращаемых данных:\n\n ```json\n [\n {\n \"id\": \"1\",\n \"title\": \"Автомобиль\",\n \"description\": \"Эффективное средство передвижения\",\n \"price\": 999999\n },\n {\n \"id\": \"2\",\n \"title\": \"Компьютер\",\n \"description\": \"Электронно-вычислительная машина, помогает в различных задачах\",\n \"price\": 25000\n }\n ]\n ```\n\n * `POST /api/login` — аутентификация\n\n Пример тела запроса:\n\n ```json\n { \"username\":\"111111\", \"password\":\"111111\" }\n ```\n Пример ответа:\n\n ```json\n {\n \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjcsImlhdCI6MTY3MjMxNjU0Nn0.d58qv6_e6QWJev4OqEtLTriSzMmqnWY2ltFA8ilwY6M\",\n \"username\": \"111111\"\n }\n ```\n\n* `POST /api/signup` — создание нового пользователя\n\n Пример тела запроса:\n\n ```json\n {\"username\":\"111111\",\"password\":\"111111\",\"phoneNumber\":\"111111\"}\n ```\n\n Пример ответа:\n\n ```json\n {\n \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjcsImlhdCI6MTY3MjMxNjU0Nn0.d58qv6_e6QWJev4OqEtLTriSzMmqnWY2ltFA8ilwY6M\",\n \"username\": \"111111\"\n }\n ```\n\n* `POST /api/cart` — добавление товара в корзину (требуется авторизация)\n\n Пример тела запроса:\n\n ```json\n {\n \"id\": \"8\",\n \"title\": \"Кефир\",\n \"description\": \"Кисломолочный продукт\",\n \"price\": 68,\n \"count\": 2\n }\n ```\n\n* `GET /api/cart` — получение корзины (требуется авторизация)\n\n Пример ответа:\n\n ```json\n {\n \"userId\": \"7\",\n \"products\": [\n {\n \"id\": \"8\",\n \"title\": \"Кефир\",\n \"description\": \"Кисломолочный продукт\",\n \"price\": 68,\n \"count\": 2\n }\n ]\n }\n ```\n\n* `POST /api/orders` — добавление заказа (требуется авторизация). В заказ попадают товары, которые были добавлены в корзину авторизованного пользователя\n\n Пример ответа:\n\n ```json\n {\n \"userId\": \"7\",\n \"id\": \"10\",\n \"date\": \"2022-12-29T12:33:34.842Z\",\n \"products\": [\n {\n \"id\": \"8\",\n \"title\": \"Кефир\",\n \"description\": \"Кисломолочный продукт\",\n \"price\": 68,\n \"count\": 2\n }\n ]\n }\n ```\n\n* `GET /api/orders` — получение списка заказов авторизованного пользователя (требуется авторизация)\n\n Пример ответа:\n\n ```json\n [\n {\n \"userId\": \"7\",\n \"id\": \"10\",\n \"date\": \"2022-12-29T12:33:34.842Z\",\n \"products\": [\n {\n \"id\": \"8\",\n \"title\": \"Кефир\",\n \"description\": \"Кисломолочный продукт\",\n \"price\": 68,\n \"count\": 2\n }\n ]\n }\n ]\n ```\n\n* `GET /api/orders/:id` — получение заказа\n\n Пример ответа:\n\n ```json\n {\n \"userId\": \"7\",\n \"id\": \"10\",\n \"date\": \"2022-12-29T12:33:34.842Z\",\n \"products\": [\n {\n \"id\": \"8\",\n \"title\": \"Кефир\",\n \"description\": \"Кисломолочный продукт\",\n \"price\": 68,\n \"count\": 2\n }\n ]\n }\n ```\n\nПротестируйте приложение и проверьте через devtools, как отрабатывают запросы во фронтенд-приложении.\n\nВ запросе на получение заказа вместо `:id` подставляется идентификатор сущности. Например, запрос `GET /api/orders/7` вернет заказ с идентификатором 7.\n\n## solution\n\nЗапишите в файл **solution** запросы, которые не работают или работают неправильно. Каждый запрос запишите на отдельной строке.\n\nНапример:\n\n```text\nGET /api/products\nGET /api/orders/:id\n```\n","has_solution":true,"entity_name":"Система тестирования"},"units":[{"id":7297,"name":"theory","url":"/courses/testing-phase/lessons/testing-system/theory_unit"},{"id":7667,"name":"quiz","url":"/courses/testing-phase/lessons/testing-system/quiz_unit"},{"id":8381,"name":"exercise","url":"/courses/testing-phase/lessons/testing-system/exercise_unit"}],"links":[],"ordered_units":[{"id":7297,"name":"theory","url":"/courses/testing-phase/lessons/testing-system/theory_unit"},{"id":7667,"name":"quiz","url":"/courses/testing-phase/lessons/testing-system/quiz_unit"},{"id":8381,"name":"exercise","url":"/courses/testing-phase/lessons/testing-system/exercise_unit"}],"id":3280,"slug":"testing-system","state":"approved","name":"Система тестирования","course_order":500,"goal":"Обсуждаем, что такое уровни тестирования и система тестирования, из чего она состоит и какие варианты представления бывают","self_study":null,"theory_video_provider":"vimeo","theory_video_uid":"783916385","theory":"Система тестирования на проекте — это способ организации тестов в процессе разработки. Она включает в себя порядок выполнения тестов на каждом уровне, их место в общем процессе разработки, а еще степень автоматизации и относительное количество. Обычно система тестирования соответствует требованиям проекта.\n\nВ этом уроке мы познакомимся с самой системой и ее уровнями. Этот урок поможет понять пирамиду тестирования, которую мы будем изучать далее в курсе.\n\n## Что такое система тестирования\n\nСистема тестирования — это способ организации тестов на проекте. Она включает в себя определенный порядок выполнения тестов и их место в процессе разработки. Количество тестов на каждом уровне зависит от конкретного проекта и его требований.\n\nКак правило, система состоит из трех уровней:\n\n* Модульное тестирование\n* Интеграционное тестирование\n* Системное тестирование\n\n## Модульное тестирование\n\nМодульное тестирование ищет дефекты в отдельных модулях приложения — объектах, классах, функциях, программных модулях и других компонентах, которые могут быть протестированы независимо друг от друга. Другими словами, мы проверяем конкретные фрагменты кода.\n\nМодульное тестирование проводится с помощью **юнит-тестов**. Для примера представим, что нам нужно протестировать велосипед. На этапе модульного тестирования мы оценим, как работают отдельные запчасти — например, колесо.\n\nЮнит-тесты колеса могли бы проверить:\n\n* Не деформирована ли сама форма колеса\n* Нет ли повреждений на ободке, спицах и камере\n* Все ли в порядке со звездочками\n* Крутится ли колесо в целом\n\nТаким же образом проверяются другие запчасти велосипеда — например, цепь или руль.\n\nВозьмем менее бытовой пример и представим, что нам нужно протестировать корзину интернет-магазина. Работу этой корзины обеспечивает код из разных модулей — в том числе в нем есть функция, которая подсчитывает общую стоимость заказа.\n\nПри модульном тестировании этой функции юнит-тесты проверяют:\n\n* Работает ли функция суммирования\n* Нет ли в функции синтаксических или логических ошибок\n* Правильным ли получается результат суммирования\n\nПо такому же принципу мы проверим другие модули — например, API, которое передает параметры для суммирования.\n\n## Интеграционное тестирование\n\nНа этапе интеграционного тестирования мы проверяем взаимодействие между отдельными модулями — объектами, классами, функциями, программными модулями и так далее. Другими словами, мы проверяем, как два фрагмента кода работают вместе.\n\nВернемся к примеру с велосипедом. На этапе модульного тестирования мы изучили колесо и цепь по отдельности, а теперь нужно проверить взаимодействие и узнать, точно ли колесо приводится в движение с помощью цепи. Здесь мы проверяем интеграцию цепи и звездочки колеса — дергаем за цепь и смотрим, будет ли крутиться колесо.\n\nПерейдем к примеру с корзиной. На первом этапе мы проверили функцию суммирования и API по отдельности, а сейчас протестируем их вместе:\n\n* Правильно ли API отдает параметры в функцию\n* Верно ли API передает результат функции дальше\n\nВ контексте системы тестирования термин «интеграционное тестирование» означает проверку взаимодействий модулей, но в других источниках вы можете встретить другое определение. Иногда этим термином обозначают проверку интеграции между двумя подсистемами, то есть какими-то большими частями программы. Это тоже правильное определение, просто оно используется в контексте других аспектов тестирования.\n\n## Системное тестирование\n\nСледующий уровень — это системное тестирование. Оно выполняется для всей системы и проверяет функциональные и нефункциональные требования.\n\nОба рассмотренных выше примера закончатся системным тестированием:\n\n* В примере с велосипедом мы сядем на него и попробуем поехать. Если получится, значит велосипед работает как система в целом — функциональный системный тест пройден\n* В примере с корзиной мы зайдем на сайт, добавим несколько товаров в корзину и проверим, как отображается сумма заказа. Если сумма верна и видна в интерфейсе, то — функциональный системный тест пройден\n"},"lessonMember":null,"courseMember":null,"course":{"start_lesson":{"exercise":null,"units":[{"id":7289,"name":"theory","url":"/courses/testing-phase/lessons/intro/theory_unit"}],"links":[],"ordered_units":[{"id":7289,"name":"theory","url":"/courses/testing-phase/lessons/intro/theory_unit"}],"id":3276,"slug":"intro","state":"approved","name":"Введение","course_order":100,"goal":"Знакомимся с целями курса","self_study":null,"theory_video_provider":"vimeo","theory_video_uid":"782862781","theory":"Как и в разработке, в тестировании есть конкретные практики, которые проверены временем. Но сфера разработки приложений быстро меняется, а значит старые способы постепенно теряют свою актуальность. Поэтому специалисту по тестированию нужно учиться не только выполнять свои непосредственные задачи, но и смотреть шире. Умение видеть недочеты в процессах и устранять их — это тот навык, который нужен и новичкам, и уже опытным специалистам. Именно этому навыку мы будем учиться на этом курсе.\n\n\n\n## Цели курса\n\nЗдесь вы узнаете, как выполнять тестирование лучше — быстрее, эффективнее, дешевле. Мы обсудим классический подход, отметим его достоинства и недостатки — так вы поймете, какие задачи можно оптимизировать. Также вы узнаете, как на стоимость проекта влияют система тестирования, тестовая пирамида и функциональные тесты. В этом курсе мы рассмотрим такие темы:\n\n* Место тестирования в процессе разработки — классический подход и его недостатки в современной разработке\n* Способы удешевления тестирования\n* Автоматизация — какая она бывает и на каких уровнях тестирования работает\n* Система и уровни тестирования\n* Пирамида тестирования\n* Смещение тестирования влево по процессу разработки\n"},"id":317,"slug":"testing-phase","challenges_count":3,"name":"Этап тестирования","allow_indexing":true,"state":"approved","course_state":"finished","pricing_type":"paid","description":"На этом курсе вы изучите подробнее этап тестирования. Вы узнаете больше про пирамиду тестирования, удешевления тестирования, для чего нужна автоматизация. В итоге вы научитесь видеть достоинства и недостатки классического подхода к тестированию, а также поймете, какие задачи можно оптимизировать.","kind":"additional","updated_at":"2026-01-20T11:43:04.839Z","language":"other","duration_cache":29940,"skills":["Научитесь выполнять тестирование быстрее, эффективнее и дешевле","Узнаете, какие тесты следует автоматизировать первыми","Сможете видеть недочеты в процессах и устранять их"],"keywords":[],"lessons_count":7,"cover":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NjY0OCwicHVyIjoiYmxvYl9pZCJ9fQ==--095eb5a1e59d894c26ead8f003cd3e05e0d74ef4/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fZmlsbCI6WzYwMCw0MDBdfSwicHVyIjoidmFyaWF0aW9uIn19--6067466c2912ca31a17eddee04b8cf2a38c6ad17/image.png"},"recommendedLandings":[{"stack":{"id":56,"slug":"qa-engineer","title":"Инженер по тестированию","audience":"for_beginners","start_type":"weekly","pricing_model":"purchase","priority":"high","kind":"profession","state":"published","stack_state":"finished","order":40,"duration_in_months":4},"id":100,"slug":"qa-engineer","title":"Инженер по ручному тестированию","subtitle":"Изучите виды тестирования, тест-кейсы, DevTools, Postman, SQL, Git и HTTP/HTTPS.","subtitle_for_lists":"Изучите виды тестирования, тест-кейсы, DevTools, Postman, SQL, Git и HTTP/HTTPS.","locale":"ru","current":true,"duration_in_months_text":"4 месяца","stack_slug":"qa-engineer","price_text":"от 3 368 ₽","duration_text":"4 месяца","cover_list_variant":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Mzk1MCwicHVyIjoiYmxvYl9pZCJ9fQ==--4a16fe638654fb8d5ae09d7e8ab8e16ff228214f/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Bug%20fixing-amico.png"}],"lessonMemberUnit":null,"accessToLearnUnitExists":false,"accessToCourseExists":false},"url":"/courses/testing-phase/lessons/testing-system/theory_unit","version":"8f286f6358a90a7bef2263b3a6edf5a90a94fa42","encryptHistory":false,"clearHistory":false}"><style data-mantine-styles="true">:root, :host{--mantine-font-family: Arial, sans-serif;--mantine-font-family-headings: Arial, sans-serif;--mantine-heading-font-weight: normal;--mantine-radius-default: 0rem;--mantine-primary-color-filled: var(--mantine-color-indigo-filled);--mantine-primary-color-filled-hover: var(--mantine-color-indigo-filled-hover);--mantine-primary-color-light: var(--mantine-color-indigo-light);--mantine-primary-color-light-hover: var(--mantine-color-indigo-light-hover);--mantine-primary-color-light-color: var(--mantine-color-indigo-light-color);--mantine-spacing-xxl: calc(4rem * var(--mantine-scale));--mantine-font-size-xs: 12px;--mantine-font-size-sm: 14px;--mantine-font-size-md: 16px;--mantine-font-size-lg: clamp(16.0000px, calc(15.2727px + 0.2273vw), 18.0000px);--mantine-font-size-xl: clamp(16.0000px, calc(14.5455px + 0.4545vw), 20.0000px);--mantine-font-size-display-3: clamp(32.0000px, calc(26.1818px + 1.8182vw), 48.0000px);--mantine-font-size-display-2: clamp(36.0000px, calc(25.8182px + 3.1818vw), 64.0000px);--mantine-font-size-display-1: clamp(40.0000px, calc(25.4545px + 4.5455vw), 80.0000px);--mantine-font-size-h1: clamp(28.0000px, calc(23.6364px + 1.3636vw), 40.0000px);--mantine-font-size-h2: clamp(24.0000px, calc(21.0909px + 0.9091vw), 32.0000px);--mantine-font-size-h3: clamp(20.0000px, calc(17.0909px + 0.9091vw), 28.0000px);--mantine-font-size-h4: clamp(16.0000px, calc(13.0909px + 0.9091vw), 24.0000px);--mantine-font-size-h5: clamp(16.0000px, calc(14.5455px + 0.4545vw), 20.0000px);--mantine-font-size-h6: 1rem;--mantine-primary-color-0: var(--mantine-color-indigo-0);--mantine-primary-color-1: var(--mantine-color-indigo-1);--mantine-primary-color-2: var(--mantine-color-indigo-2);--mantine-primary-color-3: var(--mantine-color-indigo-3);--mantine-primary-color-4: var(--mantine-color-indigo-4);--mantine-primary-color-5: var(--mantine-color-indigo-5);--mantine-primary-color-6: var(--mantine-color-indigo-6);--mantine-primary-color-7: var(--mantine-color-indigo-7);--mantine-primary-color-8: var(--mantine-color-indigo-8);--mantine-primary-color-9: var(--mantine-color-indigo-9);--mantine-color-red-0: #ffeaea;--mantine-color-red-1: #fed4d4;--mantine-color-red-2: #f4a7a8;--mantine-color-red-3: #ec7878;--mantine-color-red-4: #e55050;--mantine-color-red-5: #e03131;--mantine-color-red-6: #e02829;--mantine-color-red-7: #c71a1c;--mantine-color-red-8: #b21218;--mantine-color-red-9: #9c0411;--mantine-color-violet-0: #fce9ff;--mantine-color-violet-1: #f1cfff;--mantine-color-violet-2: #e09bff;--mantine-color-violet-3: #d16fff;--mantine-color-violet-4: #be37fe;--mantine-color-violet-5: #b51afe;--mantine-color-violet-6: #b009ff;--mantine-color-violet-7: #9b00e4;--mantine-color-violet-8: #8a00cc;--mantine-color-violet-9: #7800b3;--mantine-color-indigo-0: #edecff;--mantine-color-indigo-1: #d6d5fe;--mantine-color-indigo-2: #aaa9f4;--mantine-color-indigo-3: #7b79eb;--mantine-color-indigo-4: #5451e4;--mantine-color-indigo-5: #3b37e0;--mantine-color-indigo-6: #2d2adf;--mantine-color-indigo-7: #1f1ec7;--mantine-color-indigo-8: #1819b2;--mantine-color-indigo-9: #0c149e;--mantine-color-cyan-0: #dffdff;--mantine-color-cyan-1: #caf5ff;--mantine-color-cyan-2: #99e8ff;--mantine-color-cyan-3: #64daff;--mantine-color-cyan-4: #3ccffe;--mantine-color-cyan-5: #24c8fe;--mantine-color-cyan-6: #00c2ff;--mantine-color-cyan-7: #00ade4;--mantine-color-cyan-8: #009acd;--mantine-color-cyan-9: #0085b5;--mantine-color-green-0: #e9fdec;--mantine-color-green-1: #d7f6dc;--mantine-color-green-2: #b0eab9;--mantine-color-green-3: #86df94;--mantine-color-green-4: #62d574;--mantine-color-green-5: #4ccf5f;--mantine-color-green-6: #3fcc54;--mantine-color-green-7: #2fb344;--mantine-color-green-8: #25a03b;--mantine-color-green-9: #138a2e;--mantine-color-yellow-0: #fff7e2;--mantine-color-yellow-1: #ffeecd;--mantine-color-yellow-2: #ffdc9c;--mantine-color-yellow-3: #ffc966;--mantine-color-yellow-4: #feb93a;--mantine-color-yellow-5: #feae1e;--mantine-color-yellow-6: #ffa90f;--mantine-color-yellow-8: #ca8200;--mantine-color-yellow-9: #af7000;--mantine-h1-font-size: clamp(28.0000px, calc(23.6364px + 1.3636vw), 40.0000px);--mantine-h1-font-weight: normal;--mantine-h2-font-size: clamp(24.0000px, calc(21.0909px + 0.9091vw), 32.0000px);--mantine-h2-font-weight: normal;--mantine-h3-font-size: clamp(20.0000px, calc(17.0909px + 0.9091vw), 28.0000px);--mantine-h3-font-weight: normal;--mantine-h4-font-size: clamp(16.0000px, calc(13.0909px + 0.9091vw), 24.0000px);--mantine-h4-font-weight: normal;--mantine-h5-font-size: clamp(16.0000px, calc(14.5455px + 0.4545vw), 20.0000px);--mantine-h5-font-weight: normal;--mantine-h6-font-size: 1rem;--mantine-h6-font-weight: normal;}
:root[data-mantine-color-scheme="dark"], :host([data-mantine-color-scheme="dark"]){--mantine-color-anchor: var(--mantine-color-text);--mantine-color-dimmed: #495057;--mantine-color-dark-filled: var(--mantine-color-dark-5);--mantine-color-dark-filled-hover: var(--mantine-color-dark-6);--mantine-color-dark-light: rgba(105, 105, 105, 0.15);--mantine-color-dark-light-hover: rgba(105, 105, 105, 0.2);--mantine-color-dark-light-color: var(--mantine-color-dark-0);--mantine-color-dark-outline: var(--mantine-color-dark-1);--mantine-color-dark-outline-hover: rgba(184, 184, 184, 0.05);--mantine-color-gray-filled: var(--mantine-color-gray-5);--mantine-color-gray-filled-hover: var(--mantine-color-gray-6);--mantine-color-gray-light: rgba(222, 226, 230, 0.15);--mantine-color-gray-light-hover: rgba(222, 226, 230, 0.2);--mantine-color-gray-light-color: var(--mantine-color-gray-0);--mantine-color-gray-outline: var(--mantine-color-gray-1);--mantine-color-gray-outline-hover: rgba(241, 243, 245, 0.05);--mantine-color-red-filled: var(--mantine-color-red-5);--mantine-color-red-filled-hover: var(--mantine-color-red-6);--mantine-color-red-light: rgba(236, 120, 120, 0.15);--mantine-color-red-light-hover: rgba(236, 120, 120, 0.2);--mantine-color-red-light-color: var(--mantine-color-red-0);--mantine-color-red-outline: var(--mantine-color-red-1);--mantine-color-red-outline-hover: rgba(254, 212, 212, 0.05);--mantine-color-pink-filled: var(--mantine-color-pink-5);--mantine-color-pink-filled-hover: var(--mantine-color-pink-6);--mantine-color-pink-light: rgba(250, 162, 193, 0.15);--mantine-color-pink-light-hover: rgba(250, 162, 193, 0.2);--mantine-color-pink-light-color: var(--mantine-color-pink-0);--mantine-color-pink-outline: var(--mantine-color-pink-1);--mantine-color-pink-outline-hover: rgba(255, 222, 235, 0.05);--mantine-color-grape-filled: var(--mantine-color-grape-5);--mantine-color-grape-filled-hover: var(--mantine-color-grape-6);--mantine-color-grape-light: rgba(229, 153, 247, 0.15);--mantine-color-grape-light-hover: rgba(229, 153, 247, 0.2);--mantine-color-grape-light-color: var(--mantine-color-grape-0);--mantine-color-grape-outline: var(--mantine-color-grape-1);--mantine-color-grape-outline-hover: rgba(243, 217, 250, 0.05);--mantine-color-violet-filled: var(--mantine-color-violet-5);--mantine-color-violet-filled-hover: var(--mantine-color-violet-6);--mantine-color-violet-light: rgba(209, 111, 255, 0.15);--mantine-color-violet-light-hover: rgba(209, 111, 255, 0.2);--mantine-color-violet-light-color: var(--mantine-color-violet-0);--mantine-color-violet-outline: var(--mantine-color-violet-1);--mantine-color-violet-outline-hover: rgba(241, 207, 255, 0.05);--mantine-color-indigo-filled: var(--mantine-color-indigo-5);--mantine-color-indigo-filled-hover: var(--mantine-color-indigo-6);--mantine-color-indigo-light: rgba(123, 121, 235, 0.15);--mantine-color-indigo-light-hover: rgba(123, 121, 235, 0.2);--mantine-color-indigo-light-color: var(--mantine-color-indigo-0);--mantine-color-indigo-outline: var(--mantine-color-indigo-1);--mantine-color-indigo-outline-hover: rgba(214, 213, 254, 0.05);--mantine-color-blue-filled: var(--mantine-color-blue-5);--mantine-color-blue-filled-hover: var(--mantine-color-blue-6);--mantine-color-blue-light: rgba(116, 192, 252, 0.15);--mantine-color-blue-light-hover: rgba(116, 192, 252, 0.2);--mantine-color-blue-light-color: var(--mantine-color-blue-0);--mantine-color-blue-outline: var(--mantine-color-blue-1);--mantine-color-blue-outline-hover: rgba(208, 235, 255, 0.05);--mantine-color-cyan-filled: var(--mantine-color-cyan-5);--mantine-color-cyan-filled-hover: var(--mantine-color-cyan-6);--mantine-color-cyan-light: rgba(100, 218, 255, 0.15);--mantine-color-cyan-light-hover: rgba(100, 218, 255, 0.2);--mantine-color-cyan-light-color: var(--mantine-color-cyan-0);--mantine-color-cyan-outline: var(--mantine-color-cyan-1);--mantine-color-cyan-outline-hover: rgba(202, 245, 255, 0.05);--mantine-color-teal-filled: var(--mantine-color-teal-5);--mantine-color-teal-filled-hover: var(--mantine-color-teal-6);--mantine-color-teal-light: rgba(99, 230, 190, 0.15);--mantine-color-teal-light-hover: rgba(99, 230, 190, 0.2);--mantine-color-teal-light-color: var(--mantine-color-teal-0);--mantine-color-teal-outline: var(--mantine-color-teal-1);--mantine-color-teal-outline-hover: rgba(195, 250, 232, 0.05);--mantine-color-green-filled: var(--mantine-color-green-5);--mantine-color-green-filled-hover: var(--mantine-color-green-6);--mantine-color-green-light: rgba(134, 223, 148, 0.15);--mantine-color-green-light-hover: rgba(134, 223, 148, 0.2);--mantine-color-green-light-color: var(--mantine-color-green-0);--mantine-color-green-outline: var(--mantine-color-green-1);--mantine-color-green-outline-hover: rgba(215, 246, 220, 0.05);--mantine-color-lime-filled: var(--mantine-color-lime-5);--mantine-color-lime-filled-hover: var(--mantine-color-lime-6);--mantine-color-lime-light: rgba(192, 235, 117, 0.15);--mantine-color-lime-light-hover: rgba(192, 235, 117, 0.2);--mantine-color-lime-light-color: var(--mantine-color-lime-0);--mantine-color-lime-outline: var(--mantine-color-lime-1);--mantine-color-lime-outline-hover: rgba(233, 250, 200, 0.05);--mantine-color-yellow-filled: var(--mantine-color-yellow-5);--mantine-color-yellow-filled-hover: var(--mantine-color-yellow-6);--mantine-color-yellow-light: rgba(255, 201, 102, 0.15);--mantine-color-yellow-light-hover: rgba(255, 201, 102, 0.2);--mantine-color-yellow-light-color: var(--mantine-color-yellow-0);--mantine-color-yellow-outline: var(--mantine-color-yellow-1);--mantine-color-yellow-outline-hover: rgba(255, 238, 205, 0.05);--mantine-color-orange-filled: var(--mantine-color-orange-5);--mantine-color-orange-filled-hover: var(--mantine-color-orange-6);--mantine-color-orange-light: rgba(255, 192, 120, 0.15);--mantine-color-orange-light-hover: rgba(255, 192, 120, 0.2);--mantine-color-orange-light-color: var(--mantine-color-orange-0);--mantine-color-orange-outline: var(--mantine-color-orange-1);--mantine-color-orange-outline-hover: rgba(255, 232, 204, 0.05);--app-cta-gradient: linear-gradient(90deg, var(--mantine-color-blue-9) 0%, var(--mantine-color-cyan-7) 100%);--app-color-surface: #2e2e2e;}
:root[data-mantine-color-scheme="light"], :host([data-mantine-color-scheme="light"]){--mantine-color-anchor: var(--mantine-color-text);--mantine-color-dimmed: #495057;--mantine-color-red-light: rgba(224, 40, 41, 0.1);--mantine-color-red-light-hover: rgba(224, 40, 41, 0.12);--mantine-color-red-outline-hover: rgba(224, 40, 41, 0.05);--mantine-color-violet-light: rgba(176, 9, 255, 0.1);--mantine-color-violet-light-hover: rgba(176, 9, 255, 0.12);--mantine-color-violet-outline-hover: rgba(176, 9, 255, 0.05);--mantine-color-indigo-light: rgba(45, 42, 223, 0.1);--mantine-color-indigo-light-hover: rgba(45, 42, 223, 0.12);--mantine-color-indigo-outline-hover: rgba(45, 42, 223, 0.05);--mantine-color-cyan-light: rgba(0, 194, 255, 0.1);--mantine-color-cyan-light-hover: rgba(0, 194, 255, 0.12);--mantine-color-cyan-outline-hover: rgba(0, 194, 255, 0.05);--mantine-color-green-light: rgba(63, 204, 84, 0.1);--mantine-color-green-light-hover: rgba(63, 204, 84, 0.12);--mantine-color-green-outline-hover: rgba(63, 204, 84, 0.05);--mantine-color-yellow-light: rgba(255, 169, 15, 0.1);--mantine-color-yellow-light-hover: rgba(255, 169, 15, 0.12);--mantine-color-yellow-outline-hover: rgba(255, 169, 15, 0.05);--app-color-surface: #f1f3f5;--app-cta-gradient: linear-gradient(90deg, var(--mantine-color-blue-filled) 0%, var(--mantine-color-cyan-5) 100%);}</style><style data-mantine-styles="classes">@media (max-width: 35.99375em) {.mantine-visible-from-xs {display: none !important;}}@media (min-width: 36em) {.mantine-hidden-from-xs {display: none !important;}}@media (max-width: 47.99375em) {.mantine-visible-from-sm {display: none !important;}}@media (min-width: 48em) {.mantine-hidden-from-sm {display: none !important;}}@media (max-width: 61.99375em) {.mantine-visible-from-md {display: none !important;}}@media (min-width: 62em) {.mantine-hidden-from-md {display: none !important;}}@media (max-width: 74.99375em) {.mantine-visible-from-lg {display: none !important;}}@media (min-width: 75em) {.mantine-hidden-from-lg {display: none !important;}}@media (max-width: 87.99375em) {.mantine-visible-from-xl {display: none !important;}}@media (min-width: 88em) {.mantine-hidden-from-xl {display: none !important;}}</style><div style="position:absolute;top:0rem" class=""></div><div style="max-width:var(--container-size-xl);height:100%;min-height:0rem" class=""><style data-mantine-styles="inline">.__m__-_R_5ub_{--grid-gutter:0rem;}</style><div style="height:100%;min-height:0rem" class="m_410352e9 mantine-Grid-root __m__-_R_5ub_"><div class="m_dee7bd2f mantine-Grid-inner" style="height:100%"><style data-mantine-styles="inline">.__m__-_R_rdub_{--col-flex-grow:auto;--col-flex-basis:91.66666666666667%;--col-max-width:91.66666666666667%;}@media(min-width: 48em){.__m__-_R_rdub_{--col-flex-grow:auto;--col-flex-basis:83.33333333333334%;--col-max-width:83.33333333333334%;}}</style><div style="min-width:0rem;height:100%;min-height:0rem;display:flex" class="m_96bdd299 mantine-Grid-col __m__-_R_rdub_"><style data-mantine-styles="inline">.__m__-_R_6qrdub_{margin-top:0rem;padding-inline:var(--mantine-spacing-xs);width:100%;}@media(min-width: 48em){.__m__-_R_6qrdub_{margin-top:var(--mantine-spacing-xl);width:80%;}}@media(min-width: 62em){.__m__-_R_6qrdub_{padding-inline:var(--mantine-spacing-xl);}}</style><div style="margin-inline:auto;max-width:var(--mantine-breakpoint-xl)" class="__m__-_R_6qrdub_"><div style="color:var(--mantine-color-dimmed)" class="m_4451eb3a mantine-Center-root" data-inline="true"><div style="--ti-size:var(--ti-size-xs);--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;margin-inline-end:calc(0.125rem * var(--mantine-scale));color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent" data-size="xs"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-lock "><path d="M5 13a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v6a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-6"></path><path d="M11 16a1 1 0 1 0 2 0a1 1 0 0 0 -2 0"></path><path d="M8 11v-4a4 4 0 1 1 8 0v4"></path></svg></div><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Этап тестирования</p></div><h1 style="--title-fw:var(--mantine-h1-font-weight);--title-lh:var(--mantine-h1-line-height);--title-fz:var(--mantine-h1-font-size);margin-bottom:var(--mantine-spacing-xl)" class="m_8a5d1357 mantine-Title-root" data-order="1">Теория: Система тестирования</h1><script type="application/ld+json">{"@context":"https://schema.org","@type":"LearningResource","name":"Система тестирования","inLanguage":"ru","isPartOf":{"@type":"LearningResource","name":"Этап тестирования"},"isAccessibleForFree":"False","hasPart":{"@type":"WebPageElement","isAccessibleForFree":"False","cssSelector":".paywalled"}}</script><div class=""><div style="--alert-color:var(--mantine-color-indigo-light-color);margin-bottom:var(--mantine-spacing-lg);font-size:var(--mantine-font-size-lg)" class="m_66836ed3 mantine-Alert-root" id="mantine-_R_remqrdub_" role="alert" aria-describedby="mantine-_R_remqrdub_-body" aria-labelledby="mantine-_R_remqrdub_-title"><div class="m_a5d60502 mantine-Alert-wrapper"><div class="m_667f2a6a mantine-Alert-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-rocket "><path d="M4 13a8 8 0 0 1 7 7a6 6 0 0 0 3 -5a9 9 0 0 0 6 -8a3 3 0 0 0 -3 -3a9 9 0 0 0 -8 6a6 6 0 0 0 -5 3"></path><path d="M7 14a6 6 0 0 0 -3 6a6 6 0 0 0 6 -3"></path><path d="M14 9a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"></path></svg></div><div class="m_667c2793 mantine-Alert-body"><div class="m_6a03f287 mantine-Alert-title"><span id="mantine-_R_remqrdub_-title" class="m_698f4f23 mantine-Alert-label">Полный доступ к материалам</span></div><div id="mantine-_R_remqrdub_-body" class="m_7fa78076 mantine-Alert-message"><div style="--group-gap:var(--mantine-spacing-md);--group-align:center;--group-justify:space-between;--group-wrap:wrap" class="m_4081bf90 mantine-Group-root"><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Зарегистрируйтесь и получите доступ к этому и десяткам других курсов</p><a style="--button-height:var(--button-height-xs);--button-padding-x:var(--button-padding-x-xs);--button-fz:var(--mantine-font-size-xs);--button-bg:linear-gradient(45deg, var(--mantine-color-blue-filled) 0%, var(--mantine-color-cyan-filled) 100%);--button-hover:linear-gradient(45deg, var(--mantine-color-blue-filled) 0%, var(--mantine-color-cyan-filled) 100%);--button-color:var(--mantine-color-white);--button-bd:none" class="mantine-focus-auto mantine-active m_77c9d27d mantine-Button-root m_87cf2631 mantine-UnstyledButton-root" data-variant="gradient" data-size="xs" href="/u/new"><span class="m_80f1301b mantine-Button-inner"><span class="m_811560b9 mantine-Button-label">Зарегистрироваться</span></span></a></div></div></div></div></div><div class="paywalled m_d08caa0 mantine-Typography-root"><p>Система тестирования на проекте — это способ организации тестов в процессе разработки. Она включает в себя порядок выполнения тестов на каждом уровне, их место в общем процессе разработки, а еще степень автоматизации и относительное количество. Обычно система тестирования соответствует требованиям проекта.</p>
<p>В этом уроке мы познакомимся с самой системой и ее уровнями. Этот урок поможет понять пирамиду тестирования, которую мы будем изучать далее в курсе.</p>
<h2 id="heading-2-1">Что такое система тестирования</h2>
<p>Система тестирования — это способ организации тестов на проекте. Она включает в себя определенный порядок выполнения тестов и их место в процессе разработки. Количество тестов на каждом уровне зависит от конкретного проекта и его требований.</p>
<p>Как правило, система состоит из трех уровней:</p>
<ul>
<li>Модульное тестирование</li>
<li>Интеграционное тестирование</li>
<li>Системное тестирование</li>
</ul>
<h2 id="heading-2-2">Модульное тестирование</h2>
<p>Модульное тестирование ищет дефекты в отдельных модулях приложения — объектах, классах, функциях, программных модулях и других компонентах, которые могут быть протестированы независимо друг от друга. Другими словами, мы проверяем конкретные фрагменты кода.</p>
<p>Модульное тестирование проводится с помощью <strong>юнит-тестов</strong>. Для примера представим, что нам нужно протестировать велосипед. На этапе модульного тестирования мы оценим, как работают отдельные запчасти — например, колесо.</p>
<p>Юнит-тесты колеса могли бы проверить:</p>
<ul>
<li>Не деформирована ли сама форма колеса</li>
<li>Нет ли повреждений на ободке, спицах и камере</li>
<li>Все ли в порядке со звездочками</li>
<li>Крутится ли колесо в целом</li>
</ul>
<p>Таким же образом проверяются другие запчасти велосипеда — например, цепь или руль.</p>
<p>Возьмем менее бытовой пример и представим, что нам нужно протестировать корзину интернет-магазина. Работу этой корзины обеспечивает код из разных модулей — в том числе в нем есть функция, которая подсчитывает общую стоимость заказа.</p>
<p>При модульном тестировании этой функции юнит-тесты проверяют:</p>
<ul>
<li>Работает ли функция суммирования</li>
<li>Нет ли в функции синтаксических или логических ошибок</li>
<li>Правильным ли получается результат суммирования</li>
</ul>
<p>По такому же принципу мы проверим другие модули — например, API, которое передает параметры для суммирования.</p>
<h2 id="heading-2-3">Интеграционное тестирование</h2>
<p>На этапе интеграционного тестирования мы проверяем взаимодействие между отдельными модулями — объектами, классами, функциями, программными модулями и так далее. Другими словами, мы проверяем, как два фрагмента кода работают вместе.</p>
<p>Вернемся к примеру с велосипедом. На этапе модульного тестирования мы изучили колесо и цепь по отдельности, а теперь нужно проверить взаимодействие и узнать, точно ли колесо приводится в движение с помощью цепи. Здесь мы проверяем интеграцию цепи и звездочки колеса — дергаем за цепь и смотрим, будет ли крутиться колесо.</p>
<p>Перейдем к примеру с корзиной. На первом этапе мы проверили функцию суммирования и API по отдельности, а сейчас протестируем их вместе:</p>
<ul>
<li>Правильно ли API отдает параметры в функцию</li>
<li>Верно ли API передает результат функции дальше</li>
</ul>
<p>В контексте системы тестирования термин «интеграционное тестирование» означает проверку взаимодействий модулей, но в других источниках вы можете встретить другое определение. Иногда этим термином обозначают проверку интеграции между двумя подсистемами, то есть какими-то большими частями программы. Это тоже правильное определение, просто оно используется в контексте других аспектов тестирования.</p>
<h2 id="heading-2-4">Системное тестирование</h2>
<p>Следующий уровень — это системное тестирование. Оно выполняется для всей системы и проверяет функциональные и нефункциональные требования.</p>
<p>Оба рассмотренных выше примера закончатся системным тестированием:</p>
<ul>
<li>В примере с велосипедом мы сядем на него и попробуем поехать. Если получится, значит велосипед работает как система в целом — функциональный системный тест пройден</li>
<li>В примере с корзиной мы зайдем на сайт, добавим несколько товаров в корзину и проверим, как отображается сумма заказа. Если сумма верна и видна в интерфейсе, то — функциональный системный тест пройден</li>
</ul></div><div style="margin-block:var(--mantine-spacing-xl)" class=""><h2 style="--title-fw:var(--mantine-h2-font-weight);--title-lh:var(--mantine-h2-line-height);--title-fz:var(--mantine-h2-font-size);margin-bottom:var(--mantine-spacing-md)" class="m_8a5d1357 mantine-Title-root" data-order="2">Рекомендуемые программы</h2><style data-mantine-styles="inline">.__m__-_R_2mremqrdub_{--carousel-slide-gap:var(--mantine-spacing-xs);--carousel-slide-size:70%;}@media(min-width: 36em){.__m__-_R_2mremqrdub_{--carousel-slide-gap:var(--mantine-spacing-xl);--carousel-slide-size:50%;}}</style><div style="--carousel-control-size:calc(2.5rem * var(--mantine-scale));--carousel-controls-offset:var(--mantine-spacing-sm);margin-bottom:var(--mantine-spacing-lg);padding-block:var(--mantine-spacing-sm);background:var(--app-color-surface)" class="m_17884d0f mantine-Carousel-root responsiveClassName" data-orientation="horizontal" data-include-gap-in-size="true"><div class="m_39bc3463 mantine-Carousel-controls" data-orientation="horizontal"><button class="mantine-focus-auto m_64f58e10 mantine-Carousel-control m_87cf2631 mantine-UnstyledButton-root" type="button" data-inactive="true" data-type="previous" tabindex="-1"><svg viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg" style="transform:rotate(90deg);width:calc(1rem * var(--mantine-scale));height:calc(1rem * var(--mantine-scale));display:block"><path d="M3.13523 6.15803C3.3241 5.95657 3.64052 5.94637 3.84197 6.13523L7.5 9.56464L11.158 6.13523C11.3595 5.94637 11.6759 5.95657 11.8648 6.15803C12.0536 6.35949 12.0434 6.67591 11.842 6.86477L7.84197 10.6148C7.64964 10.7951 7.35036 10.7951 7.15803 10.6148L3.15803 6.86477C2.95657 6.67591 2.94637 6.35949 3.13523 6.15803Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg></button><button class="mantine-focus-auto m_64f58e10 mantine-Carousel-control m_87cf2631 mantine-UnstyledButton-root" type="button" data-inactive="true" data-type="next" tabindex="-1"><svg viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg" style="transform:rotate(-90deg);width:calc(1rem * var(--mantine-scale));height:calc(1rem * var(--mantine-scale));display:block"><path d="M3.13523 6.15803C3.3241 5.95657 3.64052 5.94637 3.84197 6.13523L7.5 9.56464L11.158 6.13523C11.3595 5.94637 11.6759 5.95657 11.8648 6.15803C12.0536 6.35949 12.0434 6.67591 11.842 6.86477L7.84197 10.6148C7.64964 10.7951 7.35036 10.7951 7.15803 10.6148L3.15803 6.86477C2.95657 6.67591 2.94637 6.35949 3.13523 6.15803Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg></button></div><div class="m_a2dae653 mantine-Carousel-viewport" data-type="media"><div class="m_fcd81474 mantine-Carousel-container __m__-_R_2mremqrdub_" data-orientation="horizontal"><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/programs/qa-engineer?promo_name=programs_list&promo_position=course&promo_creative=catalog_card&promo_type=card" target="_blank"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><div style="--group-gap:calc(0.25rem * var(--mantine-scale));--group-align:center;--group-justify:flex-start;--group-wrap:nowrap" class="m_4081bf90 mantine-Group-root"><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">4 месяца</span><span class="mantine-focus-auto m_b6d8b162 mantine-Text-root">·</span><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">С нуля</span></div><p style="margin-bottom:var(--mantine-spacing-sm);font-size:var(--mantine-font-size-h5);font-weight:bold" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Инженер по ручному тестированию</p><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Изучите виды тестирования, тест-кейсы, DevTools, Postman, SQL, Git и HTTP/HTTPS.</p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Mzk1MCwicHVyIjoiYmxvYl9pZCJ9fQ==--4a16fe638654fb8d5ae09d7e8ab8e16ff228214f/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Bug%20fixing-amico.png" alt="Инженер по ручному тестированию" loading="eager"/></div><div style="--group-gap:var(--mantine-spacing-md);--group-align:end;--group-justify:space-between;--group-wrap:wrap;margin-top:var(--mantine-spacing-xs)" class="m_4081bf90 mantine-Group-root"><p style="font-size:var(--mantine-font-size-xl)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">от 3 368 ₽</p><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Посмотреть →</p></div></div></div></a></div></div><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/courses?promo_name=programs_list&promo_position=course&promo_creative=catalog_card&promo_type=card"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><h2 style="--title-fw:var(--mantine-h2-font-weight);--title-lh:var(--mantine-h2-line-height);--title-fz:var(--mantine-h2-font-size);margin-bottom:var(--mantine-spacing-md);font-size:var(--mantine-font-size-h3)" class="m_8a5d1357 mantine-Title-root" data-order="2" data-responsive="true">Каталог</h2><p style="margin-bottom:auto" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Полный список доступных курсов по разным направлениям</p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="/vite/assets/development-BVihs_d5.png" alt="Orientation"/></div></div></div></a></div></div></div></div></div></div></div></div></div><style data-mantine-styles="inline">.__m__-_R_1bdub_{--col-flex-grow:auto;--col-flex-basis:8.333333333333334%;--col-max-width:8.333333333333334%;}@media(min-width: 48em){.__m__-_R_1bdub_{--col-flex-grow:auto;--col-flex-basis:16.666666666666668%;--col-max-width:16.666666666666668%;}}</style><div style="min-width:0rem;height:100%;min-height:0rem" class="m_96bdd299 mantine-Grid-col __m__-_R_1bdub_"><div style="margin-inline:var(--mantine-spacing-xs)" class="mantine-visible-from-sm"><a style="--button-color:var(--mantine-color-white);margin-bottom:var(--mantine-spacing-lg);text-decoration:none" class="mantine-focus-auto m_849cf0da mantine-focus-auto m_77c9d27d mantine-Button-root m_87cf2631 mantine-UnstyledButton-root m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/courses/testing-phase/lessons/testing-system/finish_unit?unit=theory" data-disabled="true" data-block="true" disabled=""><span class="m_80f1301b mantine-Button-inner"><span class="m_811560b9 mantine-Button-label"><span style="margin-inline-end:var(--mantine-spacing-xs)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Дальше</span>→</span></span></a><a style="padding-inline:0rem" class="mantine-focus-auto m_f0824112 mantine-NavLink-root m_87cf2631 mantine-UnstyledButton-root"><span class="m_690090b5 mantine-NavLink-section" data-position="left"><div style="--ti-size:var(--ti-size-sm);--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent" data-size="sm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-list-numbers "><path d="M11 6h9"></path><path d="M11 12h9"></path><path d="M12 18h8"></path><path d="M4 16a2 2 0 1 1 4 0c0 .591 -.5 1 -1 1.5l-3 2.5h4"></path><path d="M6 10v-6l-2 2"></path></svg></div></span><div class="m_f07af9d2 mantine-NavLink-body"><span class="m_1f6ac4c4 mantine-NavLink-label">Навигация по теме</span><span class="m_57492dcc mantine-NavLink-description">Теория</span></div><span class="m_690090b5 mantine-NavLink-section" data-position="right"></span></a><div style="margin-block:var(--mantine-spacing-lg)" class="m_3eebeb36 mantine-Divider-root" data-orientation="horizontal" role="separator"></div><div style="margin-block:var(--mantine-spacing-lg)" class=""><div style="justify-content:space-between;margin-bottom:calc(0.1875rem * var(--mantine-scale));color:var(--mantine-color-dimmed);font-size:var(--mantine-font-size-xs)" class="m_8bffd616 mantine-Flex-root __m__-_R_qimrbdub_"><p style="font-size:var(--mantine-font-size-xs)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Завершено</p><p style="font-size:var(--mantine-font-size-xs)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">0 / 7</p></div><div style="--progress-size:var(--progress-size-sm)" class="m_db6d6462 mantine-Progress-root" data-size="sm"><div style="--progress-section-size:0%;--progress-section-color:var(--mantine-color-gray-filled)" class="m_2242eb65 mantine-Progress-section" role="progressbar" aria-valuemax="100" aria-valuemin="0" aria-valuenow="0" aria-valuetext="0%"></div></div></div><button style="padding-inline:0rem" class="mantine-focus-auto m_f0824112 mantine-NavLink-root m_87cf2631 mantine-UnstyledButton-root" type="button"><span class="m_690090b5 mantine-NavLink-section" data-position="left"><div style="--ti-size:var(--ti-size-sm);--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent" data-size="sm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-message "><path d="M8 9h8"></path><path d="M8 13h6"></path><path d="M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3h12"></path></svg></div></span><div class="m_f07af9d2 mantine-NavLink-body"><span class="m_1f6ac4c4 mantine-NavLink-label">Обсуждения (архив)</span><span class="m_57492dcc mantine-NavLink-description"></span></div></button><div style="--toc-bg:var(--mantine-color-blue-light);--toc-color:var(--mantine-color-blue-light-color);--toc-size:var(--mantine-font-size-sm);--toc-radius:var(--mantine-radius-sm);margin-top:var(--mantine-spacing-xl)" class="m_bcaa9990 mantine-TableOfContents-root" data-variant="light" data-size="sm"></div></div><div class="mantine-hidden-from-sm"><div style="--stack-gap:0rem;--stack-align:stretch;--stack-justify:flex-start" class="m_6d731127 mantine-Stack-root"><a style="--button-color:var(--mantine-color-white);margin-bottom:var(--mantine-spacing-xs);padding:0rem;text-decoration:none" class="mantine-focus-auto m_849cf0da mantine-focus-auto m_77c9d27d mantine-Button-root m_87cf2631 mantine-UnstyledButton-root m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/courses/testing-phase/lessons/testing-system/finish_unit?unit=theory" data-disabled="true" data-block="true" disabled=""><span class="m_80f1301b mantine-Button-inner"><span class="m_811560b9 mantine-Button-label">→</span></span></a><button style="--ai-size:var(--ai-size-sm);--ai-bg:transparent;--ai-hover:var(--mantine-color-indigo-light-hover);--ai-color:var(--mantine-color-indigo-light-color);--ai-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;padding-block:var(--mantine-spacing-lg);color:inherit;width:100%" class="mantine-focus-auto m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="subtle" data-size="sm" data-disabled="true" type="button" disabled=""><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-list-numbers "><path d="M11 6h9"></path><path d="M11 12h9"></path><path d="M12 18h8"></path><path d="M4 16a2 2 0 1 1 4 0c0 .591 -.5 1 -1 1.5l-3 2.5h4"></path><path d="M6 10v-6l-2 2"></path></svg></span></button><button style="--ai-size:var(--ai-size-sm);--ai-bg:transparent;--ai-hover:var(--mantine-color-indigo-light-hover);--ai-color:var(--mantine-color-indigo-light-color);--ai-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;padding-block:var(--mantine-spacing-lg);color:inherit;width:100%" class="mantine-focus-auto mantine-active m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="subtle" data-size="sm" type="button"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-message "><path d="M8 9h8"></path><path d="M8 13h6"></path><path d="M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3h12"></path></svg></span></button></div></div></div></div></div></div></div>
</main>
<footer class="bg-dark fw-light text-light px-3 py-5">
<div class="row small">
<div class="col-12 col-sm-6 col-md-3">
<div class="h5 mb-3">Хекслет</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/about">О нас</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/testimonials">Отзывы</a>
</li>
<li>
<span class="nav-link link-light py-1 ps-0 external-link" data-href="https://b2b.hexlet.io" role="button">Корпоративное обучение</span>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/blog">Блог</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/qna">Вопросы и ответы</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/glossary">Глоссарий</a>
</li>
<li>
<span class="nav-link link-light py-1 ps-0 external-link" data-href="https://help.hexlet.io" data-target="_blank" role="button">Справка</span>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" target="_blank" rel="noopener noreferrer" href="/map">Карта сайта</a>
</li>
</ul>
</div>
<div class="col-12 col-sm-6 col-md-3">
<div class="h5 fw-normal mb-3">Направления</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_devops">DevOps
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_data_analytics">Аналитика
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_backend_development">Бэкенд
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_programming">Программирование
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_testing">Тестирование
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_front_end_dev">Фронтенд
</a></li>
</ul>
</div>
<div class="col-12 col-sm-6 col-md-3">
<div class="h5">Профессии</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/devops-engineer-from-scratch">DevOps-инженер с нуля</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/go">Go-разработчик</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/java">Java-разработчик</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/python">Python-разработчик </a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/data-analytics">Аналитик данных</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/qa-engineer">Инженер по ручному тестированию</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/php">РНР-разработчик</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/frontend">Фронтенд-разработчик</a>
</li>
</ul>
</div>
<div class="col-12 col-sm-6 col-md-3">
<div class="h5">Навыки</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/python-django-developer">Django</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/docker">Docker</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/php-laravel-developer">Laravel</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/postman">Postman</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/js-react-developer">React</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/js-rest-api">REST API в Node.js</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/spring-boot">Spring Boot</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/typescript">Typescript</a>
</li>
</ul>
</div>
</div>
<hr>
<div class="row">
<div class="col-12 col-sm-4 col-md-2">
<div class="fs-4">
<ul class="list-unstyled d-flex">
<li class="me-3">
<a aria-label="Telegram" target="_blank" class="link-light" rel="noopener noreferrer nofollow" href="https://t.me/hexlet_ru"><span class="bi bi-telegram"></span>
</a></li>
<li>
<a aria-label="Youtube" target="_blank" class="link-light" rel="noopener noreferrer nofollow" href="https://www.youtube.com/user/HexletUniversity"><span class="bi bi-youtube"></span>
</a></li>
</ul>
</div>
<div class="mb-2 d-flex flex-column">
<a class="link-light text-decoration-none" rel="nofollow" href="mailto:support@hexlet.io">support@hexlet.io</a>
<a class="link-light text-decoration-none py-2" target="_blank" href="https://t.me/hexlet_help_bot">t.me/hexlet_help_bot</a>
</div>
<ul class="list-unstyled d-flex">
<li class="me-3">
<span class="link-light text-decoration-none opacity-50 x-font-size-18 external-link" rel="nofollow" data-href="https://hexlet.io/locale/switch?new_locale=en" data-target="_self" role="button"><span class="my-auto">EN</span>
</span></li>
<li class="me-3">
<span class="link-light text-decoration-none opacity-50 x-font-size-18 opacity-100 external-link" rel="nofollow" data-href="https://ru.hexlet.io/locale/switch?new_locale=ru" data-target="_self" role="button"><span class="my-auto">RU</span>
</span></li>
<li class="me-3">
<span class="link-light text-decoration-none opacity-50 x-font-size-18 external-link" rel="nofollow" data-href="https://kz.hexlet.io/locale/switch?new_locale=kz" data-target="_self" role="button"><span class="my-auto">KZ</span>
</span></li>
</ul>
</div>
<div class="col-12 col-sm-4 col-md-3">
<ul class="list-unstyled fs-4">
<li class="mb-3">
<a class="link-light text-decoration-none" href="tel:8%20800%20100%2022%2047">8 800 100 22 47</a>
<span class="d-block opacity-50 small">бесплатно по РФ</span>
</li>
<li>
<a class="link-light text-decoration-none" href="tel:%2B7%20495%20085%2021%2062">+7 495 085 21 62</a>
<span class="d-block opacity-50 small">бесплатно по Москве</span>
</li>
</ul>
</div>
<div class="col-12 col-sm-4 col-md-3">
<div class="small mb-3">Образовательные услуги оказываются на основании Л035-01298-77/01989008 от 14.03.2025</div>
<ul class="list-unstyled small">
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/legal">Правовая информация</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/offer">Оферта</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/license">Лицензия</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/contacts">Контакты</a>
</li>
</ul>
</div>
<div class="col-12 col-sm-12 col-md-4 small">
<div class="mb-2">
<div>ООО «<a href="/" class="text-decoration-none link-light">Хекслет Рус</a>»</div>
<div>108813 г. Москва, вн.тер.г. поселение Московский,</div>
<div>г. Московский, ул. Солнечная, д. 3А, стр. 1, помещ. 20Б/3</div>
<div>ОГРН 1217300010476</div>
<div>ИНН 7325174845</div>
</div>
<hr>
<div>АНО ДПО «<a href="/" class="text-decoration-none link-light">Учебный центр «Хекслет</a>»</div>
<div>119331 г. Москва, вн. тер. г. муниципальный округ</div>
<div>Ломоносовский, пр-кт Вернадского, д. 29</div>
<div>ОГРН 1247700712390</div>
<div>ИНН 7736364948</div>
</div>
</div>
</footer>
<div id="root-assistant-offcanvas"></div>
<script src="/vite/assets/assistant-Bukl1lYy.js" crossorigin="anonymous" type="module"></script><link rel="modulepreload" href="/vite/assets/chunk-DsPFFUou.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/init-BrRXra1y.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/ErrorFallbackBlock-naDSYSy9.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/MarkdownBlock-DbyKWoR_.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/gon-D3e4yh1x.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/mantine-CGMYrt2Y.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/shiki-V011pkdv.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/utils-DRqSHbQE.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/routes-CCH8ilKF.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/lib-XR8Qr8kR.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/dist-GCHh59xr.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Box-B5-OOzBf.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/notifications.store-C-3AFSMn.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/useIsomorphicEffect-HJ6VK0D3.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/lib-KSp6QbZ0.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/axios-BEvgo0ym.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/classnames-l6ipYlLR.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/dayjs.min-BkKovM-s.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/debounce-jMQ_Cf4f.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/i18next-BlSq9s7B.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/client-U9M77rxp.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-dom-DaLxUz_h.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/useTranslation-Bx1Cdrkz.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/compiler-runtime-6XxiPFnt.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/jsx-runtime-CwjcCKJi.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-CkL4ZRHB.js" as="script" crossorigin="anonymous">
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v67327c56f0bb4ef8b305cae61679db8f1769101564043" integrity="sha512-rdcWY47ByXd76cbCFzznIcEaCN71jqkWBBqlwhF1SY7KubdLKZiEGeP7AyieKZlGP9hbY/MhGrwXzJC/HulNyg==" data-cf-beacon='{"version":"2024.11.0","token":"d11015b65d11429ea6b4a2ef37dd7e0b","server_timing":{"name":{"cfCacheStatus":true,"cfEdge":true,"cfExtPri":true,"cfL4":true,"cfOrigin":true,"cfSpeedBrain":true},"location_startswith":null}}' crossorigin="anonymous"></script>
</body>
</html>