Чи повинні бути одиничні тести складних регулярних виразів?


34

Чи слід писати одиничні тести для складних регулярних виразів у своїй програмі?

  • З одного боку: їх легко перевірити, оскільки формат введення та виведення часто простий і чітко визначений, і вони часто можуть набути такого складного рівня, тому тести на них конкретно цінні.
  • З іншого боку: вони самі рідко є частиною інтерфейсу якогось блоку. Можливо, краще лише протестувати інтерфейс і робити це таким чином, що неявно тестує регулярні вирази.

Редагувати:

Я погоджуюся з Доком Браун, який у своєму коментарі зазначає, що це особливий випадок одиничного тестування внутрішніх компонентів .

Але як внутрішні компоненти регулярні вирази мають кілька особливих характеристик:

  1. Регекс для одного рядка може бути справді складним, не будучи справді окремим модулем.
  2. Regexes відображає карту для виведення без будь-яких побічних ефектів, а отже, їх справді легко перевірити окремо.

12
"вони самі рідко є частиною інтерфейсу якогось блоку". - якщо у ваших класах цікавий код закопаний глибоко під інтерфейсом, розбийте свої класи. Це приклад того, як мислення про тесс може покращити дизайн.
Натан Купер

3
Це ж питання в більш загальному вигляді: які внутрішні компоненти слід перевірити? Дивіться програмісти.stackexchange.com/
Doc Brown

Сорта пов'язана, див. Регекс101. У них є розділ для написання одиничних тестів для вашого регексу. Наприклад: regex101.com/r/tR3mJ2/2
Девід каже

3
Відмова - цей коментар - моя скромна думка: 1 насамперед я вважаю, що складні виразки є чистим злом - також дивіться blog.codinghorror.com/… 2 реальна цінність тестування таких виразів настає, коли ви перевіряєте їх на великій базі реальних даних дані blog.codinghorror.com/testing-with-the-force 3 У мене дивне відчуття, що ці випробування не є одиничними тестами
Борис Треухов

Відповіді:


101

Перевіряючи догматизм убік, справжнє питання полягає в тому, чи надає він значення одиниці тестових складних регулярних виразів. Здається, досить зрозуміло, що він надає значення (незалежно від того, чи є регулярний вираз частиною загальнодоступного інтерфейсу), якщо регулярний вираз є досить складним, оскільки він дозволяє знаходити та відтворювати помилки та запобігати регресії.


25
+1, хоча якщо регулярний вираз є досить складним , що це питання, то, ймовірно , має сенс , щоб перемістити його в «обгортці» блок з відповідними методами ( isValid, parse, tryParse, або етажеркою, в залежності , як саме він використовується), так що клієнтський код не повинен знати, що він в даний час реалізований за допомогою регулярного вираження. Потім модуль обгортки провів би детальні тести, які - знову ж таки - не потребували б знати поточну реалізацію. Ці тести, звичайно, фактично випробовують регулярний вираз, але реально-агностично.
ruakh

1
Reg ex - це програма, хоча спеціалізованою і дуже лаконічною мовою. Таким чином, тестування підходить для нетривіальних виразів ... І, безумовно, слід перевірити код, який викликає вираз, який може неявно перевірити зарезервоване.
кешлам

6
@ruakh Добре сказано. Перевага класу обгортки для регулярного вираження полягає в тому, що ви можете акуратно замінити його звичайним кодом, якщо це стане необхідним. Код зі складним входом / виходом завжди повинен перевіряти одиницю, тому що без цього налагодити надзвичайно важко. Якщо вам потрібно звернутися до документації, щоб зрозуміти ефекти коду, у ньому повинні бути одиничні тести. Якщо це просто швидке відображення типу 1: 1 як перетворення типу, то проблем немає. Regexes долають цю точку, коли потрібні документи дуже швидко.
Aaron3468

4
@Lii: Regexes не заслуговує особливого лікування. У цьому випадку регулярний вираз є одиницею, тому ми його тестуємо.
ЖакБ

1
@ruakh Я збирався написати відповідь на це. Я погоджуюся, що використання регулярного вираження є детальною частиною реалізації. Що важливо, це те, що вони перевіряються, коли вони повинні, і не можуть перевірити, коли вони повинні. Перевірте FooValidatorнаявність його входів і виходів, тоді ви не хвилюєтесь, як це робиться. ++
RubberDuck

21

Regex може бути потужним інструментом, але це не той інструмент, якому ви можете довіряти, щоб просто все ще працювали, якщо ви внесете навіть незначні зміни в складні регекси.

Тому створіть безліч тестів, які документують випадки, які він повинен охоплювати. І створити безліч тестів, щоб документи, випадки яких не мали результату, якщо вони використовуються для перевірки.

Щоразу, коли вам потрібно буде змінити свої регулярні вирази, ви додаєте нові випадки як тести, модифікуйте свій регулярний вираз і сподівайтеся на найкраще.

Якби я був в організації, яка взагалі не використовувала одиничні тести, я все-таки напишу програму тестування, яка б перевірила будь-який регекс. Я б навіть зробив це самостійно, якби довелося, моєму волоссю більше не потрібно втрачати колір.


3

Регулярні вирази - це код разом з рештою вашої програми. Ви повинні перевірити, що код в цілому робить те, що ви очікуєте від нього. Це має кілька цілей:

  • Тест - це документація, яку можна виконувати. Це наочно демонструє, що вам потрібно зробити код. Якщо вона перевірена, це важливо.
  • Майбутні технічні працівники можуть бути впевнені, що якщо вони модифікують, тести забезпечать незмінність поведінки.

Оскільки є додаткові перешкоди для подолання, вклавши код іншою мовою, вбудований у решту, ви, швидше за все, повинні приділити цій додатковій увазі користь обслуговування.


1

Коротше кажучи, ви повинні перевірити свою заявку, період. Незалежно від того, чи тестуєте ви свій регекс за допомогою автоматизованих тестів, які виконують його ізольовано, як частину більшого чорного поля, або якщо ви просто рукою рухаєтесь навколо нього, є другорядним моментом, щоб переконатися, що він працює.

Основна перевага одиничних тестів полягає в тому, що вони економлять час. Вони дозволяють вам перевірити річ стільки разів, скільки вам подобається зараз, або в будь-який момент майбутнього. Якщо взагалі є якась причина вірити, що ваш регекс в будь-який момент буде відремонтований, перероблений, отримати більше обмежень тощо, то так, ви, мабуть, хочете отримати деякі регресійні тести для нього, або коли ви це зміните, вам доведеться піти через годину роздуму над усіма крайовими справами, щоб ви не порушили його. Це, або ви навчитеся жити, боячись свого коду і просто ніколи його не змінюйте.


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

-1

З іншого боку: вони самі рідко є частиною інтерфейсу якогось блоку. Можливо, краще лише протестувати інтерфейс і робити це таким чином, що неявно тестує регулярні вирази.

Я думаю, що з цим ти сам на це відповів. Regexes в підрозділі - це, швидше за все, деталь реалізації.

Те, що стосується тестування вашого SQL, ймовірно, також стосується регулярних виразів. Коли ви змінюєте шматок SQL, ви, ймовірно, запускаєте його через якийсь клієнт SQL вручну, щоб побачити, чи він дає те, що ви очікуєте. Те ж саме стосується, коли я змінюю регулярний вираз, я використовую інструмент регулярного вираження з деяким введенням зразка, щоб побачити, чи він робить те, що я очікую.

Що мені здається корисним, це коментар поблизу регулярного виразка із зразком тексту, який він повинен відповідати.


" Коли ви змінюєте частину SQL, ви, ймовірно, запускаєте її через якийсь клієнт SQL вручну, щоб побачити, чи дає він те, що ви очікуєте ". Але такий варіант відповідає на питання іншим способом ... Якщо мені потрібно чи я вважаю, що це корисно перевірити регекси вручну, тоді я повинен зробити тестовий блок для цього. Саме це і робить те, що важко вирішити!
Лій

Це дійсно залежить. Те, що ви хочете, щоб ваші одиничні тести - це можливість вносити зміни. Як часто ви змінюєте конкретний регулярний вираз? Якщо відповідь часто, то будь-якими способами створіть для неї тест.
Крістіаан

8
За інших рівних умов краще провести автоматизований тест, ніж "тест вручну".
Роберт Харві

1
Чому б ви не протестували регулярний вимір за допомогою автоматизації?
Тоні Енніс

1
Це частина методу, і все, що я намагався сказати, - це те, що ви вже не тестуєте цей метод, не потрібно спеціально перевіряти регулярний вираз. Але якщо ви це зробите, вам, ймовірно, краще витягнути регулярний вираз в окрему функцію, яку ви перевірите ізольовано.
Крістіаан

-5

Якщо вам доведеться запитати, відповідь - так.

Припустимо, якийсь FNG приходить разом і думає, що він може "покращити" ваш регулярний вираз. Тепер він FNG, тому автоматично ідіот. Точно та людина, яка ніколи не повинна торкатися вашого дорогоцінного коду! Але, можливо, він пов’язаний з PHB або щось подібне, тому нічого не можна зробити.

За винятком того, що ви знаєте, що PHB збирається тягнути вас ногами і кричати назад до цього проекту, щоб "можливо дати хлопцеві якісь вказівки про те, як ви зробили цей безлад", коли все піде погано. Таким чином, ви записуєте всі випадки, які ви ретельно розглядали, будуючи свою прекрасну майстерність експресіоналізму.

І оскільки ви їх все записали, ви маєте дві третини способу створення набору тестових прикладів, оскільки - давайте визнаємось - тестові випадки regex легко запускати, як тільки ви створили основу.

Отже, у вас є набір крайових умов, альтернатив та очікуваних результатів. І раптом тестові випадки - це документація так само, як і обіцяно в усіх тих, що я занадто Agile. Ви просто вказуєте FNG, що якщо його "поліпшення" не пройде існуючих тестових випадків, це не так багато покращення, чи не так? А де його запропоновані нові тестові випадки, які демонструють певну проблему з оригінальним кодом, який, оскільки він працює, його не потрібно змінювати ніколи!


3
що таке ЗВГ? Це не здається мені поганою відповіддю, але відсутнє визначення для FNG (gogglin для нього просто дає результати, які не пов'язані між собою, тому, можливо, ця відповідь була просто спровокована через FNG?)
GameDeveloper

1
Я підозрюю, що Google відвів вас у потрібне місце. ;-) ( en.wikipedia.org/wiki/FNG_syndrome )
Остін Гастінгс

Якщо ви не абсолютний геній програмування, будуть більш досвідчені програмісти, які враховують, що ви робите так, як дивитесь на нового хлопця. Можливо, ви хочете розглянути можливість бути більш скромним.
Thorbjørn Ravn Andersen
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.