Всупереч іншим відповідям, важливо зазначити, що деякі способи тестування можуть стати крихкими, коли система, що перевіряється (SUT), переробляється наново , якщо тест є білим ящиком.
Якщо я використовую глузуючий фреймворк, який перевіряє порядок методів, викликаних у макетах (коли порядок не має значення, оскільки виклики не мають побічних ефектів); тоді, якщо мій код чистіший з тими методами викликів у іншому порядку, і я рефактор, мій тест буде порушений. Взагалі, макети можуть внести крихкість у тести.
Якщо я перевіряю внутрішній стан мого SUT, відкриваючи його приватних або захищених членів (ми могли б використовувати "товариша" у візуальному базовому або збільшити рівень доступу "внутрішній" і використовувати "Internalsvisibleto" в c #; багатьма мовами OO, в т.ч. c # " тест-специфічний підклас " може бути використаний) тоді раптом внутрішній стан класу матиме значення - ви, можливо, будете переробляти клас як чорний ящик, але тести білого поля не зможуть. Припустимо, що одне поле повторно використовується для позначення різних речей (не належна практика!), Коли стан SUT змінюється - якщо ми розділимо його на два поля, нам може знадобитися переписати зламані тести.
Тестові підкласи можуть також використовуватися для перевірки захищених методів - це може означати, що рефактор з точки зору виробничого коду є переломною зміною з точки зору тестового коду. Переміщення декількох рядків у захищений метод або поза ним може не мати побічних ефектів виробництва, але зламати тест.
Якщо я використовую " тест-гачки " або будь-який інший тестовий або умовний код компіляції, може бути важко переконатися, що тести не порушуються через тендітні залежності від внутрішньої логіки.
Таким чином, щоб запобігти поєднанню тестів з інтимними внутрішніми деталями SUT, це може допомогти:
- Там, де це можливо, використовуйте заглушки, а не макети. Для отримання додаткової інформації дивіться блог Фабіо Перієра про тавтологічні тести та мій блог про тавтологічні тести .
- Якщо ви використовуєте макети, уникайте перевірки порядку викликаних методів, якщо це не важливо.
- Намагайтеся уникати перевірки внутрішнього стану SUT - використовуйте його зовнішній API, якщо це можливо.
- Постарайтеся уникати логіки тестування у виробничому коді
- Намагайтеся уникати використання підкласів, призначених для тесту.
Усі вищезазначені моменти - приклади з’єднання білих коробок, використовуваних у тестах. Отже, щоб повністю уникнути тесту на тесту на рефакторинг, використовуйте тестування на SUT в чорному ящику.
Відмова: Для обговорення рефакторингу тут я використовую слово трохи ширше, щоб включити зміни внутрішньої реалізації без видимих зовнішніх ефектів. Деякі пуристи можуть не погодитись і посилаються виключно на книгу Мартіна Фаулера та Кента Бека «Рефакторинг», де описані операції рефакторингу атомів.
На практиці ми схильні робити дещо більші нерозривні кроки, ніж описані там атомні операції, і, зокрема, зміни, які залишають виробничий код, що поводиться ззовні однаково, може не залишати тести проходження. Але я думаю, що справедливо включити "алгоритм заміщення іншим алгоритмом, який має однакову поведінку", як рефактор, і я думаю, що Фаулер погоджується. Сам Мартін Фаулер каже, що рефакторинг може порушити тести:
Коли ви пишете макетний тест, ви тестуєте вихідні дзвінки SUT, щоб переконатися, що він належним чином спілкується зі своїми постачальниками. Класичний тест стосується лише остаточного стану, а не того, як його було отримано. Мокістські тести, таким чином, більше поєднуються з реалізацією методу. Зміна характеру дзвінків до співпрацівників зазвичай спричиняє зрив макетів.
[...]
З'єднання з реалізацією також заважає рефакторингу, оскільки зміни в реалізації набагато частіше порушують тести, ніж класичні тестування.
Фаулер - макети не заглушки