Модули юнит-тестирование: правильно ли я делаю это, или у меня неправильное представление?
Вы пропустили лодку.
Я не совсем понимаю, как проходит тест перед кодом, если вы не знаете, какие структуры и как вы храните данные
К этому вопросу, я думаю, вам нужно вернуться, если вы хотите, чтобы идеи имели смысл.
Первый пункт: структуры данных и хранилище основаны на том, что вам нужно для выполнения кода, а не наоборот. Более подробно, если вы начинаете с нуля, вы можете использовать любое количество реализаций структуры / хранилища; действительно, вы должны иметь возможность переключаться между ними без необходимости менять свои тесты.
Второй момент: в большинстве случаев вы потребляете свой код чаще, чем производите его. Вы пишете это один раз, но вы (и ваши коллеги) звоните много раз. Поэтому удобство вызова кода должно иметь более высокий приоритет, чем если бы вы писали свое решение исключительно изнутри.
Поэтому, когда вы пишете тест и обнаруживаете, что клиентская реализация уродлива / неуклюжа / непригодна, она предупреждает вас еще до того, как вы начали что-либо реализовывать. Точно так же, если вы обнаружите, что пишете много кода установки в своих тестах, это говорит о том, что вы на самом деле не разобрали свои проблемы. Когда вы обнаружите, что говорите «вау, этот тест было легко написать», вы, вероятно, получили интерфейс, который прост в использовании.
Очень трудно достичь этого, когда вы используете примеры, ориентированные на реализацию (например, написание теста для контейнера). То, что вам нужно, это хорошо ограниченная игрушка, независимая от реализации.
В качестве тривиального примера вы можете рассмотреть менеджер аутентификации - передать идентификатор и секрет и выяснить, соответствует ли секрет идентификатору. Таким образом, вы должны иметь возможность написать три быстрых теста сразу: убедитесь, что правильный секрет разрешает доступ, убедитесь, что неправильный секрет запрещает доступ, убедитесь, что при изменении секрета только новая версия разрешает доступ.
Так что вы, возможно, пишете несколько простых тестов с именами пользователей и паролями. И, поступая так, вы понимаете, что секреты не должны быть ограничены строками, но вы должны иметь возможность создавать секрет из чего-либо сериализуемого, и что, возможно, доступ не универсален, но ограничен (это касается диспетчера аутентификации) ? может и нет) и о, вы захотите продемонстрировать, что секреты хранятся в безопасности ....
Конечно, вы можете использовать тот же подход для контейнеров. Но я думаю, вам будет проще «получить», если вы начнете с проблемы пользователя / бизнеса, а не с проблемы реализации.
Модульные тесты, которые проверяют конкретную реализацию («У нас здесь ошибка поста забора?») Имеют значение. Процесс их создания во многом похож на «угадай ошибку, напиши тест для проверки ошибки, отреагируй, если тест провалится». Эти тесты, как правило, не вносят свой вклад в ваш дизайн - у вас гораздо больше шансов клонировать блок кода и изменить некоторые входные данные. Однако часто бывает так, что когда модульные тесты следуют за реализацией, их часто сложно написать и они требуют больших затрат на запуск («зачем мне нужно загружать три библиотеки и запускать удаленный веб-сервер, чтобы проверить ошибку забора в моем цикле for»). ? ").
Рекомендуемое чтение Фриман / Прайс, Растущее объектно-ориентированное программное обеспечение, руководствуясь тестами