- Модуль за модулем
- Тестування серверного коду на C # за допомогою xUnit
- Тестування клієнтського JavaScript-коду за допомогою qUnit
- Тестування UI за допомогою CUIT
- Підвищіть якість свого ПО
Програмне забезпечення стає все складніше і складніше. Будь то додаток для Windows, iOS, Web, Android, пристрої для Інтернету речей (Internet of Things, IoT) або розумних годин (smartwatch) - це ПЗ робить багато всяких речей. Відповідно ПО повинно бути коректним. Воно повинно працювати відповідно до специфікації. А значить, розробники повинні тестувати своє ПЗ.
Без тестування важко бути впевненим в тому, що код робить те, що повинен. Крім того, стало важче ізолювати код, щоб виправляти помилки. Хоча тестування важливо, набагато важливіше тестування з обґрунтованих причин, а не просто заради самого тестування. Невеликі смарт-тести завжди здобувають перемогу над безглуздими тестами, які охоплюють всю кодову базу. У цій статті розповідається, як виконувати модульне тестування коду на серверній і клієнтській стороні, а також як автоматизувати тестування UI за допомогою кодованих тестів UI (coded UI tests, CUIT). Ці три основні області тестування дозволять перевірити головні аспекти функціональності вашого ПО.
Модуль за модулем
Модульне тестування допомагає зменшити кількість помилок і надає документацію для тестованого коду. Також важливі регресія, схвалення користувачем (user acceptance), автоматизація UI та інші показники якості. Бюджети часто вельми обмежені, а групи малі, тому доводиться вибирати, що можна зробити. Ви повинні вирішувати, скільки зусиль щодо забезпечення якості буде вкладено в вашу програму. По самому мінімуму модульне тестування та тести UI допоможуть зберегти якість на високому рівні.
Існує ряд комерційних і з відкритим вихідним кодом пакетів для модульного тестування. Багато популярних набори для тестування публікуються у вигляді NuGet-пакетів, тому ви можете легко завантажити їх прямо в Visual Studio. Кілька найбільш популярних інфраструктур тестування для C # - це xUnit, nUnit, MSTest і TestDriven.NET. Для JavaScript є qUnit, JSUnit і YUI Test.
Хоча модульне тестування часто є типом тестування за замовчуванням, існують і інші способи тестування ПО. До них відносяться автоматизація UI або CUIT, тестування на схвалення користувачем, регресійні тестування, інтеграційне тестування і всі типи спеціалізованих тестів. У Вікіпедії перераховуються десятки способів тестування ПО ( bit.ly/14066q8 ).
Хороші модульні тести перевіряють тільки одну функцію за один тест. Принцип єдиною обов'язки (single responsibility principle, SRP) - один із способів забезпечити модульність вашого коду. SRP означає, що даний код сфокусований на одній операції і виконує її добре - будь то код реалізації або сам тест. Модульні тести не повинні безпосередньо звертатися до баз даних, файлів та інших ресурсів. Вони повинні покладатися на що імітують об'єкти (mock objects), які симулюють ці ресурси; крім того, як і будь-який інший код, модульні тести повинні бути компактними.
Інший спосіб написання хороших тестів - дотримання принципів розробки на основі тестів (test-driven development, TDD). TDD - це метод розробки коду на основі набору тестів. Розробник створює тести, які провалюються, потім пише відповідний код, що задовольняє тесту, а потім виконує рефакторинг. Я називаю цей метод «Red, Green, Refactor». Він допомагає структурувати і писати відповідний код. А узгодженість - це суть розробки ПО. Хоча розгляд TDD виходить за рамки цієї статті, вивчіть цей метод і випробуйте його в своїй групі.
У цій статті обговорюється модульне тестування за допомогою xUnit і qUnit. Я також опишу тестування автоматизації UI, використовуючи CUIT. Завдяки цьому ви ознайомитеся з найбільш важливими типами тестів, які обов'язково знадобляться вам.
Тестування серверного коду на C # за допомогою xUnit
Ви приємно здивуєтеся тому, наскільки легко інтегрується пакет модульного тестування в Visual Studio. Багато інфраструктури доступні у вигляді NuGet-пакетів. Наприклад, якщо ви віддаєте перевагу використовувати xUnit, просто запустіть NuGet Package Manager, вкажіть пошук «xUnit», а потім одним клацанням встановіть обидва його пакета (базовий і засіб запуску тестів). За допомогою xUnit можна тестувати веб-сайти ASP.NET, додатки Windows Forms, Windows Presentation Foundation (WPF), Windows Store і Windows Phone на будь-якій мові, який при компіляції видає MSIL-код (Microsoft Intermediate Language). Ви можете тестувати навіть код на F #, використовуючи xUnit, - все це технології розробки Microsoft.
Щоб використовувати xUnit, додайте проект Class Library свого рішення. Простоти заради ви, можливо, вважатимете за краще дотримуватися поширених угод по іменування і писати щось на зразок ProjectName.Tests, де ProjectName - ім'я тестованого проекту. У тесті додайте посилання на цей проект. Потім назвіть і додайте в тест файл класу, а також клас для тестування чого-небудь.
На рис. 1 показаний приклад класу тесту xUnit з одним тестом і кодом, який він тестує. Код на рис. 1 визначає статус клієнта на основі того, яку суму він витратив. Тести на рис. 1 гарантують коректність коду.
Мал. 1. Тестування прикладу xUnit-коду
// Модульні тести, що перевіряють характеристики, // пов'язані з клієнтом public class CustomerTests {[Theory] [InlineData (99D)] [InlineData (1001D)] [InlineData (5001D)] [InlineData (10001D)] public void VerifyCustomerStatus (double TotalSpent ) {// Arrange var status = new Status (); var testStatus = OrderForm.Models.Status.StatusLevel.None; // Act var currentStatus = status.GetCurrentStatus (TotalSpent); // Assert Assert.True (testStatus <= currentStatus); }} // Логіка, яка встановлює статус клієнта public class Status {public StatusLevel GetCurrentStatus (decimal ForAmount) {var level = StatusLevel.None; var amt = Convert.ToInt32 (ForAmount); if (amt> тисячу && amt <= 5000) {level = StatusLevel.Silver; } Else if (amt> 5000 && amt <= 10000) {level = StatusLevel.Gold; } Else if (amt> 10000) {level = StatusLevel.Platinum; } Return level; } Public enum StatusLevel {None = 0, Silver = 1, Gold = 2, Platinum = 3}}
У методах модульного тестування ви виявите популярний шаблон Arrange, Act, Assert (або AAA), який теж представлений на рис. 1. Спочатку ви задаєте умови тесту, потім дієте за цими умовами і, нарешті, перевіряєте висновок.
AAA застосуємо до чого завгодно, але, якщо ви хочете отримати якісне ПЗ, то повинні мати осмислені тести. Інфраструктури тестування поставляються з безліччю перевірок, таких як Equal, NotEqual, Same, NotSame, Contains, DoesNotContain, InRange, IsNotEmpty і ряд інших. Звичайно, точне іменування або методи в різних інфраструктурах відрізняються, але кожна з них дає вам достатньо широкий вибір.
Ймовірно, ви помітили атрибути [Theory] і [InlineData], що доповнюють клас тесту, замість поширеного атрибута [Test]. Коли у методів тестів немає параметрів, в xUnit можна використовувати атрибут [Fact], щоб позначити метод як метод тесту. Ці анотації даних дозволяють тесту приймати параметр TotalSpent, який ви бачите в сигнатурі методу тесту на рис. 1. Один тест буде виконуватися для кожного атрибута [InlineData] в методі і відображати результати кожного тесту в Visual Studio Text Explorer (рис. 2).
Мал. 2. Метод тесту VerifyCustomerStatus з чотирма точками даних в Test Explorer
Ви можете використовувати контекстне меню на тестах в Test Explorer, щоб в будь-який момент отримати доступ до параметрів виконання, налагодження, аналізу, профілювання і т. Д. Щоразу, коли ви змінюєте код або тести, ви повинні заново компілювати і виконувати тести. Ви можете вказати варіант автоматичного виконання тестів при кожній збірці, вибравши в Visual Studio з меню Test команду Test Settings, а потім вказавши Run Tests After Build.
Ви не зможете далеко зайти з модульним тестуванням, що не зіткнувшись з необхідністю в імітують об'єктах. В принципі, коли ви намагаєтеся тестувати базу даних, ви не хочете модифікувати містяться в ній дані. А значить, потрібно використовувати імітацію як спосіб симуляції реальної бази даних, веб-сервісу або бізнес-об'єкта. Імітація виходить за рамки цієї статті, так що, коли ви дійдете до цієї стадії, пошукайте в Інтернеті Moq, Telerik JustMock або Rhino Mocks. Це популярне ПО для імітації з повною документацією і підтримкою.
Тестування клієнтського JavaScript-коду за допомогою qUnit
QUnit - це інфраструктура тестування JavaScript-коду на стороні клієнта. Вона полегшена, проста і зручна у використанні. Ви можете застосовувати qUnit для тестування будь-якого коду на JavaScript або jQuery. Оскільки ви маєте справу з клієнтським JavaScript-кодом, в UI можуть відбуватися якісь операції, які вам не треба тестувати. Ви можете пропускати такі аспекти, як затримку курсору миші над посиланням (link hovers) або зміни в оформленні UI. Крім того, ви можете задіяти тестування автоматизації UI (UI automation testing) для перевірки UI. Ваші бізнес-правила, API-код і перевірки на стороні сервера повинні охоплюватися тестами у високому ступені. Будь JavaScript-код, який виконує логіку і перевірки, теж потрібно тестувати.
На відміну від скомпільованих мовних тестів, безпосередньо інтегруються в Visual Studio, вам доведеться зібрати своє оточення тестів (test harness) qUnit. Однак це досить легко і вимагає приблизно 17 рядків коду, які можна скопіювати з рис. 3.
Мал. 3. HTML-оточення тестів qUnit
<! DOCTYPE html> <html xmlns = "http://www.w3.org/1999/xhtml"> <head> <title> Qunit Unit Testing </ title> <link href = "Content / qunit.css" rel = " stylesheet "/> </ head> <body> <h1 id =" qunit-header "> qUnit Test Suite </ h1> <h2 id =" qunit-banner "> </ h2> <div id =" qunit-testrunner -toolbar "> </ div> <h2 id =" qunit-userAgent "> </ h2> <ol id =" qunit-tests "> </ ol> <script src =" Scripts / qunit.js "> </ script> <script src = "Scripts / logic.js"> </ script> <script src = "Scripts / tests.js"> </ script> </ body> </ html>
На рис. 3 показані посилання на qunit.css, потім qunit.js, logic.js і tests.js. Цей порядок важливий. Ви повинні завантажувати qunit.js до вашої логіки, а логіку - до тестів. Файл logic.js можна назвати як завгодно, оскільки це ваш код. Між qunit.js і тестами може бути кілька файлів .js. HTML-структура сторінки оточення тестів (test harness page) містить кілька тегів head, а також впорядкований список, який відображає результати індивідуальних тестів. Всі стилі знаходяться в файлі qunit.css. Рекомендується поміщати тільки JavaScript-посилання в кінець веб-сторінки відразу за закриває тегом </ body>, як показано на рис. 3.
Для тестування з допомогою qUnit можна помістити тести в файл .js і назвати егоtests.js. Я викликаю qUnit-функцію test, яка приймає строкове ім'я викликається функції і анонімну функцію, реально виконує тест. Ім'я, яке передається функції test, з'являється в засобі запуску тестів (test runner) як ім'я тесту (рис. 4). Замість передачі параметрів в тест, використовуйте динамічну природу JavaScript для неодноразового виклику потрібного коду з використанням декількох контрольних виразів (asserts). На рис. 5 показаний висновок від цих виразів в функції тесту VerifyCustomerStatus.
Мал. 4. QUnit тестує функцію getCurrentStatus і саму логіку в JavaScript-коді
// Тести для перевірки статусів клієнтів test ( 'VerifyCustomerStatus', function () {var silver = getCurrentStatus (1001); equals (silver, "Silver", "Pass"); var gold = getCurrentStatus (5001); equals (gold, "Gold", "Pass"); var platinum = getCurrentStatus (10001); equals (platinum, "Platinum", "Pass");}) // Логіка присвоєння статусів клієнтів function getCurrentStatus (amt) {if (amt> 1000 && amt <= 5000) {return "Silver"; } Else if (amt> 5000 && amt <= 10000) {return "Gold"; } Else if (amt> 10000) {return "Platinum"; } Return "None"; }
Мал. 5. Результати тестів qUnit в браузері
Якщо ви пишете додатки Windows Store або Windows Phone, використовуючи Windows Library for JavaScript (WinJS), не хвилюйтеся. Існує qUnitMetro, який можна завантажити за посиланням bit.ly/1F2RsO7 . Цей пакет дозволяє qUnit виконуватися в контейнері додатки так, ніби це веб-сторінка. Кодування і спосіб написання тестів ідентичні застосовуваним в qUnit, тому що це і є qUnit.
Тестування UI за допомогою CUIT
Коли потрібно автоматизувати тестування «рідних» UI, перемикайтеся на CUIT. CUIT - маловідоме засіб тестування в Visual Studio. Ви можете створювати CUIT в Visual Studio для веб-додатків, додатків Windows Store і Windows Phone. Visual Studio CUIT здатні тестувати будь UI в Windows. Вам навіть не знадобиться вихідний код для тесту UI. Ви можете конфігурувати ці тести під будь-яку виконувану програму.
У Visual Studio є шаблони для базових UI: для Web, Windows Store і Windows Phone. Коли ви створюєте проект по одному з цих шаблонів, Visual Studio відразу ж виведе перше діалогове вікно, показане на рис. 6, і запитає у вас, що ви хочете - записати нові тести або відредагувати існуючі. Виберіть Record actions, edit UI map or add assertions, і з'явиться вікно інструментів (рис. 7). Той же діалог і вікно інструментів будуть відображатися при кожному додаванні нового файлу CUIT в проект (File | New Item). У цей момент ви можете натиснути кнопку запису, а потім приступити до взаємодії з UI вашої веб-сторінки або програми.
Мал. 6. Діалог, виведений Visual Studio для запису або редагування кодованих тестів UI (CUIT)
Мал. 7. Інструменти для запису і редагування контрольних виразів
Закінчивши, натисніть кнопку Add and Generate внизу вікна (рис. 8), додайте докладні і описові метадані і дозвольте Visual Studio згенерувати код.
Мал. 8. Діалоги, які створюють кодовані тести UI
Коли ви створюєте проект Coded UI і додаєте в нього Coded UI Test, Visual Studio генерує пристойний обсяг коду. Однак Visual Studio досить «розумний» в тому, як він генерує код тесту. Висновок дуже чіткий, особливо для згенерованого коду. Visual Studio генерує код, записуючи ваші дії при використанні конкретної програми. Якщо ви клацнете кнопки запису у вікні інструментів (рис. 7), засіб записи відстежує, що ви робите, щоб генерувати код, що виконує ті ж дії. Ви можете і самі написати цей код, але автоматично генерувати його все ж легше.
Як тільки ви закінчуєте роботу з Coded UI Test Builder, Visual Studio створює кілька файлів, перший з яких є Coded UI Test (CUIT). Це файл .cs, який містить клас з методами, які виконують ті ж дії, які виконував би користувач у вашому UI. Інші файли включають UIMap.uitest, UIMap.cs і UIMap.designer.cs. На відміну від традиційних дизайнерів Visual Studio, які сумно відомі тим, що генерують занадто багато коду, цей дизайнер поводиться набагато краще. Ви можете легко модифікувати тести без участі дизайнера. У будь-який момент дизайнер можна змінити, клацнувши правою кнопкою миші файл .uitest і вибравEdit with Coded UI Test Builder. Це призведе до запуску вікна інструментів, яке ви бачили на рис. 7. І знову ви можете вручну писати свої тести. Перш ніж зважитися на це, вивчіть ту частину згенерованого коду, яка виконує наступні чотири тести.
- Перевірка коректності створення нового клієнта.
- Перевірка створення нового клієнта без введення його імені.
- Перевірка створення нового клієнта без введення його адреси.
- Перевірка створення нового клієнта з введенням поштового коду в неправильному форматі.
Ви знайдете ці чотири тести в файлі дизайнера; код в класі Coded UI Test викликає їх послідовно, як видно на рис. 9.
Мал. 9. Фрагмент контенту Coded UI Test і файлів зіставлень дизайнера
// В C # -Файл Coded UI Test [CodedUITest] public class CodedUITest1 {[TestMethod] public void CodedUITestMethod1 () {this.UIMap.CreateNewCustomerCorrectly (); this.UIMap.CreateNewCustomerWithoutName (); this.UIMap.CreateNewCustomerWithoutAddress (); this.UIMap.CreateNewCustomerWihtoutValidPostalCode (); } // Якийсь інший код інфраструктури для Coded UI} // У файлі UIMap.Designer.cs для Coded UI public void CreateNewCustomerWithoutName () {#region Variable Declarations // Клацаємо посилання Create New Mouse.Click (uICreateNewHyperlink, new Point ( 51, 8)); // Вводимо '' в текстове поле Name uINameEdit.Text = this.CreateNewCustomerMissingNameParams.UINameEditText; // Вводимо '{Tab}' в текстове поле Name Keyboard.SendKeys (uINameEdit, this.CreateNewCustomerMissingNameParams.UINameEditSendKeys, ModifierKeys.None); // Вводимо '234 Lane St' в текстове поле Address uIAddressEdit.Text = this.CreateNewCustomerMissingNameParams.UIAddressEditText; // Вводимо '{Tab}' в текстове поле Address Keyboard.SendKeys (uIAddressEdit, this.CreateNewCustomerMissingNameParams.UIAddressEditSendKeys, ModifierKeys.None); }}
Кодовані тести UI є такими ж, як і будь-які інші тести. Вони призначені для взаємодії з UI так, як це робив би користувач. На щастя, інструмент Coded UI відмінно справляється із записом ваших дій і генерацією коду, який робить те ж саме. У будь-який момент можна видалити ці тести і згенерувати заново або модифікувати їх без будь-якої мороки. Крім того, як і модульні тести, ви можете запускати кодовані тести UI з Visual Studio Test Explorer. Вони з'являться слідом за модульними тестами.
Підвищіть якість свого ПО
Ви отримуєте реальну вигоду від різних форм тестування. Важливо тестувати навіть малі додатки Windows Store або Windows Phone, особливо якщо ви продаєте їх в магазині додатків.
Ви можете виконувати модульне тестування із застосуванням бібліотек начебто xUnit і qUnit і використовувати автоматичне тестування веб-і «рідних» додатків за допомогою CUIT, не кажучи вже про інших типах важливих тестів, таких як тестування на схвалення користувачем, тестування інтеграції, комплексне тестування і ін . Їх додавання після того, як у вас з'явиться усталений набір модульних і UI-тестів, значно поліпшить якість вашого ПО.