2008-08-02 27 views
18

Tôi muốn thử nghiệm một hàm với một bộ dữ liệu từ một tập hợp các trường hợp rìa và các giá trị thông thường. Ví dụ, trong khi thử nghiệm một hàm trả về true bất cứ khi nào cho ba độ dài tạo thành một tam giác hợp lệ, tôi sẽ có trường hợp cụ thể, số âm/nhỏ/lớn, giá trị gần được tràn, vv; hơn nữa, mục đích chính là tạo các kết hợp của các giá trị này, với hoặc mà không cần lặp lại để có được một tập dữ liệu thử nghiệm.Cách sử dụng kết hợp các bộ làm dữ liệu thử nghiệm

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

Là một lưu ý: Tôi thực sự biết câu trả lời cho điều này, nhưng nó có thể hữu ích cho người khác, và một thách thức đối với người dân nơi đây! - sẽ đăng câu trả lời của tôi sau này.

+0

[Abacus github] (https://github.com/foo123/Abacus) một thư viện tổ hợp cho Node.JS, Python, PHP, Actionscript (ps tôi là tác giả) –

Trả lời

14

Tuyệt đối, đặc biệt là đối phó với rất nhiều những hoán vị/kết hợp chắc chắn tôi có thể thấy rằng đèo đầu tiên sẽ là một vấn đề.

Thực hiện thú vị trong python, mặc dù tôi đã viết một chữ đẹp trong C và Ocaml dựa trên "Thuật toán 515" (xem bên dưới). Ông đã viết của mình tại Fortran vì nó đã được phổ biến trở lại sau đó cho tất cả các "Thuật toán XX" giấy tờ, tốt, mà lắp ráp hoặc c. Tôi đã phải viết lại nó và thực hiện một số cải tiến nhỏ để làm việc với các mảng không nằm trong phạm vi số. Điều này một truy cập ngẫu nhiên, tôi vẫn đang làm việc trên nhận được một số triển khai tốt đẹp của những người được đề cập trong Knuth 4 khối lượng fascicle 2. Tôi sẽ giải thích về cách thức này hoạt động cho người đọc. Mặc dù nếu ai đó tò mò, tôi sẽ không phản đối việc viết thứ gì đó lên.

/** [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; 
} 

~ "Thuật toán 515: Tạo một Vector từ Chỉ số Lexicographical"; Buckles, B. P., và Lybanon, M. ACM Giao dịch trên phần mềm toán học, Vol. 3, số 2, tháng 6 năm 1977.

+0

'select()' làm gì ? Điều đó về cơ bản có trả về 'n-c [i]' chọn 'p- (i + 1) 1' không? – mkb

+0

@mkb Tất nhiên. – nlucaroni

+0

Tôi xin lỗi, tôi không tuân theo hành vi chọn. Có vẻ như nó được định nghĩa là tự phản xạ - chọn không chọn. Bạn có thể cho tôi biết những gì nó làm trong điều kiện đơn giản hơn? – CuppM

4

Câu hỏi thú vị!

Tôi sẽ làm điều này bằng cách chọn kết hợp, giống như sau trong python. Phần khó nhất có lẽ là lần đầu tiên vượt qua xác minh, tức là if f(1,2,3) returns true, đó có phải là kết quả chính xác không? Khi bạn đã xác minh điều đó, thì đây là cơ sở tốt để thử nghiệm hồi quy.

Có lẽ bạn nên làm một bộ các trường hợp thử nghiệm mà bạn biết sẽ là đúng (ví dụ 3,4,5 cho trường hợp tam giác này) và một bộ các trường hợp kiểm tra mà bạn biết sẽ là sai (ví dụ 0,1, inf). Sau đó, bạn có thể dễ dàng xác minh các bài kiểm tra là chính xác.

 
# 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

Tôi nghĩ bạn có thể làm điều này với Row Test Attribute (có sẵn trong MbUnit và các phiên bản sau này của NUnit), nơi bạn có thể chỉ định một số bộ để thử nghiệm đơn vị.

0

Mặc dù có thể tạo nhiều dữ liệu thử nghiệm và xem điều gì sẽ xảy ra, nhưng bạn nên giảm thiểu tối đa dữ liệu đang được sử dụng.

Từ góc độ QA điển hình, bạn sẽ muốn xác định các phân loại đầu vào khác nhau. Tạo ra một tập hợp các giá trị đầu vào cho mỗi phân loại và xác định các đầu ra thích hợp.

Dưới đây là một mẫu của lớp đầu vào giá trị

  • tam giác còn hiệu lực với số lượng nhỏ như (1 tỷ, 2, tỷ, 2 tỷ đồng)
  • tam giác còn hiệu lực với số lượng lớn như (0.000001, 0,00002 , 0,00003)
  • tam giác tù hợp lệ mà là 'almost'flat như (10, 10, 19,9999)
  • tam giác cấp tính hợp lệ mà là 'gần như' phẳng như (10, 10, 0.000.001)
  • tam giác không hợp lệ Wi thứ ít nhất một giá trị âm
  • tam giác không hợp lệ mà tổng của hai bên bằng với ba
  • tam giác không hợp lệ mà tổng của hai bên lớn hơn
  • giá trị đầu vào thứ ba mà không phải số

...

Khi bạn đã hài lòng với danh sách phân loại đầu vào cho hàm này, bạn có thể tạo dữ liệu thử nghiệm thực tế. Có khả năng, sẽ rất hữu ích khi kiểm tra tất cả hoán vị của từng mục. (ví dụ: (2,3,4), (2,4,3), (3,2,4), (3,4,2), (4,2,3), (4,3,2)) Thông thường, bạn sẽ thấy có một số phân loại bạn đã bỏ qua (chẳng hạn như khái niệm inf như một tham số đầu vào).

Dữ liệu ngẫu nhiên trong một khoảng thời gian có thể hữu ích, có thể tìm thấy các lỗi lạ trong mã, nhưng nói chung là không hiệu quả.

Nhiều khả năng, chức năng này đang được sử dụng trong một số ngữ cảnh cụ thể khi áp dụng các quy tắc bổ sung (ví dụ: chỉ giá trị nguyên hoặc giá trị phải là gia số 0,01).

4

Với thương hiệu mới Python 2.6, bạn có một giải pháp tiêu chuẩn với các mô-đun itertools trả về sản phẩm Descartes của iterables:

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)] 

Bạn có thể cung cấp một "lặp lại" lập luận để thực hiện các sản phẩm với một iterable và bản thân:

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)] 

Bạn cũng có thể tinh chỉnh một cái gì đó với sự kết hợp cũng như:

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

Và nếu vấn đề trật tự, có hoán vị:

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)] 

Tất nhiên tất cả những gì nội dung thú vị không chính xác làm điều tương tự, nhưng bạn có thể sử dụng chúng trong một cách này hay cách khác để giải quyết vấn đề bạn.

Chỉ cần nhớ rằng bạn có thể chuyển đổi tuple hoặc danh sách thành tập hợp và ngược lại bằng cách sử dụng list(), tuple() và set().