Обновляем курс “Системной инженерии”
Приступил к переписке “Системной инженерии”, уже поправил все “практики” на “методы” – но с учётом новой “Методологии” там ещё много надо править по этой линии, принимать много решений, текст курса там 2022 года (хотя в нём уже и требований нет, и архитектура по-новому, и подраздел по эволюции систем есть, но вот методолога ещё не предусмотрено, а также очень абстрактные ссылки на AI-агентов). Если у вас есть к этому курсу какие-то пожелания, самое время мне их сообщить. Что туда надо бы включить? Что не очень понятно? Только, плиз, не делайте из “Системной инженерии” курс Software Engineering. У нас там все виды систем — не надо про особенности софтверной разработки, это в прикладной спецкурс. Там проблема основная в том, что софтовая разработка далеко оторвалась и от классической системной инженерии и от всех других (например, инженерии сообществ — скажем, изготовление клиентуры с нуля, хотя там steve blank со товарищи много сделал, чтобы их приблизить, это ж lean, который у них читается как agile, чуть ли не синоним). И тут можно или прямо про принципы говорить компактным языком, или вот так половинчато — “у этих так, а у этих сяк, у всех по разному, пелотон длинный, растянулся сильно”.
Болящий вопрос – это что делать с требованиями, которых нет, и тестами, которые есть. Я написал на эту тему уже два текста:
– “Use Case, DDD, BDD и их методологический синтез”, Use Case, DDD, BDD и их методологический синтез: ailev — LiveJournal (12 декабря 2024)
– “Ещё раз про Use Case 3.0”, https://ailev.livejournal.com/1745161.html (17 декабря 2024)
Эти обсуждения продолжились, причём на первый план вышло два метода:
– AI-assisted development для AI-assisted development (адаптация SoTA, то есть с использованием AI, методологии софтверной разработки при помощи AI). У нас же организаторы этим интересуются. Как выбрать метод, как донести его до разработчиков так, чтобы у них не было вопросов, а они просто начали по нему работать. Тематика организационного развития в айтишных фирмах, а в остальных фирмах будет примерно так же, только чуток попозже.
– AI-assisted development (AIAD), и в его разложении на составляющие AI-assisted testing. Как тестировать софт с помощью AI.
Некоторые обсуждения вопроса были на этой неделе в чате поддержки инженерных курсов, примерно с Telegram: Contact @systemsthinking_course. Звучат вроде бы вопросы про саму разработку, но нет – это методологические вопросы организаторов разработки, ибо сами разработчики часто никакой инициативы по переходу на новые методы не имеют. Им кто-то (“консультант” – внутренний или внешний, роль “методолог программной инженерии”) должен рассказать о SoTA методе и дать какие-то примеры. Вот в качестве такого консультанта может выступить методолог с просто какими-то знаниями о софтверной разработке, усиленный ChatGPT на предмет SoTA. И уже затем с помощью ChatGPT тот же методолог делает какие-то примеры работы (прототипы, таблички, аутлайны – то, что можно обсуждать) и даёт их команде разработчиков. Команда разработчиков тем самым начинает работать не с чистого нуля: им показали метод, им показали какие-то заведомо кривые прототипы, и они их могут улучшать. В этих репликах поминается
– прошедший мой двухдневный семинар (тут выяснилось, что до сих пор можно купить его запись, оплатив на странице Инженерия всего на пороге 2025, придёт ссылка на чат семинара с видео и вся история чата с вопросами и обсуждениями. Для ускорения доступа прислать в телеграм @ssm_tg скан чека).
– семинар по разбору случая Юрия (видео опубликовано в https://www.youtube.com/watch?v=SOw0X8cl3fg и Воркшоп с разбором рабочего кейса 20.12.24.. | Школа системного менеджмента | VK, аутлайн рассказа – Notion – The all-in-one workspace for your notes, tasks, wikis, and databases.), планируем продолжить через некоторое время.
Эволюция test-driven development
Онтология разных “тестирований” необъятна, разобраться в огромном числе методов тяжело. Посмотрите сами: вот тут статья википедии software testing, довольно многого из текущего поста там просто не помянуто – Software testing - Wikipedia. Скажем TDD приведён в разделе Teamwork подраздел agile development – один абзац, затерявшийся в огромном тексте.
Всё началось с test-driven development (TDD), после чего даже самые современные навороченные варианты сдвинутого влево (left shift) и непрерывного (continuous) тестирования называют по-старинке самым первым именем TDD, даже с включением AI и самых разных автоматизаций. В “State of testing report 2024” (Unveiling the 2024 State of Testing | PractiTest) говорится, что 23% of survey participants said that their organizations follow TDD approaches, compared to 18% last year. This growth indicates stronger support for the shifting left approach. И ещё там есть про BDD, что явно продолжение линии TDD. BDD в 2023 году было у 23% опрошенных, а в 2024 – у 26%. Водопад – у 23% в 2023 году, а в 2024 году – у 21%. Ну что же, ломка мозга идёт медленно, но верно. Методологии инженерии, как и научные теории, вымирают медленно.
А что там с AI? Тут проще, потому как AI можно воткнуть в поддержку и самой допотопной методологии тестирования – 40% of Companies Embrace AI in Testing, According to PractiTest’s 2024 State of Testing™ Report (40% of Companies Embrace AI in Testing, According to PractiTest's 2024 State of Testing™ Report).
Эволюция методов по линии “сначала тесты, потом код” привела к появлению довольно многих видов методов, каждый из которых отвечал как-то на критику предыдущих вариантов. Все эти варианты были поддержаны какими-то программными инструментами, автоматизирующими тестирование и управляющими конфигурацией тестов. Потом от тестирования кода перешли к системным тестам, тут и оказалось, что в тестировании участвуют довольно много проектных ролей, особенно когда выяснили, что тесты описывают программную систему ещё до того, как написан её код, поэтому описать систему надо с участием заказчиков. Программными инструментами поддержки тестирования оказались в том числе и средства коммуникации и организации работ. Потом “заодно” тесты функциональности стали проводить с тестами качества, в том числе тестами безопасности и fitness functions архитекторов, их встроили в DevOps, а инструментальную поддержку – в развитие DevOps в сторону NoOps (internal development engineering, занимающееся строительством всяческих CI/CD pipelines и объединяющее огромное количество разного инструментария в одну платформу разработки). AI тут стало просто вишенкой на огромном торте. Чтобы особо не перегружать текст ссылками и на тексты про методологии, и на их типовые софты поддержки, тут я их не привожу – и раньше я написал бы “гуглите”, а теперь я понимаю, что надо писать “спросите ваш AI”.
Можно таймлайн развития test-driven методологий представить очень грубо примерно так:
– TDD (test driven development) из поздних 90х, юнит-тестирование перед написанием кода, то есть тестирование на микроуровне, а не системное тестирование, плюс тестирование в ходе разработки, а не в её конце. Критики говорили, что TDD может замедлить начальную разработку, когда “всё очень быстро меняется, а вы ещё и тесты пишете на потом не нужное”, а ещё это “ломка мозга, очень плохо, не сможете переучить людей”, непонятно что там с интеграцией и тестами системного уровня, а ещё юнит-тесты проверяют реализацию, а не то, что система удовлетворяет требованиям внешних ролей. Конечно, на всю эту критику отвечали – и говорили, что тесты должны быть осмыслены в плане проверки не только кода, но и поведения системы в её окружении, и автоматизировали весь ход работы, чтобы снять упрёки в росте времени разработки. Сегодня всё это отлично существует, поддержано инструментарием, в том числе тесты генерирует AI.
– ATDD (acceptance test-driven development) из ранних 2000х, это расширение TDD на выявление требований (capturing requirements) и критерии приёмки (acceptance), и отличие было в том, что TDD было сразу кодом, а тут надо было писать тесты на естественном языке. Это был ответ на то, что в TDD не хватало юнит-тестов. Вот в этом месте инженерия требований говорит, что надо бы требования писать сразу в виде тестов. Критика была в том, что подготовка тестов потребует тесного сотрудничества между самыми разными проектными ролями (разработчики, внешние проектные роли, тестировщики, эксперты по предметной области и вот тут как раз появляются модельеры рабочих процессов, которых называли “бизнес-аналитики”), их трудно будет собрать всех вместе, а ввиду большого количества людей есть большой риск уйти от lean – формализовать процесс так, что всё утонет в согласованиях, а ещё естественный язык несовместим с тестами – высказывания на нём неоднозначны. В ответ сторонники говорили, что ATDD в существенной мере снимает критику TDD в отношении тестирования того, что “наш код работает” (проверка), а не “внешние проектные роли удовлетворены в использовании” (приёмка), а также давали честное пионерское, что они используют самый ясный и понятный, абсолютно недвусмысленный язык. Сегодня вполне процветает, поддержан инструментарием, задействуется AI.
– BDD (behavior-driven development) продолжает линию TDD и ATDD уже в середине 2000х, и отражает user eXperience движение – писать тесты надо было “с точки зрения пользователя”, а в язык описания (естественный) вводилась структура Given-When-Then: "“Given a customer with a valid account, when they request a password reset, then an email is sent to their registered address”. Цель та же, что у ATDD – совместить одинаковое понимание требований внешними проектными ролями (с учётом их впечатлений/опыта, “из первой позиции восприятия”), менеджерами (business goals), разработчиками и тестировщиками. Поддержан инструментарием, таким как Cucumber с языком описания требований Gehrkin. Это даёт и документацию для “бизнесОв”, и исполняемые машинно тесты: в тестировании та же идея, что в языках высокого уровня (там было то же самое: “хотелось бы писать программы руками экспертов предметной области на естественном языке, а у нас тут машинный язык и понимают его только программисты. Давай поднимем уровень языка описания алгоритмики и данных”, тут всё то же про тесты).
– SBE (specification-by-exapmle, Specification by Example — binwei documentation), появилось в 2000х, документирование требований делается как в BDD, но обязательно с примерами. В SBE основное – это заземление, ибо спецификация задаётся не абстрактными утверждениями, а конкретными примерами. “Нет примеров” = “недостаточное понимание”, а заземление ведёт к ускорению согласований и более точному пониманию. Критики отмечали, что конкретных примеров надо много там, где достаточно компактных абстрактных утверждений, при этом времени на примеры потребуется больше, а дыры в кейсах и сценариях всё равно останутся. И ещё по мере развития системы становится трудным поддерживать огромное количество примеров. Сторонники говорили, что лучше уж с дырами, чем вообще неправильно понятые ваши абстракции.
– PBT (property based testing) из 2000х как противоядие к SBE: говорит, что надо тестировать не примеры, а сохранение каких-то свойств софта, инвариантов. Генератор тестов будет генерировать всякие сочетания входов программы, а проверяться должно то, что какие-то свойства будут сохраняться – в том числе в на всяких границах диапазонов значений и в особых случаях. Критика в том, что подобные свойства просто трудно придумать, а генерирование большого количества тестов приводит к длительному времени тестирования, это не эффективно. Как отлаживаться – непонятно, ибо что там порушило инвариант и почему – плохо понятно. Зато вся критика о том, что какой-то набор примеров что-то там не закрыл – она снимается, если сформулированы свойства – можно потыкать в граничные значения на входах. In a financial application, a property is defined: “The sum of debits and credits in a transaction should always be zero.” The PBT framework generates numerous random transactions with varying amounts and accounts to test this property, ensuring the system maintains accounting balance under all conditions and detecting any anomalies that could lead to financial discrepancies.
– MBT (model-based testing) тоже из 2000х говорит, что надо описывать систему не на каком-то языке, а на языке моделирования. А уже из моделей поведения генерировать тесты, а не писать их самому руками. Критика тут понятна: это трудно и требует специального обучения и моделеров, модели могут быть плохими и не выражать чего-то важного, уровень абстракции в моделировании высок и поэтому плохо понятно, как совместить это с уровнем кода для тестов. Отвечали тем, что наоборот – моделирование может помочь найти дефекты, которые нельзя найти каким-то другим методом. Скажем, For a telecommunications system, engineers create a state model representing different call handling scenarios. The MBT tool generates test cases that cover various state transitions, such as call initiation, hold, transfer, and termination. This ensures that all potential paths are tested and the system behaves correctly under different conditions, improving reliability and user satisfaction. Это рассматривалось как часть MDD – моделеориентированной разработки, где по моделям и выводился затем код (моделирование было всё более и более точным, пока не превращалось в код), и делались тесты (и те, и другие должны были делаться одновременно). Всё это закончилось в 2010х большой дискуссией про DSL как предметноспецифичные языки моделирования, которые должны были генерировать вот это всё с использованием специальных stand-alone компиляторов их в код. Но потом была схватка между stand alone DSL (отдельные моделеры для DSL) и embedded DSL (языки, встроенные в хост-языки – обычные языки программирования, на которых удобно писать специализированные языки). И вот тут stand alone DSL проиграли, выиграли embedded DSL, и моделирование на них стало неотличимо от программирования. MBT поэтому потерял свой смысл: если ты генерируешь код, то он просто работает так, как ты описал на DSL. Поэтому тестирование оказалось тем же TDD, ATDD, BDD, SBE.
– CDD (contract-driven development) уже в 2010х, он определяет формальные контракты для интерфейсов между частями системы. Контракты прописываются формально – и там предусловия, постусловия, инварианты. Тесты выводятся из этих описаний контрактов, чтобы удостовериться, что эти контракты соблюдаются. Критика тут сразу в том, что моделирование на формальных языках довольно трудно, написание контрактов очень затратно по времени, жёсткие контракты уменьшают гибкость в разработке, а частые изменения приводят к тому, что приходится изменять довольно много частей системы, чтобы удовлетворять этим контрактам. Подход набрал довольно много сторонников, ибо по мере распространения микросервисной архитектуры и разных вариантов организации API для связи сервисов, стало важно тестировать интерфейсы.
– Mutation testing появился как идея в 70х прошлого века, но воскрешён в 2010х. В этом подходе надо вносить небольшие изменения в код, чтобы убедиться, что рушатся какие-то тесты. Если никакие тесты не рушатся, значит, что-то недотестировано. Можно оценивать тестовое покрытие. Критика тут в огромных вычислительных затратах, а также неочевидности связи мутаций с тестами – ну, тесты не поймали мутацию, а делать что, какой тест писать?!
От тестирования идём в quality assurance
Вообще, тестирование – это уже не так модно говорить, сейчас говорят о quality assurance, и тестирование там оказывается внутри (и в нашем курсе про этот сдвиг прописано). Это ход из 2010е в 2020е и там немного другие методы, нежели “тестирование кода на удовлетворение его функциональности”, там ход на тестирование качества, то есть архитектурных характеристик и характеристик безопасности:
– chaos engineering получил широкую известность в 2020х, тестируется жизнестойкость/resilience (архитектурная характеристика) на “боевом” софте под обычной рабочей нагрузкой: просто выключаются какие-то части системы, как при аварии – разве что известно, что именно отключено и когда это отключено. Дальше смотрим, “что упало”, какие системы резервирования и защиты от сбоев не сработали. Критика – это опасно, если нет развитой культуры разработки.
– observability-driven development тоже из 2020х, заставляет разработчиков вставлять средства диагностики в софт (то же тестирование) прямо при разработке, поднимать архитектурную характеристику observability/наблюдаемости. Если что-то пойдёт не так, это можно будет увидеть в логах. Критика – этих логов становится столько много, что непонятно, что с ними делать, где искать проблемы. Ещё при этом для администраторов делаются дашборды, дающие представления о происходящем в системе: какая там нагрузка, сколько потребляется ресурсов.
– shift-left testing with DevSecOps, тоже из 2020х. В целом всё это движение “тестирование сначала” – это shift left testing, сдвиг влево на V-диаграмме. Методология with DevSecOps просит учесть, что есть не только функциональные тесты, но и тесты на безопасность (и, добавим, ещё и fitness functions от архитекторов), то есть тестировать надо не только функциональность, но и качество системы. Безопасность и архитектуру с их тестированием надо тоже двигать влево. Тут же – infrastructure as code (IaC) testing, fitness functions архитекторов. Критика тут вся та же самая: требуется ломка мозгов разработчиков, требуется от разработчиков понимание проблем уже не только пользователей, но и безопасников с архитекторами, что увеличивает требования к квалификации разработчиков, увеличивает нагрузку разработчиков. Зато качество софта растёт. Разных вариантов тут много, например, security test-driven development (STDD, помним, что всё зовут TDD), Security Test Driven Development (STDD) (2016).
– TestOps, это подход к тестированию на основе его автоматизации и встраиванию этой автоматизации (инструментальной поддержки) в конвейер “непрерывного всего” (чаще все это будет CI/CD pipeline). Сегодня не так часто выделяют именно TestOps, ибо там меняется терминология на internal development platform engineering и инструментарий поддержки shift-left testing с генерацией и прогоном тестов, а также поддержкой коммуникации разработчиков с разными другими ролями по поводу создания тестов рассматривается в рамках platform engineering. При каждом изменении кода выполняются автоматизированные юнит-тесты, интеграционные тесты, тесты качества (архитектурные характеристики и характеристики безопасности).
– hyperautomation in testing тоже из 2020х, тут AI, машинное обучение, RPA (robotic process automation, это когда роботы нажимают на кнопки софта, изначально предназначенные для людей, а не садятся на непредусмотренный отсутствующий API). Hyperautomation имеет целью end-to-end тестирование, где участия людей вообще нет. Критика тут традиционная для любой автоматизации: машины не так хороши, как люди. Критика, конечно, игнорируется. Главное, что даёт hyperautomation – это скорость, а отстутствие людей уменьшает число конфигурационных коллизий в тестировании.
– AI-assisted testing. Никакой явной методологии тут нет, это самый-самый фронтир. Но тесты тут пишет AI, и AI же оценивает результаты их прохождения. Тут идут эксперименты, кто во что горазд. Семинар с Юрием как раз обсуждает один из таких экспериментов.
В “железной” инженерии всё идёт примерно тем же путём, только с примерно 10-летним отставанием, в Software 2.0 (обучающиеся программы, differentiable programs) всё тоже по-другому, в медицине (ага, “доказательная медицина”) и инженерии личности – тоже всё не так бодро. Тут же описывается Software 1.0 и в AI-assisted testing добавляется кусочком Sofware 3.0
Всё сложно, непонятно, очень дорого и долго. Но тестировать – надо!
На картинке интересные результаты годового обзора 2024 года (The 2024 State of Testing™ Report | PractiTest), вопрос о том, какое мастерство (skill) нужно тестировщикам. Там интересно, что вообще мастерства в текущем году надо существенно меньше, кроме мастерства в ML/AI (в прошлом году важным считали 7%, в этом году – 21%). А вот особо важным мастерство проектирования тестов и экспериментов считать перестали – в прошлом году это было важно для 63% участников опроса, в текущем году – лишь для 30%. Всё быстро, о причинах можно гадать, но есть подозрение, что эти виды мастерства уходят от тестировщиков к разработчикам и к AI. А что остаётся тестировщикам? Бог весть.
UPDATE: обсуждение в чате блога – Telegram: Contact @ailev_blog_discussion