По вашему запросу ничего не найдено :(
Убедитесь, что запрос написан правильно, или посмотрите другие наши статьи:
img
Процесс анализа программного кода должен быть максимально автоматизирован. Когда вы создаете запрос на включение изменений, как минимум, вам нужно запустить модульные тесты и статический анализ программного кода в функциональной ветке. Средства автоматизации могут многое рассказать о качестве кода: метрики, покрытие кода модульными тестами, обнаружение дублированных строк и т.д. Однако есть как минимум 50 вещей, которые нельзя проверить автоматически. Они нуждаются во внимательном взгляде опытного проверяющего (это дает нам хоть какую-то надежду на то, что роботы не заменят разработчиков в ближайшем будущем). Требования Программный код реализует все функциональные требования, которые необходимы заказчику? Программный код удовлетворяет всем нефункциональным требованиям, таким как производительность и безопасность? Если нефункциональные требования не были упомянуты заказчиком, то этот вопрос необходимо уточнить у проектировщика или у самого заказчика.  Условия сопровождения Помещены ли все интерфейсы, классы и т.д. на соответствующий прикладной уровень в соответствии с архитектурой  Onion/Clean ? Не изобретаете ли вы колесо, когда пишете программный код? Можно ли его заменить чем-то, что уже существует и что предоставляет какая-либо сторонняя библиотека?  Есть ли уже реализованная логика или какие-то ее фрагменты в кодовой базе? Правильно ли была выбрана область жизненного цикла для интерфейса и реализации в контейнере внедрения зависимостей? Являются ли реализованные функции детерминированными (то есть всегда ли они выдают один и тот же результат для одних и тех же входных данных)? Все ли зависимости явно внедряются через конструктор типов? Есть ли сильная связанность между классами, которая может затруднить повторное использование кода? Используются ли  объекты-значения вместо элементарных типов данных для того, чтобы избежать проблемы одержимости элементарными типами? Соответствуют ли реализованные компоненты, такие как функции, классы, интерфейсы и модули,  принципу единственной обязанностей ? Расширяются ли существующие функциональные возможности при помощи декораторов, технологий аспектно-ориентированного программирования (принципа открытия-закрытия) или они модифицируются на месте? Правильно ли реализованы механизмы синхронизации потоков при доступе к объектам-одиночкам в веб-приложениях? Используются ли по возможности  неизменяемые типы данных вместо изменяемых для того, чтобы избежать побочных эффектов? Добавлена ли функция ведения журнала с верными  уровнями ведения протокола в основные места кода, которые требуют отслеживания? Производительность Правильно ли были выбраны  структуры данных ? Например, используется ли структура Hashtable вместо массива, когда нужно часто искать значения, для того, чтобы избежать линейного поиска? Распараллелены ли длительные операции между всеми доступными ядрами для того, чтобы использовать ресурсы компьютера максимально эффективного? Выполняет ли программный код большое количестве  операций по выделению памяти для объектов в куче, оказывая тем самым дополнительную нагрузку на программу сборки мусора? Кэшируются ли данные, которые были считаны из базы данных, локально или в удаленном кэше? Сколько раз текущий код обращается к базе данных? Возможно стоит получить все данные за одно или несколько обращений? Выполняет ли код все обращения к базе данных, ввод-вывод и другие блокирующие вызовы асинхронно? Использует ли код  пул потоков по максимуму вместо того, чтобы создавать новые потоки? Правильно ли выбран баланс между  нормализацией и  денормализацией при создании дополнительных таблиц базы данных? Правильно ли добавляются или исправляются индексы, если запрос на включение изменений содержит новые SQL-запросы? Возникает ли  проблема с N+1 запросами при извлечении данных из базы данных при помощи фреймворка ORM? Установлен ли правильный уровень изоляции транзакций в хранимых процедурах? Возвращают ли SQL-запросы избыточные данные из базы данных, которые не требуются для кода приложения? Используется ли что-то вроде  SELECT * или что-то подобное? Модульное и интеграционное тестирование Полностью ли модульные тесты покрывают дополнительную логику? При появлении исправлений в логике, появляются ли изменения в соответствующем модульном тесте? Всегда ли все реализованные модульные или другие виды тестов ведут себя детерминировано? Например, приостанавливают ли они выполнение потока на какой-то определенный период времени перед утверждением (что по своей сути является ошибочным шаблоном)?  Все ли модульные тесты реализованы в соответствии с принципами  F.I.R.S.T. ? Есть ли какие-либо признаки проблем в модульном тестировании, такие как проблемы с  логикой проверки условий ,  рулеткой с утверждениями ,  дублированием утверждений и другие? Добавлен ли интеграционный тест, как минимум, для happy-path-сценария (сценария счастливого пути) реализованной функции? Все ли зависимости тестируемого объекта имитируются для того, чтобы модульный тест случайно не превратился в интеграционный и не выполнился быстрее положенного? Изолированы ли модульные и интеграционные тесты друг от друга? Конечные точки API Выбираются ли HTTP-команды, такие как  GET, POST, PUT, DELETE и другие, в соответствии с действием их конечной точки? Отвечает ли каждая конечная точка API за выполнение лишь одной бизнес-операции? Или все же нескольких? Возвращает ли конечная точка API правильный код состояния? Например, не возвращает ли она код 401 вместо 500 при несанкционированном запросе? Сжимаются ли объемные ответы перед их отправкой вызывающей стороне? Защищены ли конечные точки API политиками аутентификации и авторизации? Позволяет ли API, который возвращает большой список объектов, фильтровать его и разбивать на страницы? Является ли конечная точка API GET идемпотентной? Используются ли имена существительные вместо глаголов в именах конечных точек API? Критические изменения Имеются ли в конечной точке API такие критические изменения, как переименование API, удаление или переименование его параметров? Имеются ли критические изменения в полезных данных сообщения (в случае, если используется брокер сообщений), например, удаление или переименование его свойств? Повлияют ли такие изменения в схеме базы данных, как удаление столбцов или таблиц, на другие службы системы? Системная среда Насколько загружен ЦП и сколько оперативной памяти потребляет код при выполнении запроса на включение изменений? Будет ли в средах, в которых будет развернут код (среда тестирования, среда приёмочного пользовательского тестирования, производственная среда), достаточно мощный процессор и достаточный объем оперативной памяти для эффективного выполнения кода? Будет ли реализованная логика, алгоритмы, структуры данных и т.д. работать достаточно быстро на большом наборе данных, который может быть в производственной среде? Документация Была ли изменена документация для того, чтобы отразить новые изменения программного кода (документация API, документация по структуре, проектная документация)? Создается ли тикет  технических недоработок , если запрос на внесение изменений содержит неэффективный или «грязный» код, который сейчас невозможно перестроить из-за недостаточного количества времени? Заключение Количество пунктов, на которых проверяющий должен заострить свое внимание, зависит от конкретного проекта и даже от конкретного запроса на внесение изменений. Ваш с коллегами мозговой штурм (если вы примите во внимание вышеприведенные пункты) может значительно снизить риск того, что вы забудете о чем-то важно при анализе программного кода.   
img
Любое крупное приложение должно сопровождаться несколькими наборами тестов, с помощью которых можно проверить его стабильность и производительность.  Существует большое количество различных тестов, каждый из которых имеет свое назначение и охватывает определенные аспекты приложения. Именно поэтому, когда вы тестируете свое приложение, вы должны убедиться, что ваш набор тестов сбалансирован и охватывает все аспекты.  Однако есть один тип тестов, который разработчики часто предпочитают другим, и поэтому им часто злоупотребляют. Этот «сквозное тестирование» (E2E - end-to-end testing).  Что такое сквозное тестирование? Для тех, кто только начал штурмовать мир тестирования программного обеспечения, E2E-тестирование - это проверка вашего приложения от начала до конца вместе со всеми его зависимостями. При проведении E2E-тестировании вы создаете среду, которая будет идентична той, которую будут использовать реальные пользователи приложения. А затем вы тестируете все действия, которые могут выполнять пользователи в вашем приложении. С помощью сквозного тестирования вы проверяете весь рабочий поток целиком, например, вход на веб-сайт или покупку товара в интернет-магазине.   Если вы будете злоупотреблять E2Е-тестирование, то вы перевернете пирамиду тестирования. Я в такой ситуации был. В одном из своих проектов я планировал охватить большую часть приложения Е2Е-тестами или, что еще хуже, воспользоваться лишь один Е2Е-тест. К счастью, я передумал. Так вот, теперь я хочу поделиться с вами тем, что заставило меня передумать.  Почему не нужно пренебрегать пирамидой тестирования? Хаотично написанные тесты сначала могут показаться вполне пригодными, но в конце концов они таковыми не окажутся.  Мы пишем тесты для того, чтобы выиграть больше времени, и мы делаем это с помощью методы и средства автоматизации тестирования. Конечно, можно было бы самостоятельно открывать приложения и тестировать их вручную. Если бы это нужно было сделать однократно, то проблем не было бы. Но так бывает крайне редко.  Программное обеспечение постоянно обновляется. Поэтому необходимо проводить регулярные тестирования для того, чтобы оставаться в курсе последних событий. Вы, конечно, можете ежедневно запускать все тесты вручную при каждом обновлении приложения. Но если вы один раз напишите набор тестов, а затем будете его запускать каждый раз, когда нужно будет протестировать какой-то из аспектов приложения, то вы сэкономите много времени.  У каждого теста есть свое назначение. Если вы будете использовать их не по назначению, то они могут вам больше навредить, чем помочь. Это связано с тем, что в итоге вы потратите больше времени на то, чтобы написать эти тесты, и на их сопровождение, чем на разработку самого приложения. Иными словами, вы останетесь без одного из самых больших преимуществ автоматизированного тестирования.  Хорошее начало – придерживаться пирамиды тестирования. Она поможет вам определить правильный баланс в тестированиях. Эта пирамида является отраслевым стандартом и используется с середины 2000-х годов по сей день, так как все еще считается эффективной.  Значит ли это, что разработчики никогда не пренебрегают этой пирамидой? Не совсем. Иногда пирамида бывает перевернутой, где большую часть тестов составляют Е2Е, а иногда она бывает похожа на песочные часы, где очень много юнит- и Е2Е-тестов, но с очень мало интеграционных тестов.  Три уровня пирамиды тестирования Как правило, пирамида тестирования имеет три уровня: юнит-тесты, интеграционные тесты и сквозные тесты.  Юнит-тесты Юнит-тесты, или модульные тесты, делают акцент на самых маленьких единицах кода, таких как функции и классы.  Они короткие и не зависят ни от каких-либо внешних пакетов, библиотек и классов. В противном случае, в ход идет имитированная реализация.  Если юнит-тест дает сбой, то найти причину проблемы не так сложно. Они также имеют небольшой диапазон тестирования, что делает их простыми в написании, быстрыми в работе и легкими в сопровождении.  Интеграционные тесты Интеграционные тесты делают акцент на взаимодействии между двумя отдельными объектами. Как правило, они работают медленнее, потому что они требуют более серьезной настройки.  Если интеграционные тесты проваливаются, то найти проблему немного сложнее, так как диапазон ошибок больше. Они также более сложные в написании и сопровождении, в основном потому, что они требуют более продвинутое имитирование и расширенную область тестирования.  Сквозные тесты И наконец, сквозные тесты, или E2E-тесты. Они делают акцент на рабочих потоках, от самых простых до самых сложных. Эти тесты можно рассматривать как многоэтапные интеграционные тесты.  Они самые медленные, потому что они подразумевают сборку, развертывание, запуск браузера и выполнение действий внутри приложения.  Если сквозные тесты проваливаются, то найти проблему часто бывает очень сложно, потому что диапазон ошибок увеличивается до всего приложения. В принципе, по пути могло сломаться все что угодно. Это, безоговорочно, самый сложный тип тестов для написания и сопровождения (из трех типов, которые рассмотрели здесь) из-за огромного диапазона тестирования и из-за того, что они охватывают все приложение.  Надеюсь, теперь вы понимаете, почему пирамида тестирования была спроектирована именно таким образом. Снизу-вверх каждый уровень тестирования говорит о снижении скорости и увеличении диапазона и сложности и усложнении сопровождения.  Именно поэтому важно не забывать о том, что E2E-тестирование не может полностью заменить другие методы – оно лишь предназначено для расширения их возможностей. Назначение Е2Е-тестирования четко определено, и тесты не должны выходить за его границы.  В идеале тесты должны выявлять ошибки настолько близко к корню пирамиды, насколько возможно. Е2Е-тест предназначен для проверки кнопок, форм, изменений, ссылок, внешних процессов и вообще всех функций рабочего потока. Тестирование с кодом VS codeless-тестирование В целом, существует два типа тестирования: ручное и автоматизированное тестирование. Это значит, что мы можем проводить тестирования либо вручную, либо с помощью сценариев.  Чаще используют именно второй метод. Но и автоматизированное тестирование можно разделить на две части: тестирование с кодом и codeless-тестирование.  Тестирование с кодом Когда вы проводите тестирование с кодом, вы используете фреймворки, которые могут автоматизировать браузеры. Один из самых популярных инструментов – это Selenium, но я больше предпочитаю использовать в своих проектах Cypress (только для JavaScript). И тем не менее, работают они практически одинаково.  По сути, с помощью таких инструментов вы моделируете веб-браузеры и даете им указания для выполнения различные действия в вашем целевом приложении. После чего вы проверяете, отреагировало ли ваше приложение на соответствующие действия. Это простой пример имитации, взятый из документации Cypress. Я привел его, чтобы вы могли лучше понять, как работает этот инструмент: Давайте посмотрим, что тут происходит: Допустим, пользователь посещает сайт  https://example.cypress.io   Когда она нажимает на ссылку с пометкой type, URL-адрес должен добавить /commands/actions Если он вводит «fake@email.com» в поле ввода .action-email, тогда ввод .action-email принимает значение «fake@email.com». Codeless-тестирование В ситуации с codeless-тестированием вы используете фреймворки на базе искусственного интеллекта, которые запоминают ваши действия. И основываясь на некоторой дополнительной информации, они проверяют, отвечает ли ваше целевое приложение на действия должным образом.  Эти инструменты часто выглядят как малокодовые платформы для разработки, где вы перемещаете различные панели. Один из таких инструментов – TestCraft, codeless-решение, разработанное на платформе Selenium. Как правило, эти инструменты стоят дороже из-за того, то такие функции, как создание, сопровождение и запуск тестов выполняются с помощью простого перемещения панелей, а также из-за того, что для проведения тесто не нужно уметь писать программный код. Но я упомянул здесь про TestCraft, потому что у них есть бесплатная версия, которая включает в себя практически все.  Конечно, если речь идет о скорости и деньгах, то codeless-решение может оказаться вам больше по душе, но они все еще достаточно новые. Поэтому они пока не могут иметь ту сложность наборов тестов, которой можно достичь, написав код самостоятельно.  Если в целевом приложении есть очень сложные рабочие потоки, которые включают в себя несколько подвижных частей, то вам больше подойдет классический вариант тестирования. Но если сложных потоков нет, то вы можете воспользоваться codeless-решением.  Подведение итогов Написание тестов – обязательное требование для любого приложения. Если вы будете следовать всем правилам и писать наборы тестов исходя из их типов, то они только улучшат ваше приложение, а также их будет довольно просто написать и сопровождать.  Использовать сквозные тесты, как и любые другие, следует только для того, для чего они предназначены. Они предназначены для тестирования рабочего потока приложения от начала и до конца путем воспроизведения реальных пользовательских сценариев. Но помните, что большинство ошибок следует выявлять как можно ближе к корню.   
img
Ищете возможность анализировать сетевой трафик/отправлять его на систему записи телефонных разговоров? Изи. Коммутаторы Cisco (да и многие другие) дают возможность копировать пакеты с определенного порта или VLAN и отправлять эти данные на другой порт для последующего анализа (Wireshark, например). Кстати, этот функционал полезен при использовании IDS (Intrusion Detection System) систем в целях безопасности. Мы уже рассказывали теоретические основы SPAN/RSPAN, поэтому, сегодняшняя статья будет посвящена практике настройке. Про настройку SPAN В рамках обычной SPAN сессии захват (копирование) сетевого трафика происходит с порта источника (source port) и отправляется на порт назначения (destination port). Обратите внимание на пример ниже: мы сделаем SPAN – сессию с порта fa 0/1 и отправим данные на порт fa 0/5: Важно! SPAN – сессия может работать только в рамках одного коммутатора (одного устройства). Конфигурация: switch# configure terminal switch(config)# monitor session 1 source interface fa0/1 switch(config)# monitor session 1 destination interface fa0/5 Просто, не правда ли? В рамках данной конфигурации весь трафик с порта fa 0/1 будет скопирован на порт fa 0/5. Интереснее: пример RSPAN Идем вперед. Более продвинутая реализация зеркалирования трафика это RSPAN (Remote SPAN). Эта фича позволяет вам зеркалировать трафик между различными устройствами (коммутаторами) по L2 через транковые порты. Копия трафика будет отправляться в удаленный VLAN между коммутаторами, пока не будет принята на коммутаторе назначения. На самом деле, это легко. Давайте разберемся на примере: как показано на рисунке, мы хотим копировать трафик с коммутатора №1 (порт fa 0/1) и отправлять трафик на коммутатор №2 (порт fa 0/5). В примере показано прямое транковое подключение между коммутаторами по L2. Если в вашей сети имеется множество коммутаторов между устройствами источника и назначения – не проблема. Конфигурация: //Настройки на коммутаторе источнике switch_source# config term switch_source(config)# vlan 100 //Создаем Remote VLAN на первом коммутаторе (в который будем передавать данные с source порта) switch_source(config-vlan)# remote span switch_source(config-vlan)# exit switch_source(config)# monitor session 10 source interface fa0/1 switch_source(config)# monitor session 10 destination remote vlan 100 //Настройки на коммутаторе получателе switch_remote# config term switch_remote(config)# vlan 100 //Создаем Remote VLAN на втором (удаленном) коммутаторе (в который будем передавать данные с source влана уже на порт назначения) switch_remote(config-vlan)# remote span switch_remote(config-vlan)# exit switch_remote(config)# monitor session 11 source remote vlan 100 switch_remote(config)# monitor session 11 destination interface fa0/5 Таким образом, весь трафик с интерфейса fa 0/1 на локальном коммутаторе (источнике) будет отправлен в vlan 100, и, когда коммутатор получатель (remote) получит данные на 100 VLAN он отправит их на порт назначения fa 0/5. Такие дела. Party Hard: разбираемся с ERSPAN ERSPAN (Encapsulated Remote Switched Port Analyzer) - фича, которая используется для копирование трафика в L3 сетях. В основе работы механизма лежит GRE инкапсуляция. Как показано ниже, между коммутатором источником и коммутатором получателем устанавливается GRE – туннель (между IP – адресами машин). Опять же, мы хотим отправить трафик с порт fa 0/1 на порт fa 0/5. Конфигурация: //Настройки на коммутаторе источнике switch_source(config)# monitor session 1 type erspan-source switch_source(config-mon-erspan-src)# source interface fa0/1 switch_source(config-mon-erspan-src)# destination switch_source(config-mon-erspan-src-dst)# erspan-id 111 //Это значение должно быть одинаковым на всех устройствах switch_source(config-mon-erspan-src-dst)# ip address 192.168.1.5 //IP - адрес коммутатора получателя switch_source(config-mon-erspan-src-dst)# origin ip address 192.168.2.5 //IP - адрес коммутатора отправителя (источника) //Настройки на коммутаторе получателе switch_remote(config)# monitor session 1 type erspan-destination switch_remote(config-mon-erspan-dst)# destination interface fa0/5 switch_remote(config-mon-erspan-dst)# source switch_remote(config-mon-erspan-dst-src)# erspan-id 111 switch_remote(config-mon-erspan-dst-src)# ip address 192.168.1.5 //IP - адрес коммутатора получателя (назначения) Траблшутинг Мониторинг трафика в указанном VLAN: monitor session 1 source vlan 13 Мониторинг входящего или только исходящего трафика: monitor session 1 source vlan 13 rx/tx Посмотреть конфигурацию сессии зеркалирования: show monitor session 1
ВЕСЕННИЕ СКИДКИ
40%
50%
60%
До конца акции: 30 дней 24 : 59 : 59