У меня будет столько тестов, сколько потребуется, чтобы обеспечить высокий уровень доверия к системе.
Количество таблиц, правил, строк кода и т. Д. Фактически не имеет значения.
У вас должны быть соответствующие модульные тесты, чтобы убедиться, что ваши доменные объекты и бизнес-правила запускаются правильно. У вас должны быть тесты, чтобы убедиться, что ваши запросы выполняются должным образом (это сложнее).
Возможно, вы даже захотите иметь контрольные примеры для путей через программное обеспечение. Другими словами, нажмите здесь, получите эту страницу, щелкните там, отредактируйте поле, сохраните страницу, вернитесь назад ... Этот тип является наиболее сложным, поскольку тесты обычно записываются и должны быть перезаписаны при изменении страниц (т.е. : поле добавлено или удалено).
Вообще говоря, это больше охват , чем количество тестов. Вы хотите, чтобы ваши тесты охватывали столько функциональности приложений, сколько возможно осуществимо . Обратите внимание, что я не сказал, возможно. Вы можете покрыть все приложение (100%) тестовыми примерами, но для каждого небольшого изменения, исправления ошибки и т. Д. Вам придется перекодировать эти тесты. Это более желательно для зрелого приложения. Для более новых приложений вы не хотите мешать своим разработчикам и команде QA таким образом, поскольку они будут тратить слишком много времени на исправление / изменение модульных тестов ...
Для любой системы вы можете потратить столько же времени на разработку автоматических тестов, сколько и на саму систему. В некоторых случаях даже больше.
Что касается нашей группы, у нас, как правило, много юнит-тестов. Однако для тестирования путей через систему мы записываем их только после того, как определенная область перешла в режим «обслуживания». Это означает, что мы ожидаем небольших изменений в течение некоторого времени в этой области, и тестирование пути просто для того, чтобы убедиться, что никто его не измотает.
ОБНОВЛЕНИЕ: комментарии привели меня к следующему:
Идем немного дальше: давайте рассмотрим 1 небольшой фрагмент кода:
Int32 AddNumbers(Int32 a, Int32 b) {
return a+b;
}
На первый взгляд, вы можете обойтись одним тестом:
Int32 result = AddNumbers(1,2);
Assert.Equals(result, 3);
Однако этого, вероятно, недостаточно. Что произойдет, если вы сделаете это:
Int32 result = AddNumbers(Int32.MaxValue, 1);
Assert.Equals(result, (Int32.MaxValue+1));
Теперь у нас сбой. Вот еще один:
Int32 result = AddNumbers(Int32.MinValue, -1);
Assert.Equals(result, (Int32.MinValue-1));
Итак, у нас очень простой метод, который требует как минимум 3 теста. Первоначальный, чтобы увидеть, может ли он дать какой-либо результат, затем 2 для проверки границ. Это 3 теста для двух строк кода (определение метода и вычисление в одну строку).
Поскольку ваш код становится более сложным, все становится очень рискованным:
Decimal DivideThis(Decimal a, Decimal b) {
result = Decimal.Divide(a,b);
}
Это небольшое изменение вводит еще одно исключительное условие за пределами границ: DivideByZero. Итак, теперь нам требуется до 4 тестов для двух строк кода.
Теперь давайте немного упростим это:
String AppendData(String data, String toAppend) {
return String.Format("{0}{1}", data, toAppend);
}
Наш тестовый пример:
String result = AppendData("Hello", "World");
Assert.Equals(result, "HelloWorld");
Это всего лишь один тестовый блок для блока кода, другие не нужны.
Что это говорит нам: для начала 2 строки кода могут потребовать от 1 до 4 тестовых случаев. Вы упомянули 50 тыс. Строк ... Используя эту логику, вам потребуется от 50 000 до 200 000 тестовых случаев ...
Конечно, жизнь редко бывает такой простой. В этих 50-тысячных строках кода будут большие блоки кода с очень ограниченными входными данными. Например, калькулятор процентов по ипотечному кредиту может принимать 3 параметра и возвращать 1 значение (APR). Сам код может содержать около 100 строк (некоторое время, просто поработайте со мной). Количество тестовых случаев для этого будет определяться краевыми случаями вдоль линий, обеспечивающих правильную обработку округления.
Итак, скажем, это 5 случаев: это приводит нас к 20 строкам кода = 1 случай. Вычисление этого из ваших 50k строк может привести к 2500 тестам. Очевидно, намного меньше, чем мы ожидали выше.
Наконец, я собираюсь добавить еще одну морщинку в смесь.Некоторые тестовые системы могут обрабатывать входные данные и ваши утверждения, поступающие из файла данных.Рассматривая наш первый, мы могли бы иметь файл данных, в котором есть строка для каждой комбинации параметров, которую мы хотим протестировать.В этом сценарии нам нужен только 1 контрольный пример для покрытия 3 (или более ..) возможных условий.
Контрольный пример может выглядеть следующим образом (псевдокод):
read input file.
parse expected result, parameter 1, parameter 2
run method
assert method result = parsed result
repeat for each line of the file
При этомвозможности, мы до 1 тестового случая в сценарий .Я бы сказал 1 на метод, но реальность такова, что большинство методов редко бывают автономными, и вполне возможно, что многочисленные методы неявно тестируются посредством явного тестирования других;поэтому не требуются собственные индивидуальные тесты.
Это приводит меня к следующему: невозможно определить правильное количество тестовых случаев без полного понимания вашей кодовой базы.5 случаев, которые находятся на уровне пользовательского интерфейса, может быть достаточно для полного охвата в зависимости от сложности тестов;или это может занять тысячи.Поэтому гораздо лучше основывать его на покрытии кода.Какой процент кода и логики ветвления вы тестируете?