2012-05-31 6 views
21

Zaczynam wdrażać testy dla pakietu R i używam pakietu testthat. Zauważ, że jestem nowy w testowaniu, więc być może moje podejście jest wyłączone.Jak sprawdzić, czy błąd nie występuje?

Mam funkcję, która obecnie kończy się niepowodzeniem po raz 16, kiedy jest wykonywana, i przed naprawieniem tego chcę napisać test regresji, który go wyłapie, jeśli ponownie się pojawi.

np Zawsze po rzuca ten sam komunikat o błędzie:

for i in (1:17) myfun() 

myfun nie zwraca niczego, ma tylko ten skutek uboczny otwarcia połączenia z bazą danych. Oczywiste jest dla mnie, że mogę napisać test, który oczekuje błąd i przechodzi jeżeli jest ona zwracana:

expect_error(for (i in 1:17) myfun()) 

Ale nie dość dostać jak napisać test, aby upewnić się, że błąd nie występuje. Ponieważ nie jest to oczywiste, być może moje podejście jest złe. Mogę wymyślić, jak napisać bardziej szczegółowe testy, ale chciałbym zacząć od tego.

Jakiego rodzaju test powinienem napisać, aby upewnić się, że taki błąd się nie pojawia?

Odpowiedz

19

Główne edycji z powodu zmian w testthat

od wersji 0.11 (poprzez RStudio blog) istnieje bezpośrednie wsparcie testowania braku błędów:

expect_error(myfun(), NA) 

To samo dotyczy przechwytywania warning i message:

expect_warning(myfun(), NA) 
expect_message(myfun(), NA) 

marginesie: jeśli test pętli jest info parametr w expect_xxx funkcji przekazać dodatkowe informacje. Więc można zrobić:

for (i in 1:17) expect_error(myfun(), NA, info = paste("i =", i)) 
5

Na przykład:

context("test error") 
test_that("test error 1", { 
    expect_true({log(10); TRUE}) 
}) 

test_that("test error 2", { 
    expect_true({log("a"); TRUE}) 
}) 

będzie sprawdzić, czy nie ma błędu.

> test_file("x.r") 
test error : .1 


    1. Error: test error 2 ------------------------- 
    Non-numeric argument to mathematical function 
    1: expect_true({ 
      log("a") 
     TRUE 
    }) 
    2: expect_that(object, is_true(), info, label) 
    3: condition(object) 
    4: expectation(identical(x, TRUE), "isn't true") 
    5: identical(x, TRUE) 

oznacza to, że pierwsza część zdała test, a druga część nie.

+0

dzięki, ale nie jestem zaznajomiony z korzystania z klamrami i średnikiem wewnątrz oczekiwań (np 'expect_true ({...; ...})') mogłyby proszę wyjaśnić? –

+0

Możesz tam umieścić dowolne wyrażenie. I '{...; ...; ...} 'to tylko wyrażenie. W twoim przypadku powinno to być napisane jako 'expect_true ({for (i in 1:17) {myfun()}; TRUE})'. – kohske

+0

Więc to zasadniczo próbuje złapać błąd, ponieważ błąd uniemożliwiłby ocenę drugiej części wyrażenia (w tym przypadku "TRUE")? –

2

Oto jedno rozwiązanie używając oczekiwanie, że tryCatch powraca 0 gdy błąd nie występuje:

expect_equal(tryCatch(for(i in 1:17) myfun()), 0) 
7

Może owinąć go innym expect_error.

przykład:

expect_error(1) 
expect_error(expect_error(1)) 
+1

Jesteś geniuszem! – qed

+0

To już nie działa (wersja 1.0.2) –

Powiązane problemy