Подготовка модульных тестов: что важно помнить при работе над архитектурой программного обеспечения?

Допустим, я начинаю новый проект, качество - главный приоритет.

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

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


person f4.    schedule 28.01.2010    source источник
comment
Сначала напишите тесты, а потом код. Если вы сделаете это таким образом, вы обнаружите, что архитектура естественным образом тяготеет к чему-то тестируемому.   -  person Anon.    schedule 28.01.2010


Ответы (5)


Легкость тестирования достигается благодаря возможности заменить как можно больше зависимостей, имеющихся в вашем методе, на тестовый код (имитаторы, подделки и т. Д.). В настоящее время рекомендуется использовать инверсию зависимостей, также известный как принцип Голливуда: «Не звоните. мы, мы позвоним вам ". Другими словами, ваш код должен «просить о вещах, а не искать».

Как только вы начнете думать таким образом, вы обнаружите, что код может легко зависеть от многих вещей. У вас есть зависимости не только от других объектов, но и от баз данных, файлов, переменных среды, API ОС, глобальных переменных, одиночных объектов и т. Д. Придерживаясь хорошей архитектуры, вы минимизируете большинство этих зависимостей, предоставляя их через соответствующие уровни. Поэтому, когда приходит время тестирования, вам не нужна рабочая база данных, полная тестовых данных, вы можете просто заменить объект данных на фиктивный объект данных.

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

Также помните о Законе Деметры. Не копайте более одного слоя в объекте, иначе вы создадите скрытые зависимости. Вызов Flintstones.Wilma.addChild (камешки); означает, что то, что вы думали, было зависимостью от «Флинтстоунов», на самом деле является зависимостью как от «Флинтстоунов», так и от «Вильмы».

person John Deters    schedule 28.01.2010
comment
вы всегда используете инверсию зависимостей? Я использую его на уровне пакета только в данный момент - person f4.; 01.02.2010

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

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

person Graviton    schedule 28.01.2010
comment
I или инверсия управления особенно важны для разделения приложения для тестирования. Это помогает изолировать случаи и предоставляет чистое место для имитации / обнаружения взаимодействий. - person smaclell; 28.01.2010

Вы также можете проверить эти два вопроса SO:

person smaclell    schedule 28.01.2010

Некоторые случайные мысли:

  • Определите интерфейсы: отделите функциональные модули друг от друга и решите, как они будут взаимодействовать друг с другом. Интерфейс - это договор между разработчиками разных модулей. Затем, если ваши тесты работают с интерфейсами, вы гарантируете, что команды могут рассматривать модули друг друга как черные ящики и, следовательно, работать независимо.

  • Сначала создайте и протестируйте хотя бы базовую функциональность пользовательского интерфейса. Как только ваш проект сможет поговорить с вами, он сможет сказать вам, что работает, а что нет ... но только если он вам не врет. (Бонус: если у ваших разработчиков нет другого выбора, кроме как использовать пользовательский интерфейс, вы быстро обнаружите любые недостатки в простоте использования, рабочем процессе и т. Д..)

  • Тестируйте на самом низком практическом уровне: чем больше вы уверены в том, что маленькие кусочки работают, тем легче будет объединить их в единое целое.

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

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

Удачи!

person Adam Liss    schedule 28.01.2010

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

person mattjames    schedule 28.01.2010