1. Если сессия устарела (а этого ISessionProvider не знает — узнаем когда сделаем запрос) — то вызвать resetSession.
2. Может быть два одновременных запроса и каждый вызовет resetSession.
3. resetSession может быть вызван в момент, когда первый запрос уже начал восстановление сессии (а так же когда начал, почти начал, закончил, почти закончил).
4. Нельзя восстанавливать сессию повторно, если уже раз восстановили.
Допустим вы сделали решение. Как вы его будете тестировать?
17.02.25 05:14: Перенесено из 'Тестирование приложений'
S>Нужно чтобы:
S>1. Если сессия устарела (а этого ISessionProvider не знает — узнаем когда сделаем запрос) — то вызвать resetSession.
Это логика клиентского кода — тестами на провайдер это не покроется. Но если хочешь тестировать клиентский код — пиши мок на свой провайдер, возвращай "сессися протухла" из RetrieveSession, и удостоверься, что ResetSession вызван.
S>2. Может быть два одновременных запроса и каждый вызовет resetSession.
Тогда что должно произойти? Сформулируй условия, а потом будем их проверять.
S>3. resetSession может быть вызван в момент, когда первый запрос уже начал восстановление сессии.
Тогда что должно произойти? Сформулируй условия, а потом будем их проверять.
S>4. Нельзя восстанавливать сессию повторно, если уже раз восстановили.
В тесте два раза вызываешь ResetSession и проверяешь отсутствие исключений в первый раз, и ожидаемое исключение — во второй.
S>Допустим вы сделали решение. Как вы его будете тестировать?
Здравствуйте, Doom100500, Вы писали:
S>>4. Нельзя восстанавливать сессию повторно, если уже раз восстановили. D>В тесте два раза вызываешь ResetSession и проверяешь отсутствие исключений в первый раз, и ожидаемое исключение — во второй.
Зачем исключение? Просто нужно ждать пока завершится первый запрос — и не делать запрос повторно. Вроде очевидно же
Но при этом нужно убедиться что правильно будет не зависимо в какой момент вызовешь ResetSession — до запроса, в момент запроса, сразу после запроса.
Тут проблема вот в чем. Нужно как-то протестить что правильно расставлены блокировки, атомарные операции, нет кеширования в памяти (volatile где нужно) и пр. Т.е. даже правильный тест — может не всегда а лишь с определенной вероятностью обнаружить проблему. Но и даже правильный тест написать — так же под вопросом.
Здравствуйте, Shmj, Вы писали:
S>Здравствуйте, Doom100500, Вы писали:
S>>>4. Нельзя восстанавливать сессию повторно, если уже раз восстановили. D>>В тесте два раза вызываешь ResetSession и проверяешь отсутствие исключений в первый раз, и ожидаемое исключение — во второй.
S>Зачем исключение? Просто нужно ждать пока завершится первый запрос — и не делать запрос повторно. Вроде очевидно же
Пишешь мок на свой интерфейс и проверяешь в реализации мока проверку, что запрос не завершён. Это условия падения теста. А тестируется тут клиентский код, поэтому мокаем интерфейс и пишем туда тестовую логику. Это разве не очевидно? НО тест упал, и что твоя апликация должна сделать? У тебя нет никакого фидбэка что должно произойти, если это условие не выполнится, поэтому исключение. Разве ЭТО не очевидно?
S>Но при этом нужно убедиться что правильно будет не зависимо в какой момент вызовешь ResetSession — до запроса, в момент запроса, сразу после запроса.
S>Тут проблема вот в чем. Нужно как-то протестить что правильно расставлены блокировки, атомарные операции, нет кеширования в памяти (volatile где нужно) и пр. Т.е. даже правильный тест — может не всегда а лишь с определенной вероятностью обнаружить проблему. Но и даже правильный тест написать — так же под вопросом.
Определись кто должен быть ответственным за соблюдением этих условий (провайдер или клиентский код) и что должно произоити, если услоия не выполняются. И это будем тестировать.
ПС.
постарайся не употреблять манупулятивные выражения типа "Вроде очевидно же". Оставь это для конспирологов. А здесь технический вопрос и технические детали, которых ты не предоставил, и подкидываешь по ходу. Имей уважение хотя-бы к тем, у кого спрашиваешь.
Здравствуйте, Doom100500, Вы писали:
D>Пишешь мок на свой интерфейс и проверяешь в реализации мока проверку, что запрос не завершён. Это условия падения теста. А тестируется тут клиентский код, поэтому мокаем интерфейс и пишем туда тестовую логику. Это разве не очевидно? НО тест упал, и что твоя апликация должна сделать? У тебя нет никакого фидбэка что должно произойти, если это условие не выполнится, поэтому исключение. Разве ЭТО не очевидно?
Нам нужно вот что протестить — что провайдер не будет делать повторные запросы на восстановление сессии, если такой запрос уже запущен. При этом провайдер и исключения выбрасывать не должен — а просто ждать и вернуть результат после ожидания.
S>>Тут проблема вот в чем. Нужно как-то протестить что правильно расставлены блокировки, атомарные операции, нет кеширования в памяти (volatile где нужно) и пр. Т.е. даже правильный тест — может не всегда а лишь с определенной вероятностью обнаружить проблему. Но и даже правильный тест написать — так же под вопросом.
D>Определись кто должен быть ответственным за соблюдением этих условий (провайдер или клиентский код) и что должно произоити, если услоия не выполняются. И это будем тестировать.
Провайдер, конечно — не должен делать повторный запрос, если уже запущен один из запросов на обновление сессии.
Но тут вот в чем дело. Если мы запустим 2 запроса — то скорее всего все сработает. А если 200 одновременно и долбить минуту — может быть косяк и вылезет.
Еще один из негативных сценариев — провайдер не сделает ни одного запроса вообще.
З.Ы.
По идее при сбросе сессии — еще бы передавать какую именно сессию сбрасываем, а то иначе никак не понять — вдруг сбросим новую сессию, которую только что восстановили (уже после запроса на обновление).
Здравствуйте, Shmj, Вы писали:
S>Здравствуйте, Doom100500, Вы писали:
D>>Пишешь мок на свой интерфейс и проверяешь в реализации мока проверку, что запрос не завершён. Это условия падения теста. А тестируется тут клиентский код, поэтому мокаем интерфейс и пишем туда тестовую логику. Это разве не очевидно? НО тест упал, и что твоя апликация должна сделать? У тебя нет никакого фидбэка что должно произойти, если это условие не выполнится, поэтому исключение. Разве ЭТО не очевидно?
S>Нам нужно вот что протестить — что провайдер не будет делать повторные запросы на восстановление сессии, если такой запрос уже запущен. При этом провайдер и исключения выбрасывать не должен — а просто ждать и вернуть результат после ожидания.
S>>>Тут проблема вот в чем. Нужно как-то протестить что правильно расставлены блокировки, атомарные операции, нет кеширования в памяти (volatile где нужно) и пр. Т.е. даже правильный тест — может не всегда а лишь с определенной вероятностью обнаружить проблему. Но и даже правильный тест написать — так же под вопросом.
D>>Определись кто должен быть ответственным за соблюдением этих условий (провайдер или клиентский код) и что должно произоити, если услоия не выполняются. И это будем тестировать.
S>Провайдер, конечно — не должен делать повторный запрос, если уже запущен один из запросов на обновление сессии.
То есть провайдер — это обёртка. Тогда он и есть этих сессий. Вот то, что оборачиваешь — мокаешь и пишешь там тестовую логику, описанные выше. Когда ты говоришь дождаться завершения предыдущего запроса — а если дедлок, есть ли таймауты. Как это обрабатываем? Что должно произойти? Вот это и тестируем.
S>Но тут вот в чем дело. Если мы запустим 2 запроса — то скорее всего все сработает. А если 200 одновременно и долбить минуту — может быть косяк и вылезет.
Определись или ожидание или 200 одновременно. Количество одновременных запросов должно быть внешним параметром. Если есть требования но одновременные запросы, то в моке делаем счётчик и проверяем.
S>Еще один из негативных сценариев — провайдер не сделает ни одного запроса вообще.
В моке ожидаешь вызовов. Если не было — тест падает. Такое есть в популярных либах для тестов.
Здравствуйте, Doom100500, Вы писали:
S>>Провайдер, конечно — не должен делать повторный запрос, если уже запущен один из запросов на обновление сессии.
D>То есть провайдер — это обёртка. Тогда он и есть этих сессий. Вот то, что оборачиваешь — мокаешь и пишешь там тестовую логику, описанные выше.
Но тут нужно угадать по микросекундам — чтобы сделать попытку повторного запроса в нужный момент. Вдруг там не правильная проверка внутри.
Или же просто трезвым взглядом оценить что все ОК без всяких тестов. А вот как чтобы идеальный тест...
D>Когда ты говоришь дождаться завершения предыдущего запроса — а если дедлок, есть ли таймауты. Как это обрабатываем? Что должно произойти? Вот это и тестируем.
Ну, таймаут просто отразится на SessionResult.
А если дедлок — то что можно сделать — просто зависинет и все. Это и нужно проверить что дедлок не возникает.
D>Определись или ожидание или 200 одновременно.
Могут вызвать 200 одновременно, и 199 должны ждать а 1 обновлять сессию. Потом все 199 должны воспользоваться результатом того счастливчика, который начал первым.
D>Количество одновременных запросов должно быть внешним параметром. Если есть требования но одновременные запросы, то в моке делаем счётчик и проверяем. D>В моке ожидаешь вызовов. Если не было — тест падает. Такое есть в популярных либах для тестов.
Тут проблема в том что все может зависеть от промежутков (в микросекундах) между вызовами. Или просто на глаз посмотреть что все ОК, понимать что тесты ничего не гарантируют.
К примеру, если вызов в момент выполнения запроса — ОК. А если вызов точно после завершения запроса (когда некий флаг обновили, но результат еще не установили) — то пойдет повторный запрос. Может же быть и такой сценарий.
Получается только глазом смотреть и давать гарантию под честное слово без всяких тестов?
Здравствуйте, Shmj, Вы писали:
S>К примеру, такой кейс — восстановление сессии. S>interface ISessionProvider { S>Допустим вы сделали решение. Как вы его будете тестировать?
Вот сделай решение, покажи, будем посмотреть как его тестировать. Интерфейсы не тестируются, тестируется реализация.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, Shmj, Вы писали:
S>Здравствуйте, Doom100500, Вы писали:
S>>>Провайдер, конечно — не должен делать повторный запрос, если уже запущен один из запросов на обновление сессии.
D>>То есть провайдер — это обёртка. Тогда он и есть этих сессий. Вот то, что оборачиваешь — мокаешь и пишешь там тестовую логику, описанные выше.
S>Но тут нужно угадать по микросекундам — чтобы сделать попытку повторного запроса в нужный момент. Вдруг там не правильная проверка внутри.
S>Или же просто трезвым взглядом оценить что все ОК без всяких тестов. А вот как чтобы идеальный тест...
D>>Когда ты говоришь дождаться завершения предыдущего запроса — а если дедлок, есть ли таймауты. Как это обрабатываем? Что должно произойти? Вот это и тестируем.
S>Ну, таймаут просто отразится на SessionResult.
S>А если дедлок — то что можно сделать — просто зависинет и все. Это и нужно проверить что дедлок не возникает.
D>>Определись или ожидание или 200 одновременно.
S>Могут вызвать 200 одновременно, и 199 должны ждать а 1 обновлять сессию. Потом все 199 должны воспользоваться результатом того счастливчика, который начал первым.
D>>Количество одновременных запросов должно быть внешним параметром. Если есть требования но одновременные запросы, то в моке делаем счётчик и проверяем. D>>В моке ожидаешь вызовов. Если не было — тест падает. Такое есть в популярных либах для тестов.
S>Тут проблема в том что все может зависеть от промежутков (в микросекундах) между вызовами. Или просто на глаз посмотреть что все ОК, понимать что тесты ничего не гарантируют.
S>К примеру, если вызов в момент выполнения запроса — ОК. А если вызов точно после завершения запроса (когда некий флаг обновили, но результат еще не установили) — то пойдет повторный запрос. Может же быть и такой сценарий.
S>Получается только глазом смотреть и давать гарантию под честное слово без всяких тестов?
Класс. Требования уже проясняются. Подумай ещё. У тебя выразится дезигн, а тесты сами придут исходя из требований.
Здравствуйте, Doom100500, Вы писали:
D>Класс. Требования уже проясняются. Подумай ещё. У тебя выразится дезигн, а тесты сами придут исходя из требований.
Требования тут во многом интуитивно понятны — просто нужно восстановить сессию, если она устарела.
Тут в другом вопрос — как проверить что все корректно будет работать в многопоточной среде?
Здравствуйте, ·, Вы писали:
S>>Допустим вы сделали решение. Как вы его будете тестировать? ·>Вот сделай решение, покажи, будем посмотреть как его тестировать. Интерфейсы не тестируются, тестируется реализация.
Ну если TDD — сначала пишем тест, потом реализацию нам GPT сам пишет.
Но тут вопрос — как проверить что реализация действительно рабочая?
Функционал очень простой — если сессия устарела — вызываем метод ResetSession и потом получаем новую сессию RetrieveSession. Но нюанс — +- в одно время ResetSession могут вызвать 200 методов и так же затем вызывать RetrieveSession — а создать сессию нужно только 1 раз.
Здравствуйте, Shmj, Вы писали:
S>·>Вот сделай решение, покажи, будем посмотреть как его тестировать. Интерфейсы не тестируются, тестируется реализация. S>Ну если TDD — сначала пишем тест, потом реализацию нам GPT сам пишет.
Ну так тогда у GPT и спрашивай. Сюда зачем пришёл?
S>Но тут вопрос — как проверить что реализация действительно рабочая?
Многопоточка в общем случае не тестируется никак. Поэтому сводят к каким-то более ограниченным примитивам. Скажем, у тебя там Task, вот от него и пляшем. Реализация будет куда-то лазить на новой сессией, вот это место и мокаем тестом в виде тамошнего Task, который завершаем в разные моменты и тестируем что получается.
Так что ещё раз. Начни с реализации, а там поглядим.
S>Функционал очень простой — если сессия устарела — вызываем метод ResetSession и потом получаем новую сессию RetrieveSession.
Какой-то корявый интерфейс. А если результат RetrieveSession тоже устареет? Начни с правильного дизайна.
S>Но нюанс — +- в одно время ResetSession могут вызвать 200 методов и так же затем вызывать RetrieveSession — а создать сессию нужно только 1 раз.
Ты пытаешься выжать гарантию корректности из blackbox тестирования? Ну успехов.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, Shmj, Вы писали:
S>Здравствуйте, Doom100500, Вы писали:
D>>Класс. Требования уже проясняются. Подумай ещё. У тебя выразится дезигн, а тесты сами придут исходя из требований.
S>Требования тут во многом интуитивно понятны — просто нужно восстановить сессию, если она устарела.
S>Тут в другом вопрос — как проверить что все корректно будет работать в многопоточной среде?
Чтобы проверять многопоточную среду — надо определить требования к этой среде.
— Кто управляет потоками, где они создаются, где уничтожаются?
— Какое состояние у этих потоков, как его можно получить?
— Как осуществляется коммуникация между этими потоками?
Как только научишся в своей кодовой базе иметь контроль над потоками (а не ожидать магии от фреймворка, или кода, порождённого известным чатом) тогда тебе все ответы сами придут.
Ты привёл интерфейс с двумя методами. Да, у них есть названия, но требования не внятные (звучат как "сделай мне хорошо при условии, что я знаю чего хочу").
По мере обсуждений требований к твоему провайдеру, вдруг возникают требования и к клиентскому коду, и к тому, что стоит за этим провайдером.
Тесты обсуждаются когда дизайн готов. А так мы тут придумываем дизайн вместо обсуждения тестов.
Или ты просто на эффективного менеджера переучился (уж очень постановка задач похожа).
Здравствуйте, Doom100500, Вы писали:
D>Чтобы проверять многопоточную среду — надо определить требования к этой среде. D>- Кто управляет потоками, где они создаются, где уничтожаются? D>- Какое состояние у этих потоков, как его можно получить? D>- Как осуществляется коммуникация между этими потоками?
Вы как-то приняли позу учителя и начали учить нерадивого ученика теории, без конкретики. Сводя к малозначимым вопросам.
Т.е. порождает потоки — очевидно вызывающий код. Как бы сводите на малозначимое.
На каком ЯП вам удобнее привести пример, чтобы получилась конкретика?
Здравствуйте, DiPaolo, Вы писали:
DP>Интересный у тебя способ просить совета у коллег. Настолько интересный, что отвечать не хочется. Еще и в священный войнах почему-то... DP>Ты просто имей ввиду, как это со стороны смотрится. Уверен, не у меня одного так.
А вот реально встречали ли тесты для таких кейсов — именно для многопотока, а не просто в одном потоке?
Многопоток скорее просто смотрится на глаз и просто делается вывод что вроде все ОК.
Здравствуйте, Shmj, Вы писали:
S>Допустим вы сделали решение. Как вы его будете тестировать?
Решением такой задачи является некоторая state machine. Сначала мы формально доказываем, что дизайн state machine соответствует требованиям (сохраняет инварианты); затем просто аккуратно проверяем, что реализация машины соответствует дизайну.
BlackBox тестирование таких решений — прямая дорога в ад, по очевидным причинам. В частности, переход в конце девяностых к многоядерным процессорам выявил множество многолетних багов в реализациях многопоточки, которые были скрыты особенностями одноядерной многозадачности.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Doom100500, Вы писали:
D>Это самые значимые вопросы. Это архитектура. TDD — это когда архитектура уже есть, а не способ её разработки.
Выше чел. правильно написал:
Решением такой задачи является некоторая state machine. Сначала мы формально доказываем, что дизайн state machine соответствует требованиям (сохраняет инварианты); затем просто аккуратно проверяем, что реализация машины соответствует дизайну.
Т.е. по сути авто-тесты — вряд ли возможны.
На каком ЯП вам привести пример, чтобы вы поняли свою ошибку?