Как договориться о программе до того, как написана первая строка кода
До сих пор задачу давал преподаватель: условие варианта, примеры, таблица тестов. В работе условия нет — есть заказчик, который хочет «чтобы программа следила за процессами». Путь от этого желания до работающей программы и дальше называют жизненным циклом:
| Этап | Вопрос | Результат |
|---|---|---|
| Анализ и постановка задачи | что нужно заказчику? | техническое задание |
| Проектирование | как это устроить? | модель, алгоритмы, структура программы (раздел 1) |
| Кодирование | как написать? | исходный текст |
| Тестирование | делает ли программа то, что требовалось? | протокол проверок |
| Внедрение и сопровождение | работает ли у пользователей, что исправить? | новые версии |
В российских стандартах (Единая система программной документации, ГОСТ 19.102-77) стадии называются иначе — техническое задание, эскизный проект, технический проект, рабочий проект, внедрение, — но порядок тот же, и первая стадия — ТЗ. Ошибка, найденная в ТЗ, стоит исправления абзаца текста. Та же ошибка, найденная после сдачи программы, стоит переделки кода, повторного тестирования и спора о том, кто виноват.
Техническое задание — документ, в котором заказчик и исполнитель письменно договорились, что программа должна делать и как проверить, что она это делает. Оно нужно всем:
Главное правило: ТЗ описывает, что делает программа, а не как она устроена. «Программа выводит список запущенных процессов с идентификатором и именем» — требование. «Программа вызывает CreateToolhelp32Snapshot и обходит список в цикле while» — решение исполнителя, ему место в проекте, а не в ТЗ. Если в ТЗ написано «как», исполнителю связывают руки, а заказчик берёт на себя ответственность за выбор, в котором не разбирается.
ГОСТ 19.201-78 «Техническое задание. Требования к содержанию и оформлению» — часть ЕСПД. Он задаёт состав разделов; раздел, которому нечего сказать, всё равно пишут со словами «требования не предъявляются» — так видно, что о нём подумали, а не забыли.
| Раздел | Что в нём | Для учебной утилиты |
|---|---|---|
| 1. Введение | наименование программы, краткая характеристика области применения | 2–3 предложения |
| 2. Основания для разработки | документ, на основании которого ведётся разработка; кто утвердил; наименование темы | «учебный план МДК 01.04, практическая работа №15» |
| 3. Назначение разработки | функциональное (что делает) и эксплуатационное (кто, где и зачем использует) | абзац |
| 4. Требования к программе | 4.1 функциональные характеристики; 4.2 надёжность; 4.3 условия эксплуатации; 4.4 состав и параметры технических средств; 4.5 информационная и программная совместимость; 4.6 маркировка и упаковка; 4.7 транспортирование и хранение; 4.8 специальные требования | главный раздел: 4.1 — подробно, 4.2 и 4.5 — по делу, 4.6–4.7 — «не предъявляются» |
| 5. Требования к программной документации | какие документы сдаются вместе с программой | исходный текст с комментариями, руководство пользователя (справка по запуску) |
| 6. Технико-экономические показатели | ожидаемая польза, сравнение с аналогами | кратко или «не предъявляются» |
| 7. Стадии и этапы разработки | что, в каком порядке и к какому сроку делается | ТЗ → код → тестирование → сдача, с датами |
| 8. Порядок контроля и приёмки | как проверяется, что требования выполнены | список проверок: ввод, ожидаемый результат (пункт 07) |
| Приложения | форматы файлов, примеры, макеты экранов | пример входного файла и вывода |
Раздел 4.1 отвечает на вопрос «что программа делает» так, чтобы по нему можно было написать и программу, и тесты. Удобно идти по той же схеме, что и в модели задачи из раздела 1:
| Что описать | Вопросы | Пример |
|---|---|---|
| Запуск и входные данные | как запускается, что получает: аргументы командной строки, ввод, файлы | «Программа запускается командой wcount <файл>» |
| Обработка | что вычисляет — результат, а не алгоритм | «подсчитывает число строк, слов и символов файла» |
| Выходные данные | что, куда и в каком виде выводит | «выводит в консоль три числа в одной строке через пробел» |
| Ошибки | что происходит при неверном запуске, отсутствии файла, неверных данных | «если файл не открывается — сообщение с именем файла, код завершения 2» |
| Граничные случаи | пустой вход, максимальный размер, особые значения | «пустой файл — 0 0 0» |
Каждое требование — отдельный пронумерованный пункт с глаголом «должна»: «4.1.3. Программа должна…». Номер нужен, чтобы на пункт можно было сослаться в проверке и в споре. Одно требование — одно проверяемое свойство: пункт «программа должна считать строки и слова и работать быстро» проверить целиком нельзя.
Коды завершения для системной утилиты — тоже требование: по ним другая программа (или скрипт) узнаёт, как всё прошло. Принято: 0 — успех, 1 — неверный запуск (нет аргументов), 2 и дальше — ошибки выполнения. В разделе 14 ваша программа будет получать код завершения дочернего процесса — именно этот.
Если программа читает или пишет файлы, обменивается сообщениями по каналу или сети, формат данных — такое же требование, как функция. Две программы, написанные разными людьми по одному ТЗ, должны понимать файлы друг друга.
| Свойство | Что указать | Пример |
|---|---|---|
| формат | текст или двоичный; как устроена запись | «текстовый файл, одна запись в строке: фамилия, группа, балл через пробел» |
| допустимые значения | типы, диапазоны, обязательность | «группа — целое 1…99; балл — число 2.00…5.00 с двумя знаками» |
| размеры | наибольшая длина строки, число записей, размер файла | «фамилия — до 31 символа; до 100 записей» |
| кодировка и концы строк | в каком виде хранится текст | «латиница, ASCII; конец строки — CR LF или LF» |
| неверные данные | что делать с записью, которая не подходит | «строка с ошибкой пропускается, её номер выводится в сообщении» |
Ограничения по размерам — не прихоть: из них исполнитель выберет вместимость массивов (разделы 8 и 10), а тестировщик — граничные тесты. «До 100 записей» проверяется файлами из 100 и 101 записи.
Требование, которое нельзя проверить, ничего не требует: исполнитель скажет, что выполнил, заказчик — что нет, и оба будут правы. Проверяемое требование говорит, при каких условиях и какой наблюдаемый результат должен получиться.
| Непроверяемо | Проверяемо |
|---|---|
| программа должна работать быстро | обработка файла размером 10 МБ занимает не более 2 секунд на компьютере из п. 4.4 |
| удобный интерфейс | все команды меню выбираются одной клавишей; текущий пункт выделен цветом |
| программа должна обрабатывать ошибки | при отсутствии файла выводится «Cannot open <имя>», код завершения 2 |
| надёжная работа | при любом содержимом входного файла программа не завершается аварийно |
| поддержка больших файлов | файлы до 2 ГБ; строки длиной до 1000 символов |
| и другие функции по необходимости | — (такое требование удаляют: его нельзя ни выполнить, ни проверить) |
Слова-сигналы непроверяемости: «быстро», «удобно», «надёжно», «современный», «и т. д.», «по возможности», «при необходимости», «достаточный», «оптимальный». Встретили такое слово в своём ТЗ — замените числом, условием или перечнем.
Раздел 8 ТЗ — это та таблица тестов, которую вы составляли в каждой практической работе, только написанная до программы. Для каждого функционального требования — хотя бы одна проверка; для требования об ошибке — проверка, которая эту ошибку вызывает:
| № | Требование | Действие | Ожидаемый результат |
|---|---|---|---|
| 1 | 4.1.2 | wcount text.txt, в файле 3 строки, 7 слов, 40 символов | 3 7 40, код 0 |
| 2 | 4.1.4 | wcount без аргументов | подсказка по запуску, код 1 |
| 3 | 4.1.5 | wcount nofile.txt — файла нет | Cannot open nofile.txt, код 2 |
| 4 | 4.1.6 | пустой файл | 0 0 0, код 0 |
Если для требования не получается придумать проверку — значит, требование сформулировано плохо (пункт 06). Этот раздел полезно писать одновременно с разделом 4.1: он сразу показывает непроверяемые пункты. Работа принимается, когда все проверки раздела 8 пройдены — ни больше, ни меньше.
wcountСокращённое ТЗ на утилиту подсчёта строк, слов и символов — в объёме, который ожидается в практической работе №15. Разделы 4.6–4.7 и 6 — «не предъявляются».
Наименование: консольная утилита wcount. Область применения: быстрая оценка объёма текстовых файлов (отчётов, журналов, исходных текстов) из командной строки Windows и из командных файлов.
Учебный план МДК 01.04 «Системное программирование», практическая работа №15. Тема разработки — «Утилита подсчёта строк, слов и символов».
Функциональное: подсчёт числа строк, слов и символов в текстовом файле. Эксплуатационное: используется пользователями Windows в консоли и в командных файлах; результат и код завершения должны быть пригодны для обработки другими программами.
4.1. Функциональные характеристики.
wcount <имя_файла>; имя файла может содержать путь и пробелы (в кавычках).Usage: wcount <file> и завершаться с кодом 1.Cannot open <имя_файла> и завершаться с кодом 2.0 0 0.4.2. Надёжность. При любом содержимом файла (в том числе двоичном) программа не должна завершаться аварийно. Файл не должен изменяться.
4.3. Условия эксплуатации. Запуск пользователем без прав администратора; специальной подготовки пользователя не требуется.
4.4. Технические средства. Компьютер с Windows 10 или 11 (x64), 4 ГБ оперативной памяти.
4.5. Совместимость. Исполняемый файл запускается без установки дополнительных библиотек. Входной файл — текст в любой однобайтовой кодировке, концы строк CR LF или LF; размер — до 2 ГБ.
4.6–4.8. Требования не предъявляются.
Исходный текст на C++17 с комментариями; руководство пользователя — одна страница: запуск, вывод, коды завершения.
ТЗ — неделя 1; программа и тесты — неделя 2; приёмка — неделя 3.
По таблице проверок пункта 07 этой страницы, дополненной проверками для 4.1.3 (файл без перевода строки в конце; строка из одних пробелов) и 4.2 (двоичный файл, файл 2 ГБ).
Заметьте, чего в этом ТЗ нет: ни слова о ifstream, getline, массивах и функциях. Как считать — решит исполнитель. Зато есть определения «строки» и «слова»: без них две честные программы дадут разные числа на файле без перевода строки в конце — и обе будут правы.
| Ошибка | Пример | Чем опасна | Как исправить |
|---|---|---|---|
| описано «как», а не «что» | «использовать функцию CreateProcess и массив из 100 элементов» | исполнитель не может выбрать лучшее решение; ограничение без причины | описать результат; ограничение — только если оно нужно заказчику |
| непроверяемые слова | «быстро», «удобно», «надёжно» | приёмка превращается в спор | число, условие, перечень (пункт 06) |
| нет ошибочных ситуаций | описан только «хороший» запуск | программа молча падает на первом же неверном вводе | для каждого входа — что будет при его отсутствии и неверном значении |
| нет граничных случаев | ничего о пустом файле, максимальном размере | выход за границы массива (раздел 8) | пустой вход, максимум, максимум + 1 |
| термины без определений | «слово», «строка», «активный процесс» | разные программы дают разные ответы | определить в 4.1 или в приложении |
| противоречия | 4.1.2 — «выводит в файл», 8 — «проверить вывод на экране» | выполнить оба требования нельзя | перечитать ТЗ целиком после написания |
| несколько требований в одном пункте | «считает строки, выводит в файл и работает быстро» | невозможно сказать, выполнен ли пункт | один пункт — одно свойство |
| раздел 8 пуст или «проверить работу» | «приёмка — по результатам тестирования» | нет критерия «готово» | таблица проверок со ссылками на пункты 4.1 |
| разделы пропущены | нет 4.2–4.5 | не видно, подумали о них или забыли | «требования не предъявляются» |