Тестування програмного забезпечення Перевірка коду засобами Юніт Тестування
Тестування програмного забезпечення Перевірка коду засобами Юніт Тестування
Якісний продукт 100% якісних програм не існує Ступінь якості залежить від: наскільки продукт відповідає вимогам і сподіванням замовника наскільки продукт відповідає вимогам і сподіванням юзера
Як розробити якісний продукт? Основні обмеження: Scope - обсяг робіт Time (Schedule) – час Cost (Resources) – ресурси (люди, комп’ютери, ін.)
Тестування програмного забезпечення це процес виконання програми з ціллю знаходження помилок (bugs) це процес, який використовується для вимірювання ступеня якості розробленої програми – перевірка на скільки продукт відповідає вимогам та потребам замовника та юзера.
Для чого потрібно тестувати? Деякі помилки є неважливими, але деякі можуть бути дуже дорогими і навіть небезпечними “Errare humanum est,” (людині властиво помилятися),
Космічний апарат Mars Climate Orbiter (1998) зійшов з курсу на 60 миль, коли він наближався Марс через помилки і місія зазнала значних втрат $ 125 million Для чого потрібно тестувати?
Жовтень 26th і 27th 1992 – London Ambulance Service problem People lost their lives!!! Для чого потрібно тестувати?
Pay me now or pay me more later
Типи тестувань: найзагальніші Testability Unit Testing Integration Testing Smoke Testing Functional Testing GUI Testing Usability Testing Regression Testing Performance Testing Load Testing Stress Testing Acceptance Testing Alpha Testing Beta Testing
DEV Відповідальності в тестуванні QA Client User Testability Unit Integration Smoke Functional GUI Usability Performance Load Stress Acceptance Alpha Beta Regression
Середовище для тестування
Unit Testing Unit testing це процедура, яка використовується для перевірки чи окремі частини (юніти) коду працюють коректно. Юніт тестування – це автоматизовані тести, які перевіряють функціональність в компоненті, класі, методі чи властивості. Вони є основою автоматизованого і регресивного тестування, які забезпечують довготермінову стабільність та майбутню підтримку проекту.
Unit Testing Ціллю юніт тестування є ізоляція окремої частини програми і демонстрація, що ця частина працює коректно. Цей тип тестування проводять програмісти. Юніт тестування надалі дозволить програмісту проводити рефакторинг чи зміну коду з впевненістю, що покрита тестами частина коду працює коректно.
Інтеграційне тестування Integration testing це така фаза тестування програмного забезпечення, на якій окремі програмні модулі комбінуються і тестуються як група. Ціллю такого тестування є знаходження дефектів, які виникають між окремими модулями підчас їх спільного функціонування.
Never send a human to do a machine's job.
Rise of Continuous Integration Offload from people, push to computers
Ми всі тестуємо наші програми і навіть пишемо тести
Властивості юніт тестів ❂ Вони повинні бути автоматизовані і повторювальні ❂ Їх легко можна реалізувати. ❂ Один раз написані – використовуються без змін у майбутньому. ❂ Кожен може запустити їх. ❂ Вони повинні запускатися натисканням кнопки ❂Вони повинні виконуватись швидко
Integration and unit tests Відмінності між юніт та інтеграційним тестуванням
Test-Driven Development (TDD) Традиційних шлях написання юніт-тестів Test-driven development
Test-Driven Development (TDD) TDD описується як цикл red-green-refactor, який повторюється для додавання нових властивостей до програми або для фіксання багів. Red Розробка нової функціональності повинна починатися з проваленого тесту. Green Потрібно написати код, щоб тест був пройдений Refactor Вдосконалюємо структуру коду для покращення його розширюваності та підтримки.
Unit-testing frameworks UTF for .NET: MSTest (integrated into VS) NUnit XUnit … JavaScript unit testing: Qunit SinonJS Chutzpah
Створення Unit Tests 1. Утворити Unit Test проект . Додати його до вашого solution
Створення Unit Tests 2. Вибрати ім’я проекту
Створення Unit Tests 3. В Unit Test проекті додай посилання на проект, який треба тестувати In VS-2010: A separate unit test is created for each selected method. Each unit test has empty variables and a placeholder Assert statement usually the Assert.Inconclusive. To make the test meaningful, you have to initialize the variables and replace the placeholder with an appropriate Assert statement. For each class separate unit test file is created in the test project After you run your tests, the results appear in the Test Results window.
Створення Unit Tests 5. Пишіть ваші unit test
Run unit tests 1. Відкрити Test Explorer. 2. Запускаємо unit tests.
Run unit tests Результати запуску юніт тестів можна побачити в вікні Test Explorer.
Види Assert класів Microsoft.VisualStudio.TestTools.UnitTesting namespace: class Assert class CollectionAssert Для порівняння колекцій об»єктів, перевіряє стан одного чи більше колекцій. class StringAssert Для порівняння рядків.
public static class Assert Містить множину статичних методів які обчислюють Boolean умови Основа виконання юніт тестів Перевіряє умови в юніт тестах : якщо умова дає true, тест pass якщо умова дає false, тест fail Клас Assert генерує AssertFailedException для повідомлення про помилку в тесті. Це повідомлення перехоплюється механізмом Unit Test для відображення того, що тест не пройшов. Цей тип винятку не можна перехоплювати [SerializableAttribute] public class AssertFailedException:UnitTestAssertException
public static class Assert
Assert.AreEqual
public static void AreEqual( Object expected, Object actual, string message, params Object[] parameters) expected The first object to compare. This is the object the unit test expects. actual The second object to compare. This is the object the unit test produced. message A message to display if the assertion fails. This message can be seen in the unit test results. parameters An array of parameters to use when formatting message. public static void AreEqual( string expected, string actual, bool ignoreCase ) ignoreCase A Boolean value that indicates a case-sensitive or insensitive comparison. true indicates a case-insensitive comparison. Assert.AreEqual
Testing Bank project
class ExpectedExceptionAttribute AttributeUsageAttribute( AttributeTargets.Method, AllowMultiple = false, Inherited = true)] public sealed class ExpectedExceptionAttribute : ExpectedExceptionBaseAttribute Позначає, що цей виняток може буде згенеровано в коді програми.
public static class CollectionAssert
public static class StringAssert System.Text.RegularExpressions.Regex Represents an immutable regular expression.
Disable and Enable Tests Ignore attribute [Ignore] – якщо ви маєте доступ до коду тесту, то використовуйте цей атрибут для тимчасового ігнорування тесту Disable and enable. Якщо ви не маєте доступу до коду тесту, то для тимчасового усунення тесту можна використовувати лише Test Manager Window і змінювати його властивість disable/enable.
TestContext Using public class TaxTest { private TestContext testContextInstance; public TestContext TestContext {get{return testContextInstance;} set{testContextInstance = value;} } [DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", "|DataDirectory|\\SampleTaxData.csv", "SampleTaxData#csv", DataAccessMethod.Sequential), DeploymentItem("FinancialLibTests\\SampleTaxData.csv"), TestMethod()] public void AmountPlusTaxTestDataDriven() { Tax tax = new Tax(); decimal amount = convert.ToDecimal(TestContext.DataRow["Amount"]); }
Data-Driven Unit Test Є два способи для встановлення дати до юніт тесту з певного зовнішнього джерела (csv, xml файлів) Використовувати Властивості ( Properties) юніт тестів В тесті отримуваи дані з властивості TestContext.DataRow
Основні результати тестів Aborted. The tester stopped the test run. The test that was running at the time obtains the Aborted status. The rest of the tests in the test run obtain the status of Not Executed. NotRunnable. The test could not be run because of errors in the test definition. For example, a unit test is NotRunnable if it returns an integer; unit test methods must return void. Timeout. The test or the test run timed out. In Progress. The test is currently running. Inconclusive. When the test ran, no Assert statement produced a Failed result, but at least one Assert.Inconclusive statement was satisfied. This result applies only to unit tests. Failed. The exact meaning depends on the test type Passed. The exact meaning depends on the test type
Використання заглушок (stubs) для зменшення залежностей Зовнішні залежності (external dependency) є зовнішній об’єкт в методі, який ми тестуємо і який ми не можемо контролювати (filesystems, threads, memory, time, and so on.) Заглушка (stub) є контрольована заміна для існуючої залежності в програмі. Використовуючи заглушки ми можемо тестувати код без проблем із залежностями. Тестуючи цей метод – ми зможемо створити лише інтеграційний тест і маємо наступні проблеми:інтеграційний тест повільніше працює, вимагає конфігурації, тестує багато речей одночасно.
Arrange Act Assert (AAA) Pattern Сучасні тести містять три частини: { //Arrange – встановити все, що необхідно для виконання тесту: // ініціалізацію залежностей, моки (заглушки), дані тесту Mailbox mailbox = new Mailbox(); //Act – виклик коду, що тестується var result = mailbox.GetCount(0); //Assert – визначення успішного критерію для тесту Assert.AreEqual("No new messages.", result); }
Mock objects/Fake Objects Patterns Метод GetCountFromProvider, має залежність з інтерфейсом IMessageProvider: public string GetCountFromProvider(IMessageProvider MessageProvider) { if (MessageProvider.Count == 0) { return "No new messages."; } else { return "New messages: " + MessageProvider.Count.ToString(); } }
Mock objects/Fake Objects Patterns Ми можемо визначити фейковий (несправжній) message provider об»єкт, який зможемо контролювати : public class FakeMessageProvider : IMessageProvider { int count; public int Count { get { return count; } } public void SetCount(int newValue) { count = newValue; } }
Mock objects/Fake Objects Patterns [TestMethod] public void GetCountFromProvider_ItemCountIsZero_NoNewMessages() { Mailbox mailbox = new Mailbox(); FakeMessageProvider fakeProvider = new FakeMessageProvider(); fakeProvider.SetCount(0); var result = mailbox.GetCountFromProvider(fakeProvider); Assert.AreEqual("No new messages.", result); } Тест утворює об’єкт FakeMessageProvider, ініціалізує його і передає як аргумент. Якщо використовувати моки, створені вручну – це значно ускладнює тест. Також можливі нові помилки у фейкових класах.
Mock objects/Fake Objects Patterns Кращим вирішенням проблеми є використання готових бібліотек, наприклад Typemock Isolator: [TestMethod] public void GetCountFromProvider_FakeItemCountIsZero_NoNewMessages() { Mailbox mailbox = new Mailbox(); IMessageProvider fakeProvider = Isolate.Fake.Instance
Mock objects/Fake Objects Patterns public string GetCountFromCenter() { if (MessageCenter.Count == 0) { return "No new messages."; } else { return "New messages: " + MessageCenter.Count.ToString(); } } Якщо код залежить від статичних даних, або якщо потрібно задавати конкретне значення методу:
Mock objects/Fake Objects Patterns [TestMethod] public void GetCountFromCenter_ItemCountIsZero_NoNewMessages() { Mailbox mailbox = new Mailbox(); Isolate.WhenCalled(() => MessageCenter.Count).WillReturn(0); var result = mailbox.GetCountFromCenter(); Assert.AreEqual("No new messages.", result); } В таких випадках використовуємо Isolator для встановлення поведінки властивості Count таким самим способом, як ми робимо і для об’єктів.
Mock objects/Fake Objects Patterns Тести, які використовують Моки – є швидші, оскільки заміняють повільну поведінку (Виклики файлової системи, cloud) операціями в пам’яті). Вони націлені на уникнення впливу залежних об’єктів на тестований код і роблять тест незалежним. Використання моків вимагає зв’язності коду. Читабельність тесту залежить від того, як тестований код виглядає. Чим більш складний код, тим менш читабельним буде тест.
Creating unit tests http://www.visualstudio.com/en-us/get-started/create-and-run-unit-tests-vs.aspx Unit Testing Patterns - http://www.typemock.com/unit-test-patterns-for-nete?utm_expid=280644-6.oGMbnIDNSjevav7f9-VXvg.4&utm_referrer=https%3A%2F%2Fwww.google.com.ua%2F Red-Green-Refactor approach info: http://philmunro.wordpress.com/2012/01/15/tdd-and-the-red-green-refactor-approach/, http://www.giorgiosironi.com/2010/03/tdd-checklist-red-green-refactor-in.html Test doubles http://adamcod.es/2014/05/15/test-doubles-mock-vs-stub.html;
12656-lektsiya29_unit_test.ppt
- Количество слайдов: 51