Как использовать комбинации наборов в качестве тестовых данных

StackOverflow https://stackoverflow.com/questions/561

Вопрос

Я хотел бы протестировать функцию с кортежем из набора второстепенных случаев и нормальных значений.Например, при тестировании функции, которая возвращает true всякий раз, когда даны три длины, образующие действительный треугольник, у меня будут конкретные случаи: отрицательные/маленькие/большие числа, значения, близкие к переполнению, и т. д.;более того, основная цель — создать комбинации этих значений, с или без повторение, чтобы получить набор тестовых данных.

(inf,0,-1), (5,10,1000), (10,5,5), (0,-1,5), (1000,inf,inf),
...

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

Это было полезно?

Решение

Абсолютно, особенно имея дело со многими из этих перестановок/комбинаций, я определенно вижу, что первый проход будет проблемой.

Интересная реализация на Python, хотя я написал хорошую реализацию на C и Ocaml на основе «Алгоритма 515» (см. ниже).Он написал свой на Фортране, как это было тогда принято во всех статьях по «Алгоритму XX», ну, та сборка или c.Мне пришлось переписать его и внести небольшие улучшения для работы с массивами, а не с диапазонами чисел.Этот имеет произвольный доступ, я все еще работаю над созданием некоторых хороших реализаций тех, которые упомянуты в четвертом томе Кнута, глава 2.Я объясню читателю, как это работает.Хотя если кому-то интересно, я бы не отказался что-нибудь написать.

/** [combination c n p x]
 * get the [x]th lexicographically ordered set of [p] elements in [n]
 * output is in [c], and should be sizeof(int)*[p] */
void combination(int* c,int n,int p, int x){
    int i,r,k = 0;
    for(i=0;i<p-1;i++){
        c[i] = (i != 0) ? c[i-1] : 0;
        do {
            c[i]++;
            r = choose(n-c[i],p-(i+1));
            k = k + r;
        } while(k < x);
        k = k - r;
    }
    c[p-1] = c[p-2] + x - k;
}

~"Алгоритм 515:Генерация вектора из лексикографического индекса";Баклз, Б.П. и Либанон М.Транзакции ACM в математическом программном обеспечении, Vol.3, нет.2 июня 1977 г.

Другие советы

В новой версии Python 2.6 у вас есть стандартное решение с модулем itertools, который возвращает декартово произведение итерируемых объектов:

import itertools

print list(itertools.product([1,2,3], [4,5,6]))
   [(1, 4), (1, 5), (1, 6),
   (2, 4), (2, 5), (2, 6),
   (3, 4), (3, 5), (3, 6)]

Вы можете предоставить аргумент «повторение», чтобы выполнить продукт с итерацией и самим собой:

print list(itertools.product([1,2], repeat=3))
[(1, 1, 1), (1, 1, 2), (1, 2, 1), (1, 2, 2),
(2, 1, 1), (2, 1, 2), (2, 2, 1), (2, 2, 2)]

Вы также можете что-то настроить с помощью комбинаций:

print list(itertools.combinations('123', 2))
[('1', '2'), ('1', '3'), ('2', '3')]

И если порядок имеет значение, есть перестановки:

print list(itertools.permutations([1,2,3,4], 2))
[(1, 2), (1, 3), (1, 4),
   (2, 1), (2, 3), (2, 4),
   (3, 1), (3, 2), (3, 4),
   (4, 1), (4, 2), (4, 3)]

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

Просто помните, что вы можете преобразовать кортеж или список в набор и наоборот, используя list(), tuple() и set().

Интересный вопрос!

Я бы сделал это, выбрав в Python комбинации, подобные приведенным ниже.Самая сложная часть — это, вероятно, первичная проверка, т.е. if f(1,2,3) returns true, это правильный результат?Как только вы это убедитесь, это станет хорошей основой для регрессионного тестирования.

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

# xpermutations from http://code.activestate.com/recipes/190465
from xpermutations import *

lengths=[-1,0,1,5,10,0,1000,'inf']
for c in xselections(lengths,3):        # or xuniqueselections
    print c
(-1,-1,-1);
(-1,-1,0);
(-1,-1,1);
(-1,-1,5);
(-1,-1,10);
(-1,-1,0);
(-1,-1,1000);
(-1,-1,inf);
(-1,0,-1);
(-1,0,0);
...

Я думаю, вы можете сделать это с помощью Атрибут проверки строки (доступно в MbUnit и более поздних версиях NUnit), где вы можете указать несколько наборов для заполнения одного модульного теста.

Хотя можно создать множество тестовых данных и посмотреть, что произойдет, более эффективно попытаться свести к минимуму количество используемых данных.

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

Вот пример классов входных значений

  • допустимые треугольники с небольшими числами, например (1 миллиард, 2, миллиард, 2 миллиарда)
  • допустимые треугольники с большими числами, например (0,000001, 0,00002, 0,00003).
  • действительные тупоугольные треугольники, которые «почти» плоские, например (10, 10, 19,9999)
  • действительные остроугольные треугольники, которые «почти» плоские, например (10, 10, 0000001)
  • недопустимые треугольники хотя бы с одним отрицательным значением
  • неправильные треугольники, у которых сумма двух сторон равна третьей
  • неправильные треугольники, у которых сумма двух сторон больше третьей
  • входные значения, которые не являются числовыми

...

Если вы удовлетворены списком входных классификаций для этой функции, вы можете создать фактические тестовые данные.Вероятно, было бы полезно протестировать все варианты каждого элемента.(например.(2,3,4), (2,4,3), (3,2,4), (3,4,2), (4,2,3), (4,3,2)) Обычно, вы обнаружите, что некоторые классификации вы пропустили (например, концепцию inf как входного параметра).

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top