2008-08-02 2 views
18

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

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

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

+0

[Abacus github] (https://github.com/foo123/Abacus) библиотека комбинаторики для Node.JS, Python, PHP, Actionscript (ps, я автор) – 2015-03-05 23:04:49

ответ

14

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

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

/** [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 Transactions on Mathematical Software, Vol. 3, № 2, июнь 1977 года.

+0

Что делает `select()` do ? Это в основном возвращает `n-c [i]` select `p- (i + 1) 1`? – mkb 2012-02-28 04:01:34

4

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

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

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

 
# 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); 
... 
2

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

0

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

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

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

  • действительных треугольников с малыми числами, такими как (1 млрд, 2, млрд, 2 млрд)
  • действительных треугольники с большими числами, такими как (0.000001, 0.00002 , 0,00003)
  • действительные тупые треугольники, которые являются «almost'flat, такие как (10, 10, 19.9999)
  • действительных острых треугольников, которые являются 'почти' плоской, такой, как (10, 10, 0000001)
  • недействительных треугольников Wi го по меньшей мере, одно отрицательное значение
  • недействительных треугольников, где сумма двух сторон равны третьи
  • недействительных треугольники, где сумма двух сторон больше, чем третий
  • входных значений, которые являются нечисловой

...

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

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

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

4

С новенькой 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().