Я хотел бы протестировать функцию с кортежем из набора дополнительных случаев и нормальных значений. Например, при тестировании функции, которая возвращает true
всякий раз, когда заданы три длины, образующие действительный треугольник, у меня будут конкретные случаи, отрицательные / маленькие / большие числа, значения, близкие к переполнению, и т. Д .; более того, главная цель - создать комбинации этих значений с повторением или без него , чтобы получить набор тестовых данных.
(inf,0,-1), (5,10,1000), (10,5,5), (0,-1,5), (1000,inf,inf),
...
Как примечание: я действительно знаю ответ на этот вопрос, но он может быть полезен для других, и вызов для людей здесь! - опубликую мой ответ позже.
Абсолютно, особенно имея дело с множеством этих комбинаций / комбинаций, я определенно вижу, что первый проход будет проблемой.
Интересная реализация на python, хотя я написал хорошую на C и Ocaml на основе «Алгоритма 515» (см. Ниже). Он написал его на Фортране, как это было тогда в то время, для всех статей «Алгоритм XX», ну, на той сборке или в. Мне пришлось переписать его и сделать небольшие улучшения для работы с массивами, а не диапазонами чисел. Это случайный доступ, я все еще работаю над получением хороших реализаций тех, что упомянуты в четвертом томе 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 г.
choose()
? Это в основном возвращает n-c[i]
выбрать p-(i+1)1
? С новым 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 и т. Д.). Они добавляют к списку классификаций входных параметров.