2010-10-14 45 views
11

Câu hỏi: Tôi đang thử nghiệm các chức năng trong một gói mà tôi đang phát triển và muốn biết liệu bạn có thể đề xuất một số hướng dẫn chung về cách thực hiện điều này hay không. Các chức năng bao gồm một phạm vi rộng lớn của mô hình thống kê, biến đổi, subsetting, và âm mưu. Có một 'tiêu chuẩn' hoặc một số thử nghiệm đủ?nguyên tắc kiểm tra chức năng thống kê trong R?

Một thí dụ: các bài kiểm tra đó nhắc tôi hỏi câu hỏi này,

Chức năng dtheta:

dtheta <- function(x) { 
    ## find the quantile of the mean 
    q.mean <- mean(mean(x) >= x) 
    ## find the quantiles of ucl and lcl (q.mean +/- 0.15) 
    q.ucl <- q.mean + 0.15 
    q.lcl <- q.mean - 0.15 
    qs <- c(q.lcl, q.mean, q.ucl) 
    ## find the lcl, mean, and ucl of the vector 
    c(quantile(x,qs), var(x), sqrt(var(x))/mean(x)) 
} 

Bước 1: làm cho dữ liệu thử nghiệm:

set.seed(100) # per Dirk's recommendation 
test <- rnorm(100000,10,1) 

Bước 2: so sánh sản lượng dự kiến ​​từ hàm với đầu ra thực tế từ hàm:

expected <- quantile(test, c(0.35, 0.65, 0.5)) 
actual <- dtheta(test)[1:3] 
signif(expected,2) %in% signif(actual,2) 

Bước 3: có lẽ làm một thử nghiệm

test2 <- runif(100000, 0, 100) 
expected <- c(35, 50, 65) 
actual <- dtheta(test2) 
expected %in% signif(actual,2) 

Bước 4: nếu đúng, hãy xem xét chức năng 'chức năng'

Trả lời

6

Tùy thuộc vào chính xác những gì bạn muốn kiểm tra. Bên cạnh các khuyến nghị Dirks, svUnit hoặc RUnit gói VitoshKa đã đề cập, tôi muốn thêm một vài điều:

  • Thật vậy, thiết lập các hạt giống, nhưng chắc chắn rằng bạn thử chức năng với hạt giống khác nhau là tốt. Một số chức năng không chỉ một lần mười lần bạn thử. Đặc biệt khi tối ưu hóa có liên quan, điều này trở nên rất quan trọng. replicate() là một chức năng tốt để sử dụng trong ngữ cảnh này.
  • Suy nghĩ rất tốt về đầu vào bạn muốn thử nghiệm. Bạn nên kiểm tra một số trường hợp "lẻ" không thực sự giống với tập dữ liệu "hoàn hảo". Tôi luôn kiểm tra ít nhất 10 bộ dữ liệu (mô phỏng) có kích thước khác nhau.
  • Chống phân tách hàm: Tôi cũng ném vào một số loại dữ liệu không phải là loại dữ liệu có nghĩa là chức năng đó. Đầu vào loại sai có khả năng sẽ xảy ra tại một thời điểm và điều cuối cùng bạn muốn là hàm trả về kết quả không có thật mà không có cảnh báo. Nếu bạn sử dụng chức năng đó sau đó trong một số mã khác, gỡ lỗi mã đó có thể và sẽ! là địa ngục. Đã ở đó, thực hiện điều đó, đã mua áo phông ...

Ví dụ về thử nghiệm mở rộng các tập dữ liệu: bạn muốn xem đầu ra trong những trường hợp này là gì? Đây có phải là kết quả bạn mong đợi không? Không theo thử nghiệm bạn đã làm.

> test3 <- rep(12,100000) # data with only 1 value 
> expected <- c(12, 12, 12) 
> actual <- dtheta(test3) 
Error in quantile.default(x, qs) : 'probs' outside [0,1] 

> test4 <- rbinom(100000,30,0.5) # large dataset with a limited amount of values 
> expected <- quantile(test4,c(0.35, 0.50, 0.65)) 
> actual <- dtheta(test4) 
> expected %in% signif(actual,2) 
[1] FALSE TRUE TRUE 

> test5 <- runif(100,0,100) # small dataset. 
> expected <- c(35, 50, 65) 
> actual <- dtheta(test5) 
> expected %in% signif(actual,2) 
[1] FALSE FALSE FALSE 

chỉnh sửa: sửa mã để kiểm tra có ý nghĩa hơn một chút.

+1

+1 Joris để kiểm tra đầu vào. Tôi cũng sẽ thêm vào để kiểm tra * đầu ra *. Đầu ra của các hàm của bạn phải là * dự đoán được * và * được định nghĩa chính xác *. Thật không may vào thời điểm này, chức năng cơ bản của R đôi khi chỉ hút. Không bao giờ biết chính xác những gì hàm trả về trừ khi bạn đi đến tài liệu một lần nữa, và một lần nữa, và một lần nữa ... – VitoshKa

5

đẹp câu hỏi.

Ngoài các đặc điểm chung như đặt hạt giống, tôi khuyên bạn nên xem xét một số thử nghiệm trong nguồn R. Các thư mục tests/ trong nguồn có một sự giàu có của những; một số gói trong R Base (chẳng hạn như công cụ) cũng có thư mục con tests/.

+0

Tài nguyên tuyệt vời. Cảm ơn con trỏ. Tôi đã thêm set.seed() vào mã của tôi và chắc chắn sẽ bắt đầu sử dụng nó. Bạn có sử dụng nó để phân tích hoặc chỉ thử nghiệm và ví dụ? –

+1

Nếu không có hạt giống cố định, bạn không có khả năng tái sản xuất so sánh, gỡ lỗi, ... một chút khó khăn hơn ;-) –

+3

Có thể bạn đã biết về [runit] (http://cran.r-project.org/web/packages/RUnit /index.html) – VitoshKa

6

Bạn cần phải viết

  1. xét nghiệm cho thấy bạn nhận được câu trả lời đúng khi bạn nhập vào giá trị hợp lý

  2. xét nghiệm cho thấy chức năng của bạn không chính xác khi bạn nhập vô nghĩa.

  3. thử nghiệm cho tất cả các trường hợp ranh giới

Có một số lượng lớn tài liệu về chiến lược khác nhau cho phần mềm thử nghiệm; Wikipedia software testing page là một nơi tốt để bắt đầu.

Nhìn vào ví dụ của bạn:

Điều gì sẽ xảy ra khi bạn nhập một chuỗi/dataframe/danh sách?
Điều gì về tiêu cực x hoặc tưởng tượng x?
Làm thế nào về véc tơ/mảng x?
Nếu chỉ cho phép tích cực x thì điều gì sẽ xảy ra tại x = 0?

Lưu ý rằng các chức năng con (chỉ được gọi bởi các chức năng của bạn và không bao giờ bởi người dùng) cần kiểm tra đầu vào ít hơn vì bạn có nhiều quyền kiểm soát hơn những gì đi vào chức năng.

3

Nó đã xuất hiện dưới dạng nhận xét, nhưng tôi sẽ thêm nhận xét đó làm câu trả lời đầy đủ. R có một vài gói thử nghiệm tự động để trợ giúp với loại điều này, hai gói chính là Runittestthat. Tôi đã sử dụng một thời gian ngắn runit, và gần đây đã bắt đầu sử dụng testthat sâu hơn (tôi không thể thực sự cung cấp cho bất kỳ lợi thế/bất lợi tốt của một trong những khác mặc dù!).

Thử nghiệm tự động cho phép bạn thiết lập các trường hợp thử nghiệm này, cũng như các trường hợp khác như được đề xuất ở trên như;

  • Boundary Tests
  • thử nghiệm căng thẳng (ít cần phải kiểm tra về tính chính xác, chỉ cần ném dữ liệu vào nó và xem nếu nó rơi trở lên)
  • Xử lý đầu vào khác nhau
  • Đối phó với các nền tảng cơ bản/địa phương khác nhau
+1

đừng quên 'svUnit', một phần của sciviews. – mariotomo

Các vấn đề liên quan