Показаны сообщения с ярлыком flowchart. Показать все сообщения
Показаны сообщения с ярлыком flowchart. Показать все сообщения

пятница, 23 августа 2019 г.

Перегрузки

После прочтения статьи "Как спроектировать нагрузочный тест" Кристины Джеквони (Kristin Jackvony) в переводе Ольги Алифановой возникли нижеследующие дополнения.
* Для тестирования нагрузки базы в первую очередь обращаюсь к Explain Plan.
* Далее смотрим на наличие полезных индексов. Очень познавательный рассказ про индексирование есть в "Вся правда об индексах в PostgreSQL" от Олега Бартунова и Александра Короткова.
* Не менее важно использование кэширования. А в области данных вам в помощь станут CRUD матрицы.
* Если можете проверять белый ящик, то обращайте внимание на отсутствие излишних перерисовок интерфейса (Flowchart и Call Tree диаграммы покажут зацикленность и бесполезные повторы).

вторник, 12 февраля 2019 г.

Comments in Loop

Качество продукта начинается с красивых метрик кода. О том, что комментарии к коду только повышают его эффективность, уже говорилось в нескольких моих статьях ("Easy white-box testing", "Качество кода одним числом", "Документор кода или псевдокод"). Хотелось бы их подкрепить результатами исследований. Надеюсь, чарты сильнее убедят ваших программистов вставлять пояснения в код.

Для исследования были взяты две процедуры (с комментариями в цикле cmt_in loop и идентичная без комментариев cmt_no_loop) на PL/SQL Oracle:
  PROCEDURE cmts_in_loop
  IS
    t1 timestamp;
    t2 timestamp;
    l  varchar2(50);
  BEGIN
    t1 := SYSTIMESTAMP;
    FOR i IN 1..1000000 LOOP
      -- 1-st comment line in loop
      l := 'one command line in loop with comments';
      -- 2-nd comment line in loop
    END LOOP;
    t2 := SYSTIMESTAMP;
    dbms_output.put_line('timestamp for mln-loop with 2 comments: ' || to_char(t2 - t1, 'MI:SS.FF5'));
  END;
/
  PROCEDURE cmts_no_in_loop
  IS
    t2 timestamp;
    t3 timestamp;
    l  varchar2(50);
  BEGIN
    t2 := SYSTIMESTAMP;
    FOR i IN 1..1000000 LOOP
      l := 'one command line in loop without comments';
    END LOOP;
    t3 := SYSTIMESTAMP;
    dbms_output.put_line('timestamp for mln-loop without comments: ' || to_char(t3 - t2, 'MI:SS.FF5'));
  END;
/


Визуализируем и вычислим метрики кода в специализированном продукте ClearSQL:
Flowchart - cmts_in_loop
Flowchart - cmts_no_loop
По диаграммам Flowchart видно, что в обеих процедурах одинаковое количество узлов и рёбер, то есть наличие или отсутствие комментариев не влияет на цикломатическую сложность.

Измерение метрик кода дали следующие цифры:
 
Различные цифры в разрезе процедур подсвечены мной красным цветом. За счёт наличия строк-комментариев в первой процедуре вырос Maintainability Index - важная величина кода, которая чем выше, тем лучше код (подробные исследования функции смотрите в "Качество кода одним числом").
Да, идентичная программа с комментариями стоит дороже при изготовлении и поддержке, так как вместе с правкой значимых строк необходимо актуализировать и их примечания. Но это только по меркам компании Conquest Software Solutions, которая "с потолка" взяла формулу и коэффициенты для исчисления Technical Dept.
Описание Technical Dept
А теперь ударный аргумент - время на исполнение цикла.
Дельта выполнений первой и второй процедур 26 раз
Собрав результаты от пары дюжин выполнений, на график была выведена разница времени исполнения цикла с комментариями (cmt_in_loop) и времени выполнения аналогичного цикла, но без строк комментариев (cmt_no_loop). Да, по этому небольшому расхождению слегка заметно, что комментарии затягивают цикл. Но эта гипотеза была разрушена уже на второй сотне экспериментов:
Дельта выполнений первой и второй процедур 201 раз
То есть циклы без комментированных строк крутились дольше! Казалось бы - нонсенс, что увеличение строк в цикле убыстряет его ход, но видимо даже компилятору полезнее иметь код с пояснениями, а не только новичку программисту, правящему легаси.

Так что, решающим аргументом для добавления разъяснений в код стоит рассматривать следующее:
- комментарии не загружают текст, а наоборот помогают читать его;
- блок-схемы процедур "с" и "без" комментариев идентичны;
- комментарии никак не влияют на цикломатическую сложность;
- за счёт строк комментариев легко и быстро увеличить MI, то есть улучшить качество;
- комментарии даже в цикле не замедляют исполнение, а ускоряют его.

О том, сколько строк рабочих и вспомогательных оптимально (3/1) должно быть в коде, читайте в статье "Качество кода одним числом". Метрики кода могут показать общее количество и пропорцию строк, а настраиваемые правила для автоматической проверки выявят места с недоработками. В ClearSQL это называется Code Review Rule Editor, с помощью которого можно добавить пользовательские правила и проверять их в том же автоматическом режиме наряду со встроенными (~200штук).
О том, как проще добавлять пояснения в код, читайте в "Документор кода или псевдокод".

понедельник, 18 июня 2018 г.

Easy "white-box" testing

(Смотрите запись https://vimeo.com/226001966  или читайте текст ниже)

Расскажу о лёгкости тестирования "белым ящиком".
Многие уверены, что проверкой кода должен и может заниматься только высокий профессионал, имеющий опыт написания сложных программ и досконально знающий язык программирования. Но вскоре вы поймёте, что эту работу вполне можно дать вчерашнему школьнику со знаниями Информатики и Мат-Анализа.
Надеюсь, вам известно, что основными причинами серьёзных багов являются элементарные опечатки, недоправки копи-пастов и даже отсутствие кода, поэтому предлагаю проводить тестирование «белого ящика» при помощи утилит аудиторов кода:
* даже юниоры убедятся, что проверка сорсника – это не сложно;
* определим полезные визуализаторы и метрики кода;
* в процессе будут подсказки по выбору и использованию утилит.

Неколько примечаний:
- примеры кода написаны на языке PL/SQL Oracle;
- Все умозаключения по применению основаны на собственном опыте;
- Дабы избежать маркетинговых проблем и не поощрять вашу лень при интернет-поиске, никаких конкретных названий продуктов упомянуто не будет. А также советов, как у программиста взять код для теста, это «интимный» вопрос. Даже профи-аудитору код дают после утряски юридических вопросов. Предположим, что сорсник хотя бы на чтение уже в нашем распоряжении;
- Под юнитом/сорсником/подпрограммой/кодом будем иметь ввиду обычный текстовый файл с листингом программы.


Как работают утилиты, которыми пользуются аудиторы кода:
- Сначала Парсер разбивает текст на строки: значимые (сами команды) и вспомогательные (комментарии, пустые строки);
- Потом Лексер по значимым строкам определяет структуру кода: подпрограммы, команды, параметры и тому подобное;
- Визуализатор генерит диаграммы;
- Анализатор высчитывает метрики кода и по этим данным формирует предупреждения о нарушенных правилах кодирования. Списком таких «нарушений» удобно пользоваться при проведении code review, но не всегда утилиты статического анализа имеют подробные расшифровки и рекомендации по устранению ошибок. Поэтому при подборе утилит обращайте внимание на то, есть ли возможность создать свои правила проверки кода и устанавливать иные лимиты на метрики.


Приведу несколько примеров помощи тестировщику от визуализаторов кода.
Самый простой визуализатор, как ни странно, - комментарии. Их игнорируют программисты, оправдываясь правильно-названными компонентами кода, хотя, не все считают обязательным удалять закомментированные строки кода. А поскольку они не являются полезными комментами, то от них надо избавляться, благо есть система контроля версий. При наличии полезных комментов не так опасно потерять СКВ или баг-трекинговую систему (историю задачи можно восстановить по комментариям).
Если к правильным комментариям добавить специальные теги, то получится документор кода или псевдокод. Когда же чистая выборка документора совпадает с текстом аналитика хотя бы по логичности распределения команд в коде, тестировщик может автоматически закрывать чек-лист про покрытие кодом спецификации задачи. А поскольку некоторые утилиты по комментам псевдокода строят блок-схемы, то сравнение с UML диаграммой аналитика даст объём тех-задания, не покрытого кодом, моментально.
Ясное дело, наличие комментов зависит только от программиста, который не очень-то любит писать обычные тексты, но его можно легко уговорить на ведение комментов, если составлять их как план подпрограммы из текста аналитика, а потом к ним дописывать код. Они помогут следующему кодеру разобраться в программе.
При тестрировании через комментарии, юниору не нужны знания синтаксиса языка, и даже более того – по ним можно изучать программирование.
К слову сказать, крупные компании ведут комментарии кода в обязательном порядке и по своим правилам/шаблонам. Когда же StartUp-у захочется сертифицироваться, то код уже придётся документировать.


Вторая группа визуализаторов, полезных тестировщику, показывает ход программы. Это: блок-схемы, Flowchart, UML диаграммы по готовому листингу.
Мощнейшая утилита из портфеля аудитора! По нарисованному коду, даже без знаний синтаксиса языка, сразу видна масса багов или тем на рефакторинг:
- количество блоков всегда можно подсчитать, и в некоторых утилитах выставить лимит. Если диаграмма большая, то сорсник длинный. А «лапша» всегда была поводом для оптимизации кода;
- находите дубликаты блоков через поиск текста в блоках и подсветку путей, чтобы проверить их на проблемы после копи-паста (недоредактированный код), либо оформить внутреннюю задачу для рефакторинга по выносу повторений в отдельную функцию (повторяющиеся блоки - причина будущих опечаток и недоправок, а унифицированные функции ускоряют правки и переделки);
- сворачиваемость блоков и подсветка определённых путей ("Да", "Нет", "Исключение") более чётко покажут недостаточно обработанные условия и отсутствие кода. А когда фича не дописана, то тестировщику нет смысла тратить время на проверку пустот (сразу возвращайте на доработку);
- мёртвый код ищется два месяца «чёрным ящиком», а при использовании flowchart определяется за пару минут путём сравнения с диаграммой или текстом от аналитика;
- кликабельность из блоков в строки кода помогает обнаружить замедления, которые бывают от наличия комментариев или обращений к базе внутри цикла (обычно в схеме flowchart не показывается текст комментариев, поэтому их наличие придётся выявлять в самом коде, а визуализацию циклов легче определить по диаграмме);
- глазастые заметят в примере переменные без присвоенного значения или неочищенные в конце (проблем от некорректного обращения с переменными множество - от переполнения буфера и до некорректного расчёта и передачи в другие модули).
Утилиту для построения блок-схем чаще других можно найти в среде разработки программиста. Также много аналогов в свободном доступе.


Третья группа визуализаторов – демонстрирует вызовы одних подпрограмм другими и показывает связи объектов данных с кодом. Их называют обычно Call Tree, References&Dependencies диаграммы (направления стрелок показывают вызовы объектов) и CRUD матрица (Create/Read/Update/Delete операции над данными из подпрограмм).
Сорсники и таблицы всего проекта попадают без повторений в диаграмму. Поэтому простым поиском по имени выявляйте лишние и недостающие обращения к объектам. Например, в диаграмме о кадрах может быть лишней процедура "tech_proc_2", а в матрице бухгалтерии или финансового отдела часто можно обнаружить нехватку процедур или таблиц с ордерами прихода/расхода (если существует корпаративные стандарты наименований объектов).
Для генерации диаграмм и матриц берите чистый исходный код, не прошедший обфускацию или компиляцию, потому что замена имён не даст нужного результата.
Пользуйтесь детализацией связей, подсветкой вызовов и сменой уровней связей при поиске зацикленных процедур (в примере процедура "tech_proc_2" должна быть проверена на все вызовы процедурами "emp_proc_1" и "emp_proc_3", так как при определённых условиях вполне может случится зацикливание), а также шагов, приводящих к мутации данных (в примере показан триггер "emp_trg" и процедура "emp_proc_3", влияющие на данные в таблице "emp_tbl", а поскольку процедура через несколько шагов может быть выполнена из триггера, то вполне вероятно совместное обращение к одним и тем же данным).
Если формат выходной диаграммы SVG, XML или VDX, то более вероятно воспользоваться всеми полезностями (поиск по диаграмме, подсветка путей, кликабельность из диаграммы в код, сворачиваемость блоков диаграмм).


А теперь немного о метриках кода, то есть о качестве в цифрах. Если визуализаторы более полезны на начальном этапе разработки, то на метрики кода влияют каждые изменения подпрограммы. К сожалению, идеального кода не существует и добиться невозможно, как и КПД-100%. Чем же мы, тестировщики, в состоянии помочь кодеру?
Самая простая метрика - количество строк в сорснике до компиляции. С этим файлом работает программист в среде разработки – правит, отлаживает, компилирует. А большой объём файла совсем не на руку ни компилятору, ни системе контроля версий, ни тем более среде разработки.
Хороший редактор раскрашивает синтаксис, показывает начало-конец цикла и иными способами помогает кодеру, а все эти примочки требуют ресурсов. В один прекрасный день вчерашний код не откроется в среде разработки – и конец всем фиксам.
В СКВ дешевле хранить некоторые маленькие файлы, нежели один и тот же большой дописывать, потому что место на сервере слишком быстро закончится.
Слияние изменений (merge) выполнять в СКВ на мелких отдельных файлах проще, и конфликты случаются реже - как в коде, так и между сотрудниками.
Вторая простая для подсчёта величина – количество параметров (и особенно глобальных), которое рекомендуют не более 7 (5 входящих, 2 на выход). Цифра пришла из чистой психологии - единовременно человек запоминает не более 7 объектов. Для работы с бОльшим количеством параметров придётся взводить хинты-подсказки, требующие ресурсов и времени.


С 70-х годов XX века благодаря T.J.McCabe, Maurice Halstead, и чуть позже Don M Coleman и Paul Oman с Jack Hagemeister стало возможным измерить качество кода и спрогнозировать его развитие. Величины, выведенные этими людьми, стали носить их имена.
Thomas J.McCabe вывел формулу цикломатической сложности юнита как разность рёбер и узлов с добавлением удвоенного количества компонент связности.
При грубой оценке граф цикломатической сложности совпадает с диаграммой flowchart, где стрелки выполняют роль рёбер (на рисунке - зелёные), овалы и многоугольники считаются узлами (на рисунке - красные звёздочки), а целый законченный блок – компонент связности (на рисунке - серым цветом ограничены два графа для примеров кода).
Не для всех случаев граф цикломатической сложности идентичен flowchart, потому что если используется сложное условие (через OR/AND), то каждое из них может считаться узлом (в примере граф для процедуры "threeinone" станет идентичен графу для процедуры "oneinthree").
Максимальное значение величины McCabe утверждено Американским Национальным Институтом Стандартов и Технологий (NAST), равно 10, но последнее время расширяют до 15.
Нам тестировщикам это значение говорит о необходимом количестве юнит-тестов.


Все величины Мариуса Халстеда рассчитываются по операторам и операндам, и поэтому утилита должна быть версионно-зависимой для языка программирования, а лучше встроенной в среду разработки.
Что есть операторы и операнды помним, да? В выражении «a+b»: "+" – оператор, "a" и "b" – операнды.
Не удивляйтесь, если подсчитанные строки в листинге не совпадают с длиной программы по Халстеду, потому что длина программы – это сумма всех операторов и всех операндов.
Словарь юнита он определил как сумму уникальных операторов и операндов.
А помножив длину программы на логарифм словаря, Халстед получил объём подпрограммы (или ещё эту величину называют "сложностью Халстеда"). Она максимально не должна превышать 1000 (лимит не утверждён никаким стандартом).
Если же исследовать функцию сложности, приняв уникальными все операнды и операторы, то в самом сложном юните должно быть примерно – 45 операторов и 90 операндов, как это видно на графике. Фактически - это невообразимая программка.


Maintainability Index перевожу для себя не как ремонтопригодность, а как «важность и устойчивость», потому что он  прогнозирует развитие подпрограммы  (сколько ещё можно править или расширять юнит).
Индекс значимости подпрограммы, выведенный Доном Колеманом и Паулем Оманом, дополненный Джеком Хейгмейстером, зависит от всех составляющих листинг: операторов и операндов, блоков и их связей, значимых  и вспомогательных строк кода.
Предел индекса никакими институтами пока не утверждён, но для стабильно-устойчивых подпрограмм рекомендуется писать код так, чтобы индекс был более 85. Когда индекс падает ниже 65, то ваш юнит совсем плох.
Если поисследовать функцию, рассчитывающую индекс, то при максимальных величинах Халстеда, МакКейба и комментов в одном юните - не стоит делать более 1500 строк. Это видно на среднем графике.
Формула имеет две модели: с учётом комментариев (обе строки формулы:" MI = 171 - 5.2*ln(HV) - 0.23*CC - 16.2*ln(LOC) + 50*sin(sqrt(2.4*COM)) ") и без учёта комментариев (только первая строка: " MI = 171 - 5.2*ln(HV) - 0.23*CC - 16.2*ln(LOC) "). Поскольку величина комментариев зависит от функции синуса, то при отношении объёма комментов к строкам кода в процентах, синусоида сложно извивается на отрезке от 0 до 100 (левый график показывает несколько вариантов подбора - максимумы). Если же брать долевое исчисление комментов - от 0 до 1 (правый график), то 3/10 комментированных строк дадут максимум полезности. Юнит должен быть легко-читаемым. И даже цифры подтверждают, что нет смысла экономить за счёт комментариев: "+50 всегда лучше трёх минусов для стремящихся к 85 и выше".


В таблице-шпаргалке перечислены формулы для исчисления качества кода. Особым шрифтом выделены две формулы для прогноза количества багов (вывел Халстед).


При использовании аудита кода, как части среды разработки, никаких дополнительных вложений от вас не потребуется: ни в обучение, ни в покупку, ни в дальнейшую поддержку утилит, как это приходится делать с юнит-тестами.
Если результаты юнит-тестов дают понимание о том, «каков код здесь и сейчас», то аудит говорит о перспективах развития подпрограммы.
Code Audit - для комплексного тестирования всего проекта, Unit testing – для точечного.
Одно другим подменить невозможно, но совместное использование только улучшит качество конечного продукта.
Мечтающие взлететь в bug-bounty, воспользуйтесь тем, что завалялось у вашего программиста, а именно утилитами аудиторов кода, вшитые в среду разработки.

Делайте аудит кода, находите сразу причины сложных багов, давайте подсказки программистам, где именно и что рефакторить для улучшения качества кода. Или научите их делать аудит кода самостоятельно, регулярно, автоматически через шедулеры, и в тестировщиках отпадёт необходимость.

среда, 13 июня 2018 г.

Документор кода или псевдокод

Осенью 2016 года сотрудникам, рекламирующим и распространяющим продукт ClearSQL, мной было предложено позиционировать его не только для разработчиков, но и для тестировщиков. Но пользу утилит аудиторов кода они оценили только недавно, начав серию статей с Псевдокода (https://www.youtube.com/watch?v=pFCAALkJ9RU).
Именно Псевдокод является самым простым и доступным способом оценки полноты и качества кода. Фактически, это комментарии к коду, понятные любому человеку.
Комментарии псевдокода добавляются в основной код со специальными тегами. За счёт этих тегов можно вычленять только комментарии (обычный текст, который можно брать из текста технического задания от аналитика продукта) или композицию комментариев со строками кода. В ClearSQL есть возможность генерить Flowchart (блок-схему, UML диаграмму) по комментариям псевдокода. Нижеследующие скриншоты сняты из редакторов кода, псевдокода и диаграмм приложения ClearSQL 6.9.
Текст кода с комментариями псевдокода:

Диаграмма flowchart кода:

Текст псевдокода:

Диаграмма flowchart по комментариям псевдокода (UML формат, слева-направо, со строками кода):

Если аналитики балуют программистов составлением тех.задания в виде блок-схем, то сравнение UML диаграммы от аналитика с Flowchart по комментариям псевдокода даст моментально объём тех.задания, не покрытого кодом или не продуманного аналитиком. В нижеследующем примере видно, что программист обработал не только граничные значения (есть/нет звонок), но и промежуточный результат (абонент занят).
Блок-схема аналитика (нарисовано вручную в Paint):

Диаграмма flowchart по комментариям псевдокода со строками кода:


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

закомментировать эти строки (можно с тэгами псевдокода)

разбить их на логические куски

и уже к имеющемуся плану скрипта дописывать код
.
По-сути, просто "тупокодить". А сколько при этом экономится общекомандного времени на разработку!

Наличие комментариев в коде имеет ряд преимуществ:
* из-за текучки кадров следующему программисту будет быстрее и проще разобраться с чужим кодом (легаси);
* maintainability index (уровень качества кода) любого кода достигается больше минимума в 85 за счёт 3/10 комментированных строк (но только если это не временно неиспользуемый код, а именно пояснения к коду = полезные комментарии);
* по комментариям к коду не только легче разобраться с его предназначением, но и можно улучшить свои знания языка программирования;
* наличие комментариев в коде ускоряют восстановление истории задачи и добавляют уверенности при смене или потере VCS и BTS, так как нет смысла искать изменения по системе контроля версий или по баг-трекинговой системе;
* сертификация программного обеспечения подразумевает наличие документации, которую легко и быстро можно вычленить из комментариев псевдокода, а не писать с нуля, как это было в моей практике.

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