2016-02-09 1 views
6

Здесь я расскажу об этом на примере. Исходный вопрос представляет проблему более абстрактно. Не нужно читать.Где добавить утверждение для каждого сгенерированного теста Intellitest

Update: Вопрос в качестве примера

позволяет сказать, что мы реализовали эту функцию багги для нахождения мин ИНТ []:

public int MyMin(int[] data) 
{ 
    int min = 1000; 

    for (int i = 1; i < data.Length; i++) 
    { 
     if (data[i] < min) 
     { 
      min = data[i]; 
     } 
    } 

    return min; 
} 

Запуск Intellitest на этой функции дает нам: enter image description here

Примечание: для проверки №4 и №6 функция не вычисляет минимальное значение из-за его ошибочной реализации. Однако эти тесты проходят, что нежелательно.

Intellitest не может магически определить наше намеренное поведение MyMin и обработать тест с ошибкой на этих входах. Однако было бы очень хорошо, если бы мы могли вручную указать желаемый результат для этих тестов.

Решение @ michał-komorowski возможно, но для каждого тестового случая я должен повторить его ввод в терминах PexAssume. Есть ли более элегантный/чистый способ указать желаемый выход для тестовых входов?

Оригинал Вопрос

Intelitest генерирует параметризованный тест, который является изменяемыми и общими/глобальными утверждения могут быть добавлены там. Он также генерирует минимальное количество входов, которые максимизируют охват кода. Intellitest хранит входы в виде отдельных модульных тестов, каждый из которых вызывает параметризованный тест с созданным вводом.

Я ищу способ добавить утверждение для каждого входа.

Поскольку каждый вход хранится как функция проверки единицы в файле .g.cs, это утверждение может быть добавлено. Проблема в том, что эти функции не должны настраиваться пользователем, так как они будут перезаписаны Intellitest в последующих запусках.

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

ответ

2

Не следует добавлять утверждения к методам тестирования (методы с атрибутом [TestMethod]). Они используются только для предоставления значений параметров. Для размещения утверждений используются методы с атрибутом [PexMethod].

Вначале это может выглядеть как ограничение. Однако, если мы рассмотрим, как работает IntelliTest, это не так. Нет смысла добавлять утверждение на каждый вход, поскольку входы могут быть удалены, обновлены или созданы в любой момент. Например, когда:

  • Испытуемый метод был изменен.
  • PexAssume класс использовался.
  • Изменен атрибут PexMethod.

Однако вы можете сделать что-то еще, например, добавить более одного «метода Pex» для тестируемого метода и использовать PexAssume.Например, предположим, что у нас есть метод BubbleSort, и мы хотим определить разные утверждения в зависимости от длины входного массива.

[PexMethod] 
public void BubbleSort(int[] a) 
{ 
    PexAssume.IsTrue(a.Length == 5); 
    int[] result = Program.BubbleSort(a); 
    // Assertions specific for an array with 5 elements 
} 

[PexMethod] 
public void BubbleSort(int[] a) 
{ 
    PexAssume.IsTrue(a.Length == 10); 
    int[] result = Program.BubbleSort(a); 
    // Assertions specific for an array with 10 elements 
} 
+0

Hi Michal. Хотя это может быть полезно для добавления утверждений для общих условий (например, длина массива в вашем примере), но это громоздко и повторяемо, чтобы указать каждый тестовый ввод «PexAssume». Пожалуйста, ознакомьтесь с обновленным вопросом, на котором я приведу пример. – Isaac

0

Этот ответ основывается на предыдущем ответе. Это более конкретный вопрос, который был задан.

Pex генерирует тест для всех кодов кода, но ничего не знает о вашем коде. Вы все равно должны выполнить аранжировку/действие/утверждение в PUT (параметризованный модульный тест), чтобы сообщить Pex, как вы думаете, что ваш код должен работать. Кроме того, вы можете добавить предположение перед аранжировкой, чтобы шаблон принимал/устраивал/действовал/утверждал.

Для вашего примера я начинаю с этого PUT.

[PexMethod(MaxRunsWithoutNewTests = 200)] 
    [PexAllowedException(typeof(NullReferenceException))] 
    public int MyMin([PexAssumeUnderTest]Class1 target, int[] data) 
    { 
     //assume 
     PexAssume.IsTrue(data.Length == 1); 
     //arrange 
     data[0] = 0; 

     //act 
     int result = target.MyMin(data); 

     //assert 
     PexAssert.AreEqual(0, result); 
     return result; 
    } 

Результаты показывают, что только 3/8 блоки были покрыты и что тест 2 не удалось ожидаемому «0», получил «1000»

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

Я вижу, что я начинаю цикл for с 1 вместо 0. Поэтому я исправляю код и снова запускаю IntelliTest.

На этот раз я получаю два проходящих теста, которые хороши. Но были протестированы только 6/8 блоков. Я что-то упускаю.

Я создаю новый PUT, который позволяет Pex генерировать данные, которые выглядят следующим образом.

[PexMethod(MaxRunsWithoutNewTests = 200)] 
    [PexAllowedException(typeof(NullReferenceException))] 
    public int MyMin2([PexAssumeUnderTest]Class1 target, int[] data) 
    { 
     //assume 

     //act 
     int result = target.MyMin(data); 

     //assert 
     return result; 
    } 

Теперь у меня есть 7 модульных тестов, в которых выполняются все дорожки кода и все тесты проходят.

Вы заметите, что каждый PUT производит собственный набор тестов.

Смежные вопросы