Skip to content

Testing

Тестування

Які бувають види тестів?

  • Юніт-тести (Unit Tests) – це тести, які перевіряють окремі модулі коду (функції, методи, класи) на коректність роботи. Ціль таких тестів - переконатися, що кожен модуль працює правильно і не впливає на інші модулі.
  • Інтеграційні тести (Integration Tests) – це тести, які перевіряють, як різні модулі взаємодіють один з одним. Ціль таких тестів - переконатися, що всі модулі працюють разом правильно і не виникають конфлікти.
  • Системні тести (System Tests) - це тести, які перевіряють всю систему в цілому, включаючи всі модулі та взаємодії між ними. Мета таких тестів – переконатися, що система працює правильно та відповідає вимогам.
  • Приймальні тести (Acceptance Tests) – це тести, які виконуються замовником або користувачем для перевірки, чи відповідає система його вимогам та очікуванням. Мета таких тестів – переконатися, що система повністю відповідає вимогам замовника.
  • Навантажувальні тести (Load Tests) - це тести, які перевіряють, як система працює при різних навантаженнях та обсягах даних. Ціль таких тестів - переконатися, що система здатна обробляти великі обсяги даних і не ламається при великому навантаженні.
  • Смоук тести (Smoke Tests) – це тести, які виконуються перед кожним релізом для перевірки, що система працює та не виникають критичні помилки. Мета таких тестів – переконатися, що система готова до релізу та не містить критичних помилок.
  • Тестування продуктивності (Performance testing) - визначає наскільки тестований застосунок стабільний, а також досліджує показники швидкості реакції програми на зовнішні впливи при різному за характером та інтенсивністю навантаження. Метою тестування є виявлення недоліків і вразливостей в системі, визначення швидкості завантаження даних і їх обробки, надійності програми.

Links

Юніт-тести

Юніт-тести (Unit Tests) – це тести, які перевіряють окремі модулі коду (функції, методи, класи) на коректність роботи. Ціль таких тестів - переконатися, що кожен модуль працює правильно і не впливає на інші модулі.

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

Юніт-тести не повинні перевіряти зовнішні залежності або взаємодії. Потрібно замокати (mock out) виклики API. Юніт тести повинні бути швидкими, оскільки передбачається їх частий запуск, що вчасно виявляти помилки в коді.

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

Інтеграційні тести (Integration tests)

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

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

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

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

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

Функціональне тестування

  • Функціональне тестування може бути визначено як тестування окремих функцій модулів.
  • Це відноситься до тестування програмного продукту на індивідуальному рівні, щоб перевірити його функціональність.
  • Воно суттєво відрізняється від модульного або інтеграційного тестування; ви не можете написати безліч тест-кейсів для функціонального тестування, оскільки воно є складнішим, ніж модульне.
  • Інструменти для функціонального тестування спрямовані на перевірку функціональних можливостей (роботоздатність) програмного забезпечення. Тестові приклади використовуються для перевірки очікуваних та непередбачуваних результатів тестування програмного забезпечення.
  • Цей тип тестування проводиться більше з точки зору користувача. Іншими словами, воно розглядає очікування користувача щодо вибраного типу введення даних.
  • Selenium є одним з найпоширеніших інструментів, які використовуються для функціонального тестування.

Системне тестування (System test, Service test)

Автоматизовані тести, які перевіряють роботу всієї інтегрованої системи. По суті, вони представляють собою крайній випадок інтеграційних тестів. Системні тести не перевіряють бізнес-правила безпосередньо. Замість цього вони перевіряють, що компоненти системи правильно пов'язані між собою, а взаємодія між ними відбувається згідно з планом. Тести продуктивності та пропускної здатності, як правило, належать до цієї категорії.

Системне тестування полягає в тестуванні програми в цілому. Для невеликих проектів це, як правило, ручне тестування - запускаєте, натискаєте, переконуєтеся, що (не)працює. Його можна автоматизувати. Є два підходи до автоматизації.

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

Системні тести охоплюють 10% системи. Це пояснюється тим, що вони призначені для перевірки правильності конструкції системи, а не її поведінки. Правильність поведінки усього коду та компонентів вже була перевірена на нижчих рівнях піраміди.

Перевірка працездатності (Smoke test, Sanity check)

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

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

Smoke-тести також можна використовувати під час рефакторингу старого коду, оскільки написання повноцінних модульних тестів може бути дуже часо- та ресурсозатратним.

Регресійне тестування (Regression testing)

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

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

Відмінності між інтеграційним тестуванням та функціональним тестуванням

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

Функціональне тестування також називається E2E-тестуванням для перевірки браузера.

Links

Що таке mocking

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

Links

Що робити, якщо тестована функція використовує віддалене підключення до зовнішніх сервісів, яке іноді видає помилку тайм-ауту, 404 та подібні

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

Що робити, якщо тестована функція займає багато часу на виконання повторюваних операцій всередині себе

Наприклад, всередині циклу від 1 до 1000000, де щось зчитується, записується, розраховується.

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

Якщо функція не відповідає умовам, описаним у першому реченні, слід спочатку розпочати її декомпозицію.