LINUX.ORG.RU

литературное тестирование (по следам Дональда нашего Кнута)

 , , , ,


2

2

Асилив наполовину книжку Владимира Хорикова «Принципы юнит-тестирования» я что то вернулся к одной своей старой идее. Я занимаюсь разработкой всякого академического софта, и у нас юнит-тестирование делать не принято. С одной стороны проекты маленькие и без него как то можно жить, с другой его практически никто не умеет делать.

При этом документацию писать приходится, и коллеги жалуются что в моей документации мало примеров. Идея такая - раз в документации нужны примеры, то пусть эти примеры заодно играют роль тестов (всяких). Нужен doxygen наоборот, утилита которая из специально оформленной документации может выделить тесты, собрать их и запустить. Такие тесты все же лучше чем ничего.

Документация пишется разумеется в техе. Примеры оформляются в окружении verbatim, хотя можно выбрать какое то другое. В теховский документ добавляются специальные команды закомментированные для теха (начинающиеся с символа %), но влияющие на поведение утилиты тестирования.

  1. Может быть создано один или несколько файлов в которых накапливается код тестов по мере обработки теховской документации. Для создания файлов используется комбинация
%@> имена файлов через пробел 

созданные файлы могут быть активными (по умолчанию) или замороженными. Если файл активен, все что начинается с одиночного % или находится в окружении verbatim дублируется в этот файл. Для заморозки используется комбинация %@- имена файлов, для разморозки %@+ имена файлов, для закрытия файла %@. имена файлов. Для записи отдельной строки в файл или группу файлов (вне зависимости от их состояния) используется

%@(имена файлов) какой то код 

При этом в именах файлов можно использовать вайлдкарты а-ля шелл.

  1. если в окружение verbatim встречается комбинация
выражение --> результат

оно трактуется как тест. То есть в файлах с тестами, в зависимости от расширения, будет добавлен код вычисляющий выражение и сравнивающий его с результатом. В каждую строку теста в конец добавляется комментарий отсылающий к исходному теховскому файлу (имя и номер строки), если тест провален то выдается сообщение указывающее на строку в теховском файле откуда тест был взят.

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

  2. Точно нужно будет настраивать как какие тесты собирать и запускать, аналогично через какой то вариант вроде %@$ … Ну и наверное для запуска тестов можно заюзать gnu make.

  3. Отдельная история с тестированием готовых приложений (небольших), на них ведь тоже пишется документация с примерами. В общем все то же самое но для запуска shell, при этом результаты сравниваются как строки?

Как то так. Cast @bugfixer, @pon4ik, @thunar, @Vit

★★★★★

Последнее исправление: AntonI (всего исправлений: 1)

Гораздо проще делать примеры именно в коде(прям отдельные собирабельные бинарники, например по одному cpp на пример), а потом вставлять их в латех(если нужно) с нужной подсветкой. Примеры это конечно такие себе тесты, но лучше чем ничего.

pon4ik ★★★★★
()
Ответ на: комментарий от pon4ik

По моему опыту полноценные (самодостаточно работоспособные) примеры очень избыточны. И главное, пример от теста отличается тем что в тесте есть проверки и тесты кто то должен запустить и проконтролировать результат. То что я вижу в системах тестирования - там прилично так кода который этим занимается в тестах, пользователей это будет пугать.

AntonI ★★★★★
() автор топика
Ответ на: комментарий от AntonI

Идея такая - раз в документации нужны примеры, то пусть эти примеры заодно играют роль тестов (всяких).

Гораздо проще делать примеры именно в коде(прям отдельные собирабельные бинарники, например по одному cpp на пример), а потом вставлять их в латех(если нужно) с нужной подсветкой. Примеры это конечно такие себе тесты, но лучше чем ничего.

По моему опыту полноценные (самодостаточно работоспособные) примеры очень избыточны.

Тогда я ничего не понимаю. Как можно тестировать что-то неработоспособными примерами? Разве что тестировать компилятор на отлов ошибок.

aureliano15 ★★
()
Ответ на: комментарий от AntonI

Это да, поэтому я и говорю, что примеры - такие себе тесты. Максимум смоук какой-то.

Если работоспособные примеры получаются избыточными, значит API не оч. (привет boost, ну местами конечно).

Тесты нужны в первую очередь для разработчиков тестируемого, это для них «дока», а примеры и документация API для пользователей этого API. Не стоит смешивать мух и котлет. Успешная сборка и запуск примеров - может быть одним из сценариев функционального тестирования пакета API разве что.

pon4ik ★★★★★
()
Ответ на: комментарий от AntonI

Как такой извращённый вариант TDD (на самом деле скорее зачаточный, чем извращённый). Попробуй сначала написать лаконичный пример демонстрации решения задачи, а потом уже реализацию того интерфейса, который получится.

pon4ik ★★★★★
()
Ответ на: комментарий от pon4ik

Ок, вот пример

vec(1,2,3)+vec(4,5,6) --> vec(5,7,9) 

Этого достаточно в доке, и это у меня работает и в плюсах и в питоне. Что бы это сделать компилируемым/запускаемым надо подключить библиотеку, что бы превратить в тест надо еще проверку добавить. Тому кто документацию читает смотреть 100500 раз на include че то там не нужно, а интимные подробности тестирования вообще ни к чему

AntonI ★★★★★
() автор топика
Ответ на: комментарий от aureliano15

Примеры пишутся для человека не для компилятора. Вопрос в том как их сделать понятными компилятору не загромождая код предназначенный для человека

AntonI ★★★★★
() автор топика
Ответ на: комментарий от pon4ik

Если про эту идею (не знаю как назвать её правильно), то конечно напишу. Но не сразу:-)

AntonI ★★★★★
() автор топика
Ответ на: комментарий от AntonI

Для такого только велосипед из того что я знаю по-крайней мере. Можно придумать какой-то формат мэппинга id:сниппет:вывод. Разбирать этот формат, и шаблонизатором вставлять и в доку, и в код проверочный. Такая вот инверсия зависимостей на ум приходит только, парсить доку на предмет кода имхо будет гораздо сложнее, а уж тем более понимать как это собрать и запустить.

В общем как по-мне - гораздо проще делать примеры использования API в одном файле несколько примеров с комментариями. Один типа файл с основами, остальные с какими-то узкими сценариями. Комментарии можно например как-то помечать(например нумеровать), и тогда ссылаться на них в доке. По-моему, в том же doxygen даже были какие-то наработки для такого подхода.

Что-то в духе:

//introductiion.cpp

#include <superduper.hpp> // [1] include main api header

int main() {

std::cout << vec(1, 2, 3) + vec(4, 5, 6) << std::endl; // [2] vectors sum supported
// outputs vec(5, 7 , 9)

};

Как пример, пусть и не полный.

pon4ik ★★★★★
()

Хотя, ты что-то там говорил про питон :) Для питона есть юпитер записные книжки ещё.

pon4ik ★★★★★
()
Ответ на: комментарий от AntonI

Что бы это сделать компилируемым/запускаемым надо подключить библиотеку,

Опция -l для gcc в Makefile.

что бы превратить в тест надо еще проверку добавить.

Её можно добавить в другом модуле.

Тому кто документацию читает смотреть 100500 раз на include че то там не нужно,

Почему? Очень полезная информация о том, где что лежит. В man’ах все примеры и инклюдами.

а интимные подробности тестирования вообще ни к чему

Сделать в директориях с примерами многомодульные программы, содержащие как минимум модули example.cxx (содержательная часть) и test.cxx (пример). Тот, кому нужно быстренько посмотреть, — посмотрит example. Тот, кто захочет изучить примеры поглубже, может посмотреть всё. В документацию включаются только example.cxx со ссылкой на подкаталог с полной версией теста и со всеми Makefile’ами и пр.

Примеры пишутся для человека не для компилятора.

Но примеры должны компилироваться и выполняться. Иначе их ценность довольно-таки сомнительна.

Вопрос в том как их сделать понятными компилятору не загромождая код предназначенный для человека

Если речь о том, чтобы убрать все инклуды и правила для сборки, а компилятор как-то сам обо всём догадался, то боюсь, что никак.

aureliano15 ★★
()
Ответ на: комментарий от pon4ik

юпитер записные книжки ещё

Юпитер, вроде-ж, только в браузере или vscode. При этом ЗАПРЕЩАЕТ использовать табы, типа только 4 пробела и хоть тресни.

thunar ★★★★★
()

Подпишусь на тему, хотя сам пока до нормальной автоматизации тестирования не дошёл.

thunar ★★★★★
()

В спеке коммонмарка примеры используются в качестве тестов. Но это очень специфичный кейз, я не верю что у тебя звезды так сойдутся. Там все-таки финальный продукт - спека а не код.

Бывает, иногда для текстовых фикстур можно сделать компактный формат, чтобы не прописывать километры тестов https://github.com/markdown-it/markdown-it/blob/master/test/fixtures/markdown-it/commonmark_extras.txt. Это более реалистичный вариант, но тоже не частый.

IMO, делать тесты по доке - скорее всего не взлетит. Не то чтобы я желал тебе провала, просто не видел чтобы кому-то удалось скрестить настолько разные области покрытия. Еще учти такой момент, с кастомным форматом. Очень большой риск сползти в библиотекостроительство. Потому что свой лисапед надо будет подкручивать на регулярной основе.

Зайди с другого конца. Тебе все равно половину тестов надо будет делать классическим образом. Сделай сначала их, а потом уже изобретай вундервафлю. Может передумаешь в процессе.

Vit ★★★★★
()

Надо обмазываться тестами, настоящими. Они очень помогают если ресёрч делаете, потому что где-то наговнокодив если алгоритм нетривиальный, а вы по сути только проверяете какую-то гипотезу (много вычислений, на бумажке нельзя), то можно получить ложный результат и отбросить её как неправильную/принять как правильную. Тесты не панацея, но такие ошибки уменьшают и заставляют не писать лапшу хоть немного.

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 1)
Ответ на: комментарий от peregrine

То что мы делаем мы довольно тщательно тестируем - просто это нифига не юнит-тесты. Это заморочное функциональное тестирование, которое плохо автоматизируется. Если кто то научился хорошо тестить что то в какой то предметной области, у нас по этому поводу обычно пишется статья.

По одной из основных библиотек у меня за 10 лет скопилось около 70ти того что можно с натяжкой считать юнит-тестами. Но их запуск не автоматизирован, они появляются когда нужно проверить че то базовое и лежат в отдельной директории мертвым грузом;-(

AntonI ★★★★★
() автор топика
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от Vit

Очень большой риск сползти в библиотекостроительство. Потому что свой лисапед надо будет подкручивать на регулярной основе.

Поскольку я это делаю в первую очередь для себя, то меня это не пугает;-)

AntonI ★★★★★
() автор топика
Ответ на: комментарий от pon4ik

Вот пример. В доках пишется (это .tex)

Модуль myvec предоставляет в C++ и Python функцию vec(x,y,z,...) создающие экземпляры класса Vec для которых традиционно перегружены операции сложения, вычитания, скалярного умножения и умножения на число слева и справа:
%@> vec0.cpp 
%#include "myvec.hpp"
%using namespace mylib;
%int main(){
%@> vec0.py
%@(vec0.py) from myvec import *
\begin{verbatim}
vec(1,2,3)+vec(4,5,6) --> vec(5,7,9)
vec(1,2,3)-vec(4,5,6) --> vec(-3,-3,-3)
vec(1,2,3)*vec(4,5,6) --> 32
vec(1,2,3)*2 --> vec(2,4,6)
2*vec(1,2,3) --> vec(2,4,6)
\end{verbatim}
%@(vec0.cpp) }
%@. *

После прогона утилитой mytest на выходе получаются файлы vec0.py и vec0.cpp которые она же и собирает/запускает.

vec0.py:

import mytest
from myvec import *
mytest.check((vec(1,2,3)+vec(4,5,6)), (vec(5,7,9)))
mytest.check((vec(1,2,3)-vec(4,5,6)), (vec(-3,-3,-3)))
mytest.check((vec(1,2,3)*vec(4,5,6)), (32))
mytest.check((vec(1,2,3)*2), (vec(2,4,6)))
mytest.check((2*vec(1,2,3)), (vec(2,4,6)))

Вот надо еще подумать как схлопнуть преамбулу в vec0.cpp, ну в принципе она же где то будет писаться выше по тексту - надо ее запомнить и брать оттуда. Ну и закрывающая скобка } выглядит убого, но это тоже борется.

AntonI ★★★★★
() автор топика
Последнее исправление: AntonI (всего исправлений: 2)
Ответ на: комментарий от AntonI

Ты кстати в курсе что когда подсознательно что-то очень не хочется делать, мозг начинает подсовывать «гениальные мысли», чтобы сбить с толку?

Если ты спрашиваешь про свое апи тестирования, то в зависимости от того, налажены у тебя «обычные» юнит-тесты или нет, ответы могут быть диаметрально противоположными :)

Начни с тех тестов, которые в любом случае не получится описать через документацию. Когда сделаешь - станет понятно, надо добавлять навороты или ты занимался самообманом.

Vit ★★★★★
()
Ответ на: комментарий от Vit

Начни с тех тестов, которые в любом случае не получится описать через документацию.

У себя я таких юнит-тестов придумать не могу. В смысле функциональных тестов, там обычно нужно запускать серию расчетов разной степени масштабности, строить пачки графиков и смотреть на них глазами. Кое кто из коллег частично автоматизирует это через make, по мне так это муторно. Если я придумаю как это автоматизировать в общем случае, то я буду вторым Д.Кнутом:-)

Но пока нет.

AntonI ★★★★★
() автор топика
Ответ на: комментарий от AntonI

У себя я таких юнит-тестов придумать не могу.

Например (это не все, но самое очевидное, что в голову пришло):

  • кидание ошибок.
  • доведение покрытия до 100%.

Я тебе как человек, который занимался «текстовыми тестами» (примеры приводил) утверждаю. Вероятность того, что твоя вундервафля решит ВСЕ необходимые вопросы, около нуля. Но чтобы понять и принять реальное положение дел, нужно наладить «обычные» юнит-тесты.

Vit ★★★★★
()
Ответ на: комментарий от Vit

100% покрытие - такой цели просто не стоит (и не будет). С ошибками отдельная история, да.

Дело в том, что у меня подобная вундервафля уже работала когда то, но она оказалась слишком сложной/неудобной и не пошла. Тем не менее сейчас мне что то такое нужно…

Но чтобы понять и принять реальное положение дел, нужно наладить «обычные» юнит-тесты.

Я пока для себя в этом не вижу смысла. Но я тебя услышал, спасибо;-)

AntonI ★★★★★
() автор топика
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от AntonI

100% покрытие - такой цели просто не стоит (и не будет).

Это может быть не в масштабах библиотеки, а в масштабах какого-нибудь подмодуля.

Дело не в магических 100%, а в том, что тебе обязательно нужен coverage report для оценки качества, и ты можешь захотеть покрыть пропущенный бранч, не засирая документации.

Vit ★★★★★
()
Ответ на: комментарий от Vit

ты можешь захотеть покрыть пропущенный бранч, не засирая документации.

Никто не запрещает мне испольщовать обычные юнит-тесты, и никто не заставляет втыкать фрагмент документации на этот бранч в общую доку или вообще куда бы то ни было.

Мне очень нравится концепция литературного программирования Кнута, у нас решение любой задачи начинается с написания формулок на бумашке/доске, я обычно делаю это в техе. Это можно никому не показывать, но если ты не можешь это записать то ты не можешь это закодить. В этом смысле тесты требуют описания не меньше, если не больше чем сам код, а втыкать в формулы в комменты в коде как то не очень.

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

В общем эта вундервафля робкая попытка чуть сблизить описание, код и то как код запускается (это пока за кадром). Пока что я не могу это сформулировать четко, все на уровне ощущений.

AntonI ★★★★★
() автор топика
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от AntonI

А говорил не хочешь свой фреймворк тестовый писать - вот уже начал. Такой себе BDD с никому кроме тебя не понятной нотацией. Не говорю, что плохо и не взлетит, но сиё придётся развивать и поддерживать, чтобы оно не издохло в зародыше.

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

pon4ik ★★★★★
()
Ответ на: комментарий от Vit

Ты кстати в курсе что когда подсознательно что-то очень не хочется делать, мозг начинает подсовывать «гениальные мысли», чтобы сбить с толку?

Думал только у меня так :)

pon4ik ★★★★★
()

Я занимаюсь разработкой всякого академического софта, и у нас юнит-тестирование делать не принято.

Немного оффтоп, но напишу.

На сколько я понимаю, и польза от ЮТ в академическом софте может быть ниже, чем в том софте, для которого все эти книги о ЮТ написаны. Потому что ЮТ’абельность идет рука об руку с модульностью и наличием маленьких методов/функций, которые в первую очередь, удовлетворяют неким критериям хорошо структурированного кода. Например, может иметь смысл вынести 2+2 в отдельный метод, и тогда этот метод можно будет просто протестировать в соответствующем ЮТ.

Для академического кода эти критерии удачной структуризации исходника могут быть совсем другими, нежели для «типичного корпоративного софта». Например, некий вычислительный метод, может иметь код с функцией итерации на два-три экрана, и для данной предметной области это и будет удобно, потому что данная вычислительная математика более обозрима именно в таком виде, а не в виде кучи разных функций и вспомогательных процедурочек или методов. И тогда ЮТ будет сложно и писать, и поддерживать.

Во-вторых, сама польза от ЮТ может быть минимальная. Скажем, рассчитывается эволюция какой-нибудь напряженности поля (чисто гипотетический пример) и вот, допустим есть какая-то функция, которая рассчитывает эту напряженность в конкретной точке пространства. И что это значение в точке даст, если там, например, вместо 1.0 будет 1.1. Может быть это важно, а может быть вообще ни о чем не скажет, т.к. выяснить, поломался алгоритм или нет, можно только рассмотрев всю картину по всему пространству точек или даже в динамике. Т.е. может так быть, что систему можно тестировать только всю целиком, и тогда это уже не ЮТ.

А в этих книгах о ЮТ рассматриваются примерчики, которые со своей дуболомной предметной областью легко ложатся на ООП и разбитие кода на легкотестируемые единицы. И можно четко отделить, когда тест провалился, а когда выполнился успешно (например, если строку надо разбить на слова, а она разбивается неправильно, это некорректное поведение очевидно).

Может быть, более эффективно все тестировать сразу: подбирать типовые входные данные, прогонять весь алгоритм, прогонять заранее заготовленные скрипты, которые будут выяснять корректность алгоритма по неким критериям на основе всех результатов, а не результатов отдельных функций.

seiken ★★★★★
()
Ответ на: комментарий от AntonI

Тому кто документацию читает смотреть 100500 раз на include че то там не нужно, а интимные подробности тестирования вообще ни к чему

Как вариант ещё можно использовать разный размер шрифта. include и прочий int main() делать мелким, а важное крупным.

Например: https://imgur.com/a/kdHkQJu (можно ещё больше разницу в размере сделать…)

fsb4000 ★★★★★
()
Ответ на: комментарий от seiken

да, все так, спасибо за хорошую формулировку.

Может быть, более эффективно все тестировать сразу: подбирать типовые входные данные, прогонять весь алгоритм…

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

AntonI ★★★★★
() автор топика
Ответ на: комментарий от fsb4000

Но все равно этот код надо писать многократно. А хотелось бы написать один раз максимум.

AntonI ★★★★★
() автор топика
Ответ на: комментарий от pon4ik

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

Да, уже. Эти –> можно внутри цикла точно так же размещать. Я что то похожее делаю когда контейнеры тестирую, это вот кстати та область где без юнит тестов даже у нас никак.

AntonI ★★★★★
() автор топика
Ответ на: комментарий от seiken

> Немного оффтоп, но напишу.

Исключительно верное замечание! У меня сложилось ровно такое же впечатление.

И в части удачной структуризации, и для пользы юнит-тестирования (хотя признаюсь что юнит-тестирование даже метровой палочкой не ковырял)

sshestov ★★
()
Последнее исправление: sshestov (всего исправлений: 1)
Ответ на: комментарий от AntonI

Тому кто документацию читает смотреть 100500 раз на include че то там не нужно, а интимные подробности тестирования вообще ни к чему

Практика показывает, что интимные подробности может быть и не нужны, но include являются важной частью. В dlang сделано именно так, как вы описываете или очень похоже. Там юниттесты можно писать прямо в коде без лишних телодвижений. Пишите, например, класс, после него пишете документированный юниттест и этот юниттест автоматически попадает в документацию класса. Пример

Так вот проблема в том, что в этом юниттесте нет import'ов (в D import вместо include, потому что там нормальные модули). И когда пользователь находит эту документацию у него часто не компилируется пример, потому что import'ы нужно прописывать самому. Это реально раздражает. Особенно если по результатам тестирования данный пример кода отбраковывается по каким-то причинам, но ты, тем не менее, время потратил на поиск нужного модуля. Далеко не смертельно, конечно, но все же.

Краткое резюме - include в примерах нужны, как минимум иногда.

yetanother ★★
()
Ответ на: комментарий от AntonI

Вот вроде пример хороший, но по-моему немного искусственный. Во-первых тестируется сильно базовая функциональность, а во-вторых можно ли еще других похожих и нужных примеров придумать?

sshestov ★★
()
Ответ на: комментарий от seiken

Может быть, более эффективно все тестировать сразу: подбирать типовые входные данные, прогонять весь алгоритм, прогонять заранее заготовленные скрипты, которые будут выяснять корректность алгоритма по неким критериям на основе всех результатов, а не результатов отдельных функций.

This. На одних юниттестах далеко не уедешь и они необходимы, но недостаточны.

yetanother ★★
()
Ответ на: комментарий от pon4ik

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

Самый простой способ - записать навязчивую мысль куда-то в тикет. Второй вариант - найти подмножество, где все равно надо делать «по старому» и убедить себя что избежать все равно не получится.

Напрямую подсознанию не прикажешь, приходится искать обходные способы.

Vit ★★★★★
()
Ответ на: комментарий от yetanother

Обычно в доках пишут - это живёт в таком то модуле/хидере. Можно один раз написать пример инклюдов. ИМНО этого достаточно

AntonI ★★★★★
() автор топика
Ответ на: комментарий от sshestov

В цикле прохожу контейнер и проверяю что там лежит именно то что нужно например.

Вообще конечно еще нужна проверка попадания в диапазон, если мы что то приближённо считаем.

AntonI ★★★★★
() автор топика
Ответ на: комментарий от AntonI

Никто не запрещает мне испольщовать обычные юнит-тесты, и никто не заставляет втыкать фрагмент документации на этот бранч в общую доку или вообще куда бы то ни было.

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

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

Могу только сказать, что в подобной ситуации я сам упарывал всякий ад, и если бы мне сказали что страдаю фигней - не поверил бы. В этом вся проблема - непонятно как объяснить бегинерам, что начинать с лисапедов плохая идея.

Vit ★★★★★
()
Последнее исправление: Vit (всего исправлений: 1)
Ответ на: комментарий от AntonI

Обычно в доках пишут - это живёт в таком то модуле/хидере. Можно один раз написать пример инклюдов. ИМНО этого достаточно

Ну это просто мое наблюдение из практики. Мое имхо - все примеры должны быть самодостаточны. Т.е. взял, просто скопировал пример, и он должен запуститься без дополнительных телодвижений. Каждое лишнее телодвижение уменьшает вероятность что с примером будут работать дальше. Написать один include на все примеры можно конечно, но либо примеры должны быть тривиальные, либо include должен включать все возможные хидеры для всех примеров. Это тоже все такое сомнительное. Лучше всего в каждый пример включать весь необходимый набор include, только прятать его под спойлер что ли. Т.е. чтобы человек и не тратил время на список заголовочных файлов, но и мог его получить при необходимости.

yetanother ★★
()
Ответ на: комментарий от xor2003

Цели разные. В твоем случае основной продукт - это текст (книжка). Я приводил пример коммонмарковской спеки - с ней тоже такой подход прокатил.

Но автору нужен код + дока. Это похоже только с виду. Если будешь доводить примеры в доке до высокого ковераджа - люди глаза сломают.

IMHO наверное было бы проще написать тесты «как обычно» а снипеты из доки привернуть сбоку, для контроля целостности самой доки (но не для тестирования самой библиотеки).

Это конечно очень приблизительно, и по ходу можно будет подрихтовать. Главное не забывать сами тесты контролировать через коверадж.

Vit ★★★★★
()
Ответ на: комментарий от seiken

И можно четко отделить, когда тест провалился, а когда выполнился успешно (например, если строку надо разбить на слова, а она разбивается неправильно, это некорректное поведение очевидно).

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

peregrine ★★★★★
()
Ответ на: комментарий от Vit

У ТС-а немного необычные задачи. Их плохо покрывают типичные инструменты для клепания вебформочек. Код там ужасен и сложен, как и сами алгоритмы, красивые абстракции не родятся, к тому же денег там мало крутится, так что никаких нормальных инструментов нету, лучшее что есть, это юпитер, но он ужасен ИМХО.

peregrine ★★★★★
()
Ответ на: комментарий от peregrine

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

Тока щас доперло что интерполяция от фурье образа и взятие модуля некоммутируют. Если сначала интерполировать (сетка на сфере грубая) а потом взять модуль то провалы есть, если сначала модуль взять а потом интерполировать то все ОК. Ну и какие тут юнит-тесты? Обнять и плакать.

AntonI ★★★★★
() автор топика
Ответ на: комментарий от AntonI

Я когда писал сложную (для меня, может для кого-то она простая) шляпу, пришёл к выводу что надо данные которые поступают на вход каждую более-менее сложную и законченную в каком-то смысле операцию над ними выгружать (потому что у меня один этап обработки учебных данных занимал сутки) и смотреть глазками (если нельзя автоматически что-то в них проверять или даже сложно догадаться что может пойти не так), возможно через какую-то визуализацию, иногда BI и их подходы с инструментами можно натянуть сверху, иногда нельзя, я за сутки пока данные лопатились писал какую-то примитивную визуализацию под конкретный пример, благо данные через json у меня шли. Хотя меня это не особо спасало от того что мне всё пришлось переписать 3 раза с исправлением алгоритма (один раз я накосячил в теории, один раз реализовал не то что написал в формулах и пришлось всё переделывать с определённого этапа обработки, так как данные приняли другой вид и потребовали другой метод и один раз когда проверил что всё работает как надо переписал на автоматический вариант, потому что уже в конце мне было удобнее финальный рассчёт в экселе делать с выгруженного csv, чем на голом питоне), потому что там диаграммы проще и быстрее строить, чем на голом питоне, да и поменять некоторые значения в матрице чтобы посмотреть что из этого выйдет сильно проще.

peregrine ★★★★★
()
Ответ на: комментарий от peregrine

Когда идет большой расчет на кластере, на много дней, каждый день заходишь и проверяешь что там и как. Степень завершения, что насчиталось (выборочно) и тд.

AntonI ★★★★★
() автор топика
Ответ на: комментарий от peregrine

Если мысль сформулировать нельзя, то смена языка не поможет.

Здесь простой случай - хочется юнит-тестов, но встроенных в документацию. IMO при реализуемости задачи, это все равно очень неудачное сочетание.

Я бы ставил вопрос иначе - «действительно ли нужно использовать документацию для тестирования, или достаточно контролировать целостность примеров».

PS. Хотя еще есть вероятность, что мы можем вкладывать совершенно разные понятия в термины «юнит-тесты» и «документация». Но вроде на одной волне.

Vit ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.