когда ./www/index.html
не существует, это приведет к 404
, как на это указывает , местоположение должно быть: "public": "./www"
.
Наличие 100%-го покрытия кода не является настолько большим, поскольку можно думать о нем. Рассмотрите trival пример:
double Foo(double a, double b)
{
return a / b;
}
Даже тест единого блока повысит покрытие кода этого метода к 100%, но упомянутый модульный тест не скажет нам, какой код работает и каков код не. Это могло бы быть совершенно действительным кодом, но не тестируя граничные условия (такой как тогда, когда b
0.0
), модульный тест является неокончательным в лучшем случае
покрытие Кода только говорит нам, что выполнялось нашими модульными тестами, не, выполнялось ли оно правильно. Это - важное различие для создания. Просто, потому что строка кода выполняется модульным тестом, не обязательно означает, что та строка кода работает, как предназначено.
Слушают это для интересного обсуждения.
Почти что-либо.
Вы читали Код, Завершенный ? (Поскольку StackOverflow заявляет, что Вы действительно должны .) В Главе 22 это говорит, что "100%-е покрытие оператора является хорошим началом, но это едва достаточно". Остальная часть главы объясняет, как определить который дополнительные тесты добавить. Вот краткий дегустатор.
Структурированное основание, тестирующее и поток данных, тестирующий средства, тестирующие каждый логический путь через программу. Существует четыре пути через изобретенный код ниже, в зависимости от значений A и B. 100%-е покрытие оператора могло быть достигнуто путем тестирования только двух из четырех путей, возможно f=1:g=1/f
и f=0:g=f+1
. Но f=0:g=1/f
даст деление нулевой ошибкой. Необходимо рассмотреть , если операторы и , в то время как и для [1 127] циклы (тело цикла никогда не могло бы выполняться), и каждое ответвление выбор или переключатель оператор.
If A Then
f = 1
Else
f = 0
End If
If B Then
g = f + 1
Else
g = f / 0
End If
Ошибка, предполагая - информированные предположения о типах входа это часто вызывает ошибки. Например, граничные условия (прочь ошибками), недопустимые данные, очень большие значения, очень маленькие значения, нули, аннулируют, пустые наборы.
И несмотря на это могут быть ошибки в Ваших требованиях, ошибки в Ваших тестах, и т.д. - как другие упомянули.
Как упомянуто во многих ответах здесь, Вы могли иметь 100%-е покрытие кода и все еще иметь ошибки.
Вдобавок ко всему, у Вас может быть 0 ошибок, но логика в Вашем коде может быть неправильной (не соответствие требованиям). Покрытие кода или быть 100%, без ошибок, не может помочь Вам с этим вообще.
А типичная корпоративная практика разработки программного обеспечения могла быть следующие:
Примечание, которое я сказал "хороший" и не "100%". 100%-е покрытие не может всегда быть выполнимо достигнуть - в этом случае, Ваша энергия лучше всего потрачена на достижение правильности кода, а не покрытия некоторых неясных ответвлений. Различные виды вещей могут пойти не так, как надо на любом из шагов 1 - 5 выше: неверное представление, неправильная спецификация, неправильно тестирует, неверный код, неправильное выполнение теста... Нижняя строка, один только шаг 6 не является самым важным шагом в процессе.
Конкретный пример неверного кода, который не имеет никаких ошибок и имеет 100%-е покрытие:
/**
* Returns the duration in milliseconds
*/
int getDuration() {
return end - start;
}
// test:
start = 0;
end = 1;
assertEquals(1, getDuration()); // yay!
// but the requirement was:
// The interface should have a method for returning the duration in *seconds*.
Выполните 100%-е покрытие кода, т.е. 100% инструкций, 100% входных и выходных доменов, 100%-х путей, 100% вообще, о которых Вы думаете, и у Вас все еще могут быть ошибки в Вашем коде: недостающие возможности .
К вашему сведению Microsoft Pex пытается выручить путем исследования кода и нахождения "граничных" случаев, как деление нулем, переполнением, и т.д.
, Этот инструмент является частью VS2010, хотя можно установить техническую версию предварительного просмотра в VS2008. Довольно замечательно, что инструмент находит материал, это находит, тем не менее, IME, это все еще не собирается получать Вас полностью к "пуленепробиваемому".
Покрытие кода не означает много. То, что имеет значение, - покрыты ли все (или большинство) значений аргументов, которые влияют на поведение.
Для, например, рассматривают типичный compareTo метод (в Java, но применяется на большинстве языков):
//Return Negative, 0 or positive depending on x is <, = or > y
int compareTo(int x, int y) {
return x-y;
}
, пока у Вас есть тест для compareTo(0,0)
, Вы получаете покрытие кода. Однако Вам нужны по крайней мере 3 тестовых сценария здесь (для этих 3 результатов). Тем не менее это не бесплатная ошибка. Это также платит для добавления тестов для покрытия исключительных / состояний ошибки. В вышеупомянутом случае, Если Вы пробуете compareTo(10, Integer.MAX_INT)
, это собирается перестать работать.
Концевая строка: Попытайтесь разделить свой вход, чтобы разделить наборы на основе поведения, иметь тест по крайней мере для одного входа от каждого набора. Это добавит больше покрытие в истинном смысле.
Также проверка на инструменты как QuickCheck (При наличии для Вашего языка).
Я не знаю ни о ком больше, но мы не получаем в какой-либо степени 100%-е покрытие. Ни один из наш "Этого никогда не должны происходить" ВЫГОДЫ, осуществлены в наших тестах (хорошо, иногда они делают, но затем код исправлен так, они больше не делают!). Я боюсь, что не волнуюсь, что могла бы быть ошибка Синтаксиса/Логики в never-happen-CATCH
Ваш продукт мог бы быть технически корректным, но не выполнить потребности клиента.
Хорошо, если Ваши тесты не тестируют вещь, которая происходит в покрытом коде. Если у Вас есть этот метод, который добавляет число к свойствам, например:
public void AddTo(int i)
{
NumberA += i;
NumberB -= i;
}
, Если Ваш тест только проверит свойство NumberA, но не NumberB, то у Вас будет 100%-е покрытие, тестовые передачи, но NumberB будут все еще содержать ошибку.
Заключение: модульный тест с 100% не гарантирует, что код без ошибок.
Проверка аргумента, иначе. Пустые Проверки. Если Вы берете какие-либо внешние исходные данные и передаете их в функции, но никогда не проверяете, допустимы ли они/пустые, то можно достигнуть 100%-го покрытия, но Вы все еще получите NullReferenceException, если Вы так или иначе передаете пустой указатель в функцию, потому что это - то, что Ваша база данных дает Вам.
также, арифметическое переполнение, как
int result = int.MAXVALUE + int.MAXVALUE;
Покрытие Кода только покрывает существующий код, это не сможет указать, где необходимо добавить больше кода.
В недавней газете программного обеспечения IEEE "Две Ошибки и Безошибочное программное обеспечение: Признание", утверждал Robert Glass, что в "реальном мире" существует больше ошибок, вызванных тем, что он называет недостающей логикой или комбинаторикой (который не может быть предотвращен с инструментами покрытия кода), чем логическими ошибками (который может).
, Другими словами, даже с 100%-м покрытием кода Вы все еще рискуете встречаться с этими видами ошибок. И лучшая вещь, которую можно сделать, - Вы предположили, что она - действительно больше кодирует обзоры.
Покрытие кода ничего не означает, если Ваш тесты содержат ошибки, или Вы тестируете неправильную вещь.
Как связанная касательная; я хотел бы напомнить Вам, что я могу тривиально создать O (1) метод, который удовлетворяет следующий тест псевдокода:
sorted = sort(2,1,6,4,3,1,6,2);
for element in sorted {
if (is_defined(previousElement)) {
assert(element >= previousElement);
}
previousElement = element;
}
бонусная карма Jon Skeet, который указал на лазейку, я думал приблизительно
Покрытие кода обычно только говорит Вам, сколько из ответвлений в функции застраховано. Это обычно не сообщает о различных путях, которые могли быть взяты между вызовами функции . Много ошибок в программах происходят, потому что передача от одного метода до другого является неправильной, не потому что сами методы содержат ошибки. Все ошибки этой формы могли все еще существовать в 100%-м покрытии кода.
Рассмотрите следующий код:
int add(int a, int b)
{
return a + b;
}
Этот код мог не реализовать некоторую необходимую функциональность (т.е. не встретил требования конечного пользователя): "100%-е покрытие" не обязательно тестирует/обнаруживает функциональность, которая должна быть реализована, но которая не является.
Этот код мог работать на некоторых, но не все диапазоны входных данных (например, когда a и b являются оба очень большими).
Могут всегда быть исключения на этапе выполнения: заполняющаяся память, база данных или другие соединения, не закрываемые и т.д.
1. Проблемы "Пространства данных"
Ваш (плохой) код:
void f(int n, int increment)
{
while(n < 500)
{
cout << n;
n += increment;
}
}
Ваш тест:
f(200,100);
Ошибка в использовании реального мира:
f(200,0);
Моя точка: Ваш тест может покрыть 100% строк Вашего кода, но он не будет (обычно) покрывать все Ваше возможное пространство входных данных, т.е. множество всех возможных значений исходных данных.
2. При тестировании против собственной ошибки
Другой классический пример - когда Вы просто принимаете плохое решение в дизайне и тестируете Ваш код против Вашего собственного плохого решения.
, Например, документ спецификаций говорит, "печатают все простые числа [до 113] n", и Вы печатаете все простые числа [до 114] n, но , исключая n. И Ваши модульные тесты тестируют Ваше неверное представление.
3. Неопределенное поведение
Использование значение неинициализированных переменных, вызовите недопустимый доступ к памяти, и т.д. и Ваш код имеет неопределенное поведение (в C++ или любом другом языке, который рассматривает "неопределенное поведение"). Иногда это будет проходить Ваши тесты, но это откажет в реальном мире.
...
Покрытие кода не означает, что Ваш код является ошибкой, бесплатной всегда. Это - оценка о том, как хорошо Вы - покрытие тестовых сценариев Ваша база исходного кода. 100%-е покрытие кода подразумевало бы, что каждая строка кода тестируется, но каждое состояние Вашей программы, конечно, не. Существует исследование, сделанное в этой области, я думаю, что это упоминается как моделирование конечного состояния, но это - действительно грубая сила способ попытаться исследовать каждое состояние программы.
А более изящным способом сделать то же самое является что-то называемое абстрактной интерпретацией. MSR (Microsoft Research) выпустили что-то позвонившее CodeContracts на основе абстрактной интерпретации. Выезд Pex также, они действительно секач акцента методы тестирования поведения времени выполнения приложения .
я мог записать действительно хороший тест, который даст мне хорошее покрытие, но нет никаких гарантий, что тот тест исследует все состояния, которые могла бы иметь моя программа. Это - проблема записи действительно хороших тестов, который тверд.
покрытие Кода не подразумевает хорошие тесты
Поскольку я не видел, что это упомянуло все же, я хотел бы добавить этот поток, который покрытие кода делает не , говорят Вам, какая часть Вашего кода является bugfree.
Это только говорит Вам, что части Вашего кода , гарантировал, что был не протестирован.
Мм? Какой-либо вид обычной логической ошибки, я предполагаю? Повреждение памяти, переполнение буфера, простой неверный код, assignment-instead-of-test, список продолжается. Покрытие только, что, оно сообщает, что все пути выполнения кода выполняются, не, что они корректны.
работы над моей машиной
Много вещей работают хорошо над локальной машиной, и мы не можем гарантировать что работать над Подготовкой/Производством. Покрытие кода не может покрыть это.