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

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

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

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

Ответов (5)

Решение

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

Интересная реализация на 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, No. 2, июнь 1977 г.

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

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

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

# xpermutations из http://code.activestate.com/recipes/190465
из импорта xpermutations *

lengths = [- 1,0,1,5,10,0,1000, 'inf']
для c в xselections (lengths, 3): # или xuniqueselections
    печать c
(-1, -1, -1);
(-1, -1,0);
(-1, -1,1);
(-1, -1,5);
(-1, -1,10);
(-1, -1,0);
(-1, -1,1000);
(-1, -1, инф);
(-1,0, -1);
(-1,0,0);
...

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

While it's possible to create lots of test data and see what happens, it's more efficient to try to minimize the data being used.

From a typical QA perspective, you would want to identify different classifications of inputs. Produce a set of input values for each classification and determine the appropriate outputs.

Here's a sample of classes of input values

  • valid triangles with small numbers such as (1 billion, 2, billion, 2 billion)
  • valid triangles with large numbers such as (0.000001, 0.00002, 0.00003)
  • valid obtuse triangles that are 'almost'flat such as (10, 10, 19.9999)
  • valid acute triangles that are 'almost' flat such as (10, 10, 0000001)
  • invalid triangles with at least one negative value
  • invalid triangles where the sum of two sides equals the third
  • invalid triangles where the sum of two sides is greater than the third
  • input values that are non-numeric

...

Once you are satisfied with the list of input classifications for this function, then you can create the actual test data. Likely, it would be helpful to test all permutations of each item. (e.g. (2,3,4), (2,4,3), (3,2,4), (3,4,2), (4,2,3), (4,3,2)) Typically, you'll find there are some classifications you missed (such as the concept of inf as an input parameter).

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

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

В новом 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 ().