В iOS приложении Яндекс.Диска то же есть лента. Самое печальное — невозможно показать кому-то конкретный файл (например документ или билет) не засветив последние загруженные фото.
Классические юнит тесты (те что общительные) проверяли состояние (до/после), что зачастую требовало раскрытия внутреннего состояния юнита и нарушало инкапсуляцию.
Моки, на мой взгляд, стали революцией в юнит тестировании, так как позволили писать тесты только для публичного интерфейса юнита заменив проверку состояния на проверку поведения. Последняя предъявляет более высокие требования к дизайну делая код чище/лучше (можно получить код соответсвующий SOLID принципам ничего не зная о последних).
В TDD c изолированными (Solitary) тестами фаза рефакторинга практически отсутствует (если тесты и юниты достаточно простые) и заменяется проектированием. В классических тестах требования к дизайну минимальны (главное получить нужное состояние на выходе, что можно сделать бесчисленным количеством способов), и в фазе рефакторинга каждый улучшает код как может или не делает этого вовсе. Моки можно сделать строгими задавая ожидаемое поведение, любое неожиданное поведение (вызов не ожидаемого метода или метода с параметром отличным от ожидаемого) приведет к провалу теста. Тесты состояния менее чувствительны к сайд эффектам, так как зависимости могут быть неявными (DI — необязателен). Можно изменить поведение на некорректное таким образом, что тест состояния останется зеленым делая его практически бесполезным. Чтобы этого избежать тест должен запускаться на множестве входных данных, что делает его медленнее.
В связи со всем вышесказанным считаю классические юнит тесты устаревшим подходом, по которому, однако, написано очень много материалов (особенно от авторитетных светил вроде Дяди Боба), что вносит путаницу и уводит новичков от прогресса.
Упущенный но существенный момент — сложность юнита. Чем она меньше, тем проще написать тесты, тем менее хрупкими они будут, тем быстрее они будут исполняться. Ну и как следствие, сложный тест — индикатор («запашок») плохого дизайна.
Вы несколько ушли от темы, при этом проигнорировали мои доводы. Мой вопрос больше философский, — где проходит граница между черным и белым ящиками?
Юнит-тест тестирует не только публичный интерфейс, но и взаимодействие с зависимостями (кроме модулей без зависимостей). Зависимости в чистом SOLID скрыты от клиента абстракцией (Java итерфейсом или абстрактным классом). Интерфейс не задает поведения, он лишь определяет контракт взаимодействия. Поведение задает конкретная реализация интерфейса. Тест эту реализацию проверяет с помощью моков зависимостей. Зависимости — часть внутреннего (скрытого от клиента) устройства модуля, поэтому юнит-тесты считаются тестами белого ящика.
Ну это для клиента он black-box, так как клиент ожидает только выполнение контракта (интерфейс, возможные исключения, нулабилити). А является ли модуль black-box для юнит-теста? В моем понимании — нет, не является, так как юнит тест должен в точности проверить детали реализации. Максимум, что можно отнести к black-box — это использование стандартных коллекций и строк, — то что нет смысла инжектить и мокать. Т.е., по сути, любой тест состояния можно отнести к тестированию black-box, но тест поведения (через моки) — это уже white-box. Последних в моей практике на порядок больше.
Это уже не юнит-тестирование. Почему-то все путают публичный API програмного компонента (библиотеки) и публичный интерфейс модуля. Последний может оставаться частью приватного API, но при этом протестированным юнит-тестами. А вот тестировать приватные методы модуля — действительно плохая практика, в этом случае лучше пересмотреть дизайн и вынести логику в отдельный тестируемый модуль.
Есть подозрение на некий процесс отделение/обновление эпителия слизистой, который запускается во время сна. Еще одна догадка — прекращение слюноотделения и пересыхание слизистой, но хотелось бы подробностей по этому поводу.
Давно мучает вопрос: что меняется в полости рта во время сна? После короткого сна (15 — 60 минут в любое время суток) ощущается дискомфорт и странный привкус во рту, который не уходит даже после чистки. После здорового, продолжительного сна ничего подобного нет.
Тут еще нужно обратить внимание на особенность работы UIImage и UIImageView. У первого есть внутренний кеш, но при первом рендеринге он конечно же пуст, и загрузка изображения в память происходит в главном потоке, что добавляет тормозов даже для небольших изображений на современных устройствах. Выход — предварительный рендеринг UIImage в битмап контексте на фоновом потоке для заполнения кеша.
И никто не помнит, что он еще и спрашивает пароль от вашей почты!
Пример
И раньше он делал это мимикрируя под форму логина, это ж чистой воды фишинг! Меня спасло то, что пароли разные и браузер подставил пароль от LinkedIn'а, и я не сразу понял, почему логин фейлится.
Проблема была в том, что конструктора реактора отрицали наличие в нем «уязвимости». На момент аварии о ней никто толком не знал, несмотря на то, что она себя уже проявляла ранее.
Хорошо, далее вопрос, что входит в таком случае в управление циклом жизни своего view?
Показывать и прятать дочерние VC — хорошо, основываясь на чем? На изменении состояния модели?
Обычно у вью контроллера есть свое внутреннее состояние, например selectedIndex у UITabBarController, еще он является делегатом UITabBar. Можно и модель, но она должна быть очень простой сущностью (не доменная модель).
Моки, на мой взгляд, стали революцией в юнит тестировании, так как позволили писать тесты только для публичного интерфейса юнита заменив проверку состояния на проверку поведения. Последняя предъявляет более высокие требования к дизайну делая код чище/лучше (можно получить код соответсвующий SOLID принципам ничего не зная о последних).
В TDD c изолированными (Solitary) тестами фаза рефакторинга практически отсутствует (если тесты и юниты достаточно простые) и заменяется проектированием. В классических тестах требования к дизайну минимальны (главное получить нужное состояние на выходе, что можно сделать бесчисленным количеством способов), и в фазе рефакторинга каждый улучшает код как может или не делает этого вовсе. Моки можно сделать строгими задавая ожидаемое поведение, любое неожиданное поведение (вызов не ожидаемого метода или метода с параметром отличным от ожидаемого) приведет к провалу теста. Тесты состояния менее чувствительны к сайд эффектам, так как зависимости могут быть неявными (DI — необязателен). Можно изменить поведение на некорректное таким образом, что тест состояния останется зеленым делая его практически бесполезным. Чтобы этого избежать тест должен запускаться на множестве входных данных, что делает его медленнее.
В связи со всем вышесказанным считаю классические юнит тесты устаревшим подходом, по которому, однако, написано очень много материалов (особенно от авторитетных светил вроде Дяди Боба), что вносит путаницу и уводит новичков от прогресса.
Юнит-тест тестирует не только публичный интерфейс, но и взаимодействие с зависимостями (кроме модулей без зависимостей). Зависимости в чистом SOLID скрыты от клиента абстракцией (Java итерфейсом или абстрактным классом). Интерфейс не задает поведения, он лишь определяет контракт взаимодействия. Поведение задает конкретная реализация интерфейса. Тест эту реализацию проверяет с помощью моков зависимостей. Зависимости — часть внутреннего (скрытого от клиента) устройства модуля, поэтому юнит-тесты считаются тестами белого ящика.
И раньше он делал это мимикрируя под форму логина, это ж чистой воды фишинг! Меня спасло то, что пароли разные и браузер подставил пароль от LinkedIn'а, и я не сразу понял, почему логин фейлится.
Обычно у вью контроллера есть свое внутреннее состояние, например selectedIndex у UITabBarController, еще он является делегатом UITabBar. Можно и модель, но она должна быть очень простой сущностью (не доменная модель).
Да, я вас понял. Надеюсь и вы меня ;)