Какие ошибки мой код мог все еще содержать, даже если у меня есть 100%-е покрытие кода?

Какие ошибки мой код мог все еще содержать, даже если у меня есть 100%-е покрытие кода? Я ищу конкретные примеры или ссылки на конкретные примеры таких ошибок.

14
задан Ricardo Altamirano 13 August 2012 в 18:30
поделиться

21 ответ

Наличие 100%-го покрытия кода не является настолько большим, поскольку можно думать о нем. Рассмотрите trival пример:

double Foo(double a, double b)
{
    return a / b;
}

Даже тест единого блока повысит покрытие кода этого метода к 100%, но упомянутый модульный тест не скажет нам, какой код работает и каков код не. Это могло бы быть совершенно действительным кодом, но не тестируя граничные условия (такой как тогда, когда b 0.0), модульный тест является неокончательным в лучшем случае

покрытие Кода только говорит нам, что выполнялось нашими модульными тестами, не, выполнялось ли оно правильно. Это - важное различие для создания. Просто, потому что строка кода выполняется модульным тестом, не обязательно означает, что та строка кода работает, как предназначено.

Слушают это для интересного обсуждения.

37
ответ дан 1 December 2019 в 05:48
поделиться

Почти что-либо.

Вы читали Код, Завершенный ? (Поскольку 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

  • Ошибка, предполагая - информированные предположения о типах входа это часто вызывает ошибки. Например, граничные условия (прочь ошибками), недопустимые данные, очень большие значения, очень маленькие значения, нули, аннулируют, пустые наборы.

И несмотря на это могут быть ошибки в Ваших требованиях, ошибки в Ваших тестах, и т.д. - как другие упомянули.

0
ответ дан 1 December 2019 в 05:48
поделиться

Как упомянуто во многих ответах здесь, Вы могли иметь 100%-е покрытие кода и все еще иметь ошибки.

Вдобавок ко всему, у Вас может быть 0 ошибок, но логика в Вашем коде может быть неправильной (не соответствие требованиям). Покрытие кода или быть 100%, без ошибок, не может помочь Вам с этим вообще.

А типичная корпоративная практика разработки программного обеспечения могла быть следующие:

  1. Имеют явно записанную функциональную спецификацию
  2. , Имеют план тестирования, который это записано против (1), и имейте его, коллега рассмотрел
  3. , Записали тестовые сценарии против (2) и сделали, чтобы они взаимодействовали рассмотренный
  4. , Пишут код против функциональной спецификации и имеют его, коллега рассмотрел
  5. Тест, Ваш код против тестовых сценариев
  6. Действительно кодирует анализ покрытия и пишет больше тестовых сценариев для достижения хорошего покрытия.

Примечание, которое я сказал "хороший" и не "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*.
0
ответ дан 1 December 2019 в 05:48
поделиться

Выполните 100%-е покрытие кода, т.е. 100% инструкций, 100% входных и выходных доменов, 100%-х путей, 100% вообще, о которых Вы думаете, и у Вас все еще могут быть ошибки в Вашем коде: недостающие возможности .

0
ответ дан 1 December 2019 в 05:48
поделиться

К вашему сведению Microsoft Pex пытается выручить путем исследования кода и нахождения "граничных" случаев, как деление нулем, переполнением, и т.д.

, Этот инструмент является частью VS2010, хотя можно установить техническую версию предварительного просмотра в VS2008. Довольно замечательно, что инструмент находит материал, это находит, тем не менее, IME, это все еще не собирается получать Вас полностью к "пуленепробиваемому".

1
ответ дан 1 December 2019 в 05:48
поделиться

Покрытие кода не означает много. То, что имеет значение, - покрыты ли все (или большинство) значений аргументов, которые влияют на поведение.

Для, например, рассматривают типичный 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 (При наличии для Вашего языка).

0
ответ дан 1 December 2019 в 05:48
поделиться

Я не знаю ни о ком больше, но мы не получаем в какой-либо степени 100%-е покрытие. Ни один из наш "Этого никогда не должны происходить" ВЫГОДЫ, осуществлены в наших тестах (хорошо, иногда они делают, но затем код исправлен так, они больше не делают!). Я боюсь, что не волнуюсь, что могла бы быть ошибка Синтаксиса/Логики в never-happen-CATCH

1
ответ дан 1 December 2019 в 05:48
поделиться

Ваш продукт мог бы быть технически корректным, но не выполнить потребности клиента.

1
ответ дан 1 December 2019 в 05:48
поделиться

Хорошо, если Ваши тесты не тестируют вещь, которая происходит в покрытом коде. Если у Вас есть этот метод, который добавляет число к свойствам, например:

public void AddTo(int i)
{
NumberA += i;
NumberB -= i;
}

, Если Ваш тест только проверит свойство NumberA, но не NumberB, то у Вас будет 100%-е покрытие, тестовые передачи, но NumberB будут все еще содержать ошибку.

Заключение: модульный тест с 100% не гарантирует, что код без ошибок.

1
ответ дан 1 December 2019 в 05:48
поделиться

Проверка аргумента, иначе. Пустые Проверки. Если Вы берете какие-либо внешние исходные данные и передаете их в функции, но никогда не проверяете, допустимы ли они/пустые, то можно достигнуть 100%-го покрытия, но Вы все еще получите NullReferenceException, если Вы так или иначе передаете пустой указатель в функцию, потому что это - то, что Ваша база данных дает Вам.

также, арифметическое переполнение, как

int result = int.MAXVALUE + int.MAXVALUE;

Покрытие Кода только покрывает существующий код, это не сможет указать, где необходимо добавить больше кода.

1
ответ дан 1 December 2019 в 05:48
поделиться

В недавней газете программного обеспечения IEEE "Две Ошибки и Безошибочное программное обеспечение: Признание", утверждал Robert Glass, что в "реальном мире" существует больше ошибок, вызванных тем, что он называет недостающей логикой или комбинаторикой (который не может быть предотвращен с инструментами покрытия кода), чем логическими ошибками (который может).

, Другими словами, даже с 100%-м покрытием кода Вы все еще рискуете встречаться с этими видами ошибок. И лучшая вещь, которую можно сделать, - Вы предположили, что она - действительно больше кодирует обзоры.

ссылка на бумагу здесь , и я нашел грубую сводку здесь .

3
ответ дан 1 December 2019 в 05:48
поделиться

Ошибки в тестах :)

2
ответ дан 1 December 2019 в 05:48
поделиться

Покрытие кода ничего не означает, если Ваш тесты содержат ошибки, или Вы тестируете неправильную вещь.

Как связанная касательная; я хотел бы напомнить Вам, что я могу тривиально создать 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, который указал на лазейку, я думал приблизительно

3
ответ дан 1 December 2019 в 05:48
поделиться

Покрытие кода обычно только говорит Вам, сколько из ответвлений в функции застраховано. Это обычно не сообщает о различных путях, которые могли быть взяты между вызовами функции . Много ошибок в программах происходят, потому что передача от одного метода до другого является неправильной, не потому что сами методы содержат ошибки. Все ошибки этой формы могли все еще существовать в 100%-м покрытии кода.

3
ответ дан 1 December 2019 в 05:48
поделиться

Рассмотрите следующий код:

int add(int a, int b)
{
  return a + b;
}

Этот код мог не реализовать некоторую необходимую функциональность (т.е. не встретил требования конечного пользователя): "100%-е покрытие" не обязательно тестирует/обнаруживает функциональность, которая должна быть реализована, но которая не является.

Этот код мог работать на некоторых, но не все диапазоны входных данных (например, когда a и b являются оба очень большими).

3
ответ дан 1 December 2019 в 05:48
поделиться

Могут всегда быть исключения на этапе выполнения: заполняющаяся память, база данных или другие соединения, не закрываемые и т.д.

3
ответ дан 1 December 2019 в 05:48
поделиться

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++ или любом другом языке, который рассматривает "неопределенное поведение"). Иногда это будет проходить Ваши тесты, но это откажет в реальном мире.

...

5
ответ дан 1 December 2019 в 05:48
поделиться

Покрытие кода не означает, что Ваш код является ошибкой, бесплатной всегда. Это - оценка о том, как хорошо Вы - покрытие тестовых сценариев Ваша база исходного кода. 100%-е покрытие кода подразумевало бы, что каждая строка кода тестируется, но каждое состояние Вашей программы, конечно, не. Существует исследование, сделанное в этой области, я думаю, что это упоминается как моделирование конечного состояния, но это - действительно грубая сила способ попытаться исследовать каждое состояние программы.

А более изящным способом сделать то же самое является что-то называемое абстрактной интерпретацией. MSR (Microsoft Research) выпустили что-то позвонившее CodeContracts на основе абстрактной интерпретации. Выезд Pex также, они действительно секач акцента методы тестирования поведения времени выполнения приложения .

я мог записать действительно хороший тест, который даст мне хорошее покрытие, но нет никаких гарантий, что тот тест исследует все состояния, которые могла бы иметь моя программа. Это - проблема записи действительно хороших тестов, который тверд.

покрытие Кода не подразумевает хорошие тесты

11
ответ дан 1 December 2019 в 05:48
поделиться

Поскольку я не видел, что это упомянуло все же, я хотел бы добавить этот поток, который покрытие кода делает не , говорят Вам, какая часть Вашего кода является bugfree.

Это только говорит Вам, что части Вашего кода , гарантировал, что был не протестирован.

6
ответ дан 1 December 2019 в 05:48
поделиться

Мм? Какой-либо вид обычной логической ошибки, я предполагаю? Повреждение памяти, переполнение буфера, простой неверный код, assignment-instead-of-test, список продолжается. Покрытие только, что, оно сообщает, что все пути выполнения кода выполняются, не, что они корректны.

8
ответ дан 1 December 2019 в 05:48
поделиться

работы над моей машиной

Много вещей работают хорошо над локальной машиной, и мы не можем гарантировать что работать над Подготовкой/Производством. Покрытие кода не может покрыть это.

3
ответ дан 1 December 2019 в 05:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: