Як структурувати одиничні тести для програми GUI за допомогою C # та NUnit


16

Мене попросили зробити невеликий побічний проект, щоб поставити просту заявку одному з наших клієнтів. Зазвичай я б працював над бек-кодом, де я вирішив усі свої потреби в тестуванні, і я ще не мав сумнівної насолоди писати тести для GUI, тому мені трохи незрозуміло, як я повинен налаштувати код тестування та інструменти для EXE.

Перший мій інстинкт полягав у тому, щоб просто включити тести з кодом програми, однак це вимагало б поставити ряд залежностей від тесту, які мені доручали спеціально не надсилати замовнику. Я також не в змозі вичавити будь-яку готівку за цільовим інструментом тестування, тому мені потрібно використовувати підручні інструменти, які я маю під рукою ( StoryQ , RhinoMocks і NUnit), що насправді має бути більш ніж достатньо для перевірки поведінки простого додатка GUI. Наскільки я бачу, це дозволяє мені намагатися досягти хорошого балансу між збереженням дизайну дійсно простою, або цілеспрямовано надмірною інженерією заради тестів. Здається, я або будую додаток із діловою логікою в окремій бібліотеці і тестую проти бібліотеки, як зазвичай, або знаходжу якийсь інший механізм, який дозволяє мені виконувати виконувану програму, не порушуючи додаткових модулів, яких дизайн програми не робить дійсно потрібно.

Редагувати:
Зауважте, що це питання стосується того, як структурувати взаємозв’язок між NUnit та моїм виконуваним файлом - на відміну від DLL -, а не про те, як розділити логіку презентації та бізнесу.
/ Редагувати

Отже, моє питання:

  1. Чи існує конкретний / рекомендований метод для налаштування простого додатка графічного інтерфейсу з одиничними тестами, який дозволить мені адекватно перевірити стан та поведінку, використовуючи інструменти, які я маю під рукою, і не вдаючись до надмірної інженерії?
  2. Я пропустив щось принципове про те, як слід викликати / налаштувати NUnit під час тестування EXE (на відміну від DLL)?
  3. Чи можете ви надати або вказати мені на приклади, як досягти всього цього?

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


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

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

1
Немає нічого страшного складного в одиничному тестуванні матеріалів в EXE. Просто попросіть тестувальну DLL посилатись на ваш файл EXE, і вам добре.
whatsisname

Відповіді:


3

В одному зі своїх коментарів я відповів на відповідь симорамана, що я продумав кілька способів зробити це. Один із моїх варіантів був подібний до пропозиції у відповіді Джалайна про створення дубліката проекту та створення DLL, тоді як інша моя ідея полягала в тому, щоб просто посилання на файли в проекті, де був код, який я хотів перевірити. Хоча обидва варіанти можна змусити працювати, вони менш ніж ідеальні.

У другому випадку я мав би забруднити одиничні залежності, якщо не зміг би розірвати архітектуру, щоб мінімізувати залежності. Це добре для менших проектів, але більші з них легко можуть стати справжньою безладою для управління. Але найбільший опір цьому варіанту - це суцільна неелегантність. Звичайно, я мігзмусити його працювати, але при цьому мені фактично потрібно перервати інкапсуляцію, щоб перевірити внутрішню частину збірки безпосередньо через джерело, а не тестувати через загальнодоступні інтерфейси, що, на мій погляд, є великим ні-ні. Так само наявність додаткового файлу проекту означатиме або дублювання зусиль у двох проектах одночасно, або пошук способу автоматичного додавання параметрів файлу проекту до двох файлів одночасно, або запам'ятовування копіювання та перейменування поля проекту кожного разу, коли я будую. Це може бути автоматизовано на сервері збірки, але це буде неприємно управляти в IDE. Знову ж таки, це може спрацювати, але це в кращому випадку неприємність, а в гіршому - якщо ви помилитесь.

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


2

Я думаю що:

  • Код вашого тесту для бізнесу повинен бути в окремому проекті, протестуючи бібліотеку бізнес-кодів.
  • Ваш тестовий код GUI повинен бути в окремому проекті, протестуючи вашу бібліотеку GUI. Тепер, як створити бібліотеку графічного інтерфейсу замість виконуваного файлу, я намагаюся відповісти на це пізніше.
  • Якщо у вас є my.namespace.biz.MyClass, ваш тестовий клас повинен бути my.namespace.biz.MyClassTest (або MyClassTestCase).
  • Якщо ви хочете перевірити код, знайдений у вашій виконуваній цілі, тоді у вас повинна бути налаштування, яка створює EXE, та інша установка, яка створює бібліотеку (DLL), на яку ви будете запускати свої тести.

Це правила, яких я люблю дотримуватися, будь то Java або C # (за винятком проблеми EXE з Java, звичайно, немає :-))

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

Використання MSBuild

Створіть клон вашого .proj-файлу (скажімо, myproject-as-dll.proj ). Змініть OutputTypeв клонованому файлі з " EXE" на " Library". Використовуючи команду MSBuild, тепер ви можете створити бібліотеку, яку ви можете встановити як посилання у своєму проекті, що містить тестові приклади NUnit.

Мені це здається можливим, але я ніколи не використовував це так чесно, тому не впевнений. Крім того, у вас може бути MSBuild на вашому тестовому сервері інтеграції, і я не знаю, чи можна його відокремити від Visual Studio ...

Використання NAnt

Якщо ви не знайомі з NAnt, вам доведеться шукати в Google, як налаштувати конструкції проекту за допомогою нього. Можливо, перевірте це , воно трохи старе, але автор прокоментував файли NAnt і якщо вважаю, що це пояснює себе. ( Редагувати: детальніше вивчаючи його файл, я вважаю його файл конфігурації надзвичайно багаторазовим ). Він також робить набагато більше, ніж просто будує, оскільки виконує тестові випадки та запускає засоби покриття коду. Тепер, я визнаю, я ніколи не використовував NAnt, всупереч його колезі Java та батькові "Мурашка", який я багато використовував, але я бачу, що це зовсім те саме, і я не думаю, що це так складно навчитися.

За допомогою цього інструменту ви можете створити конфігурацію, яка дозволить вам:

  • створити всі свої проекти (бізнес-логіка, графічний інтерфейс тощо) в окремі бібліотеки
  • побудувати свої тестові проекти
  • запустити тести (ця конкретна частина виконується із завданням NUnit2 ).
  • вивчити покриття коду завданням NCover .

Маючи трохи більше коду, ви навіть можете:

  • виконувати щомісячні розгортання на вашому інтеграційному сервері
  • якщо NAnt доступний на вашому сервері інтеграції, запускайте нічні тести інтеграції за допомогою запланованих завдань

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

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


0

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

Ви не згадали, який графічний інтерфейс ви використовуєте. WPF MVVM (Model-View-ViewModel) хороший і дозволяє досить легко писати тести з усієї логіки. З WinForms я чув хороші речі про MVP (Model-View-Presenter)


Я пишу тести на весь код, який я пишу. Навіть речі, які вам можуть здатися тривіальними. Єдиний раз, коли я не пишу тест, коли це шип. У цьому випадку я доставляю клієнту єдину утиліту, тому тестування - це не просто розкіш, це вимога для задоволення наших стандартів якості. З точки зору "над інженерією", це не вибір між хорошою чи поганою архітектурою, а скоріше уникати необхідності вводити додаткові шари, які не потрібні в цьому випадку, оскільки додаток є єдиною метою з відносно коротким життєвим циклом.
Робінз

Що стосується вибору gui-фреймворку, я не бачу, як це вплине на спосіб налаштування тестового середовища. Я шукаю, ЯК спеціально реалізувати тестові одиниці рівня GUI, використовуючи наявні інструменти. Ця конкретна відповідь насправді нічого не говорить про це.
Робінз

Сімораман - Якщо ви відібрали досить судження першого абзацу, це би наближалося до відповіді. Виправте це, і я зніму -1. @ S.Robins зауважимо, що другий абзац є релевантним - хоча це не повна відповідь, це допоможе. Якщо ваш шар GUI тонкий, добре структурований і очевидний, а вся бізнес-логіка перевірена одиничними тестами на рівні Моделі, можливо, вам не потрібно буде пройти додаткові клопоти тестування інтерфейсу користувача чітко.
Марк Бут

1
@MarkBooth Layering насправді не є проблемою. Як згадує simiraman, я можу MVP, MVVM або я можу побудувати щось навіть тонше. Однак у мене є деякі елементи GUI, які потребують явного тестування, тому я вирішив написати це як питання. У мене є пара ідей, і якщо гірше стане гірше, я знаю, що врешті-решт я зможу вирішити проблему і написати відповідь самостійно. Однак я хотів відкрити це перед громадою, оскільки думав, що це стане гарним питанням для ProgrammersSE. ;-)
Робінз

0

Погляньте на мою відповідь на це запитання: Як встановити MVP для рішення Winforms?

Я фактично написав зразок програми, який показує, як я шар і як я тестую свій графічний інтерфейс.

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


Дякуємо за рекомендацію ReSharper. Це інструмент, який я використовую при розробці. На жаль, це не допоможе при виконанні тестів на сервері інтеграції. Він також не каже мені, як налаштувати тести Nunit для доступу до коду в exe під час тестування.
Робінз

1
Неофіційно це робить. Exe - це просто представлення, яке завантажує презентатора, моделі та моделі перегляду з бібліотеки класів у рамках запуску програми. Принаймні, в моєму рішенні погляд є досить тупим, що ми не перевіряємо його автоматизованими тестами, а просто робимо тести прийняття, щоб переконатися, що все написано правильно, а кнопки - там, де вони повинні бути. NUnit-тестування dll дуже легко зробити.
Брайан Боттчер

0

Я писав Nunit WinForms кілька років тому (я думаю, 6 років). Одне, що я пам'ятаю конкретно, - це те, що він є єдиним тестовим прикладом, але він також виступає в якості тестового випадку. Іноді на передньому кінці не так багато тестування (проста форма). Тож навіть якщо ви намагаєтеся перевірити, чи з’являється вікно повідомлення, яке спливе на натискання кнопки, ви ненавмисно випробовуєте різні інші методи з інших шарів. Є деякі речі, які ви також не можете автоматизувати. Вигляд, відчуття та зручність використання неможливо автоматизувати за допомогою автоматизованого тестування блоку. Перед випуском вам доведеться провести кілька ручних тестів.


Якщо ваш клієнт вказує, що екран повинен виглядати певним чином або повинен певним чином змінюватися, то ви повинні мати можливість перевірити ці речі. Захоплення специфікацій як тестів є основою методології BDD, і я ніколи не знаходив ситуації, коли ви не змогли б - хоч і творчо - знайти засоби для автоматизації тесту. Справжнє питання полягає в тому, чи буде тестування корисним, чи додаток розроблено достатньо добре, щоб в першу чергу ви змогли автоматизувати всі тести та чи будуть тести ефективними? Я погоджуюся, що іноді їх немає.
S.Robins
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.