Основы тестирования (Quality Assurance)

Tests can make good code great!
  • Статья о IXIA
  • Бажат все, даже такие ведущие вендоры как Cisco (особенно Firepower :D). Важно насколько сырой продукт в текущем состоянии и как быстро исправляют проблемы.
из чатика:
на 65 залипает или вообще не работает вплс, на а1к перестают анонситься маршруты, нцс просто тупо сырые.
как эта циска заебала Есть другие вендоры с рабочими фичами из презентаций, которые не нужно ждать годами и с нормальным саппортом
  • Хорошая книга:
Test Driven Development in Ruby
A Practical Introduction to TDD Using Problem and Solution Domain Analysis
Authors: Paranj, Bala
  • https://3dnews.ru/986328 – история с samsung galgaxy fold показывает, насколько важно хорошее тестирование перед запуском продуктов
  • https://habr.com/ru/post/193902/ – статья про тестирование карандашей как тестовое задания на собесе. Показывает тестировщика как мега-дотошного чела 🙂 Диаграма и годная критика оттуда:

image

Было у меня на собеседовании подобное задание и я тоже стартанул генерировать идеи, шагая по списку критериев качества. Благодаря их комбинированию можно придумать еще пару сотен тестов на этот многострадальный карандашик.
Но меня осадили достаточно просто — у вас разве бесконечно времени и денег?

Первое. Во всей статье нет ни одного слова приоритет.

Зачем вообще вас попросили тестировать карандаши? Какую проблему решает клиент?
Второе. Во всей статье нет ни одного слова риск.

Вы тестируете карандаши в лаборатории по созданию карандашей? Вы тестируете карандаши на заводской линии? Вы тестируете карандаши на открузке в магазины?
Третье. У вас не указан контекст. Впрочем, несколько предположений вы делаете.
Что позволяет выявить тестирование оборудования/систем:
  • Выявление реальных характеристик производительности для клиентов
  • Аргументированные дефекты
  • Поверка сохранения уровня производительности при изменении. 

Test-Driven Development (TDD) – в идеальном случае (не только unit) стоит писать тесты перед написанием кода, далее писать код, запускать этот код на созданные тесты и проверять что все ок. Причем без кода он должен возвращать fail и возвращать true только когда все ок.

Тесты обычно бывают Black Box и White Box. Оба типа могут писаться как до создания непосредственно софта (TDD), так и во время и после написания. Оба лучше использовать и не пренебрегать каким либо из них.

  • White Box (Clear Box, Transparent Testing) – полагается на знание тестером тестируемого кода/внутреннего устройства продукта для создания кейсов для тестов. Тесты пишутся во многом исходя из знания как устроен софт. Преимущество: знания устройства позволяют писать более конкретные тесты, зная на что акцентировать внимание при тестировании.
  • Black Box – тестер не знает как работает софт “внутри”. Тесты пишутся на основе данных которые софт генерирует как результат, требованиям к приложению таких как скорости работы и нагрузка. Преимущество: проверка характеристик приложения, без акцента на особенностях написания кода.
Типы тестов

Случайное (ad-hoc) тестирование – проводя ad-hoc тестирование, тестировщик пытается сломать систему, используя нестандартные методы. Обычно это тестирование не имеет четкого плана, а тестировщики не придерживаются никаких особых методик создания тест-кейсов. Главная цель ad-hoc тестирования – обнаружить баги при помощи случайных проверок.

Дымовое тестирование (Smoke test, build verification test) – базовое тестирование для поиска на явные ошибки (запускается ли программа, принимает ли ввод, генерирует ли она результат).

Тестирование объектов (Unit test) – проверка корректности работы маленькой части изолированной кода. Обычно пишутся одновременно с кодом для проверки поведения отдельных его частей (классов, методов, функций), но могут писаться и до разработки, поэтому нельзя их называть чисто WhiteBox. Должна быть изоляция объекта при тестировании, чтобы не вносить внешние факторы в тестирование – т.е. объект не должен зависить от других. Большая часть сводится к вопросу – давая такой то ввод данных (не обязательно корректных), будет ли в результате корректный вывод.Такой подход позволяет разделить тестирование программы на кучу мелких простых тестирований (divide and conquer), в каждом из которых причин для провала немного, но в совокупности очень много.

Интеграционный тест (Integration test) – проверка корректности работы разных частей кода между собой. Это могут быть отдельные модули по обработке, работающие с сетью, базой данных, api и прочее.

Регрессионное тестирование (Regression testing) – проверка корректности отработки после добавления функционала/изменения зависимых модулей/исправления багов.

Test suite – Группа разных тестов, собранная вместе.

Edge case (corner case) – случай когда в общем unit или софт работает, но в каких-то особых случаях генерирует fail (например, деление на 0). Чаще всего находитcя на крайностях корректного ввода (1-10 usual, 0 и 11 – edge case). В идеале в коде не стоит делать special cases для edge cases (реализовывать заранее универсальные алгоритмы, захватывающие их), чтобы программа продолжала работать as expected, но зачастую без этого никаких не обойтись. Иногда обработка edge case не требуется и даже наоборот, хорошо, если программа падает, нежели продолжает работать дальше в непонятных или опасных условиях (пример с делением на 0 – тот случай, это не та операция, которая должна быть реализована).

Continuous integration – когда программисты делают submit кода в VCS, на этот код автоматически запускаются тесты на баги и ошибки. Полезная, но зачастую сложная для реализации вещь.

 

Ruby example

У ruby нет в стандартной библиотеке тестирующей среды. Есть gem test-unit, который позволяет делать тесты. Сначала устанавливаем.

gem install test-unit

Тесты должны жить в отдельном от тестируемого кода файле.

script.rb
test_script.rb

Подгружаем то, что тестируем в тестируемый код.

require 'test/unit'
require_relative 'script'

При использовании этого gem нужно организовывать тесты в классы, которые наследуют от класса TestCase. Простейший тест – проверка что то, что мы отдаем методу является тем, что мы ожидаем. Будь то корректный результат или ошибка – но главное что именно то, что мы ожидаем (assertion). В результате теста будет время, количество попыток и еще куча другой полезной инфы.

class ScriptTest < Test::Unit::TestCase

def test_basic
x = 10
y = 2
expected = 5
assert_equal(expected, script_method(x, y))
end

def test_err
x = 1
y = 0
assert_raise( ZeroDivisionError ) { script_method(x, y) }
end

end

Leave a Reply