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

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

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

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

5 ответов

Решение

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

Интересная реализация на python, хотя я написал хорошую на C и Ocaml на основе "Алгоритма 515" (см. Ниже). Он написал его на Фортране, как это было тогда в то время, для всех статей "Алгоритм XX", ну, на той ассамблее или в. Мне пришлось переписать его и сделать небольшие улучшения для работы с массивами, а не диапазонами чисел. Это случайный доступ, я все еще работаю над получением хороших реализаций тех, что упомянуты в 4-м томе Knuth тома 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: генерация вектора из лексикографического индекса"; Buckles, BP, и Lybanon, М. 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)]

Вы можете предоставить аргумент "repeat" для выполнения продукта с итерацией и самого себя:

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
из xpermutations import *

длины =[-1,0,1,5,10,0,1000,'инф']
для c в xselections(длины,3):        # или xuniqueselections
    печать с
(-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), где вы можете указать несколько наборов для заполнения одного модульного теста.

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

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

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

  • допустимые треугольники с небольшими числами, такими как (1 миллиард, два миллиарда, два миллиарда)
  • допустимые треугольники с большими числами, такими как (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 и т. Д.). Они добавляют к списку классификаций входных параметров.

Другие вопросы по тегам