Случайные данные в модульных тестах?

Вы можете поймать сброшенную ошибку в переменную и выполнить анализ времени выполнения переменной. Например, для некоторой неизвестной реализации:

/* ---------------------- */
/* unknown implementation */
enum HiddenError: ErrorType {
    case SomeError
}

class AnotherError : NSError { }

func foo() throws -> Int {
    let foo = arc4random_uniform(3);
    if foo == 0 {
        throw HiddenError.SomeError
    }
    else if foo == 1 {
        throw AnotherError(domain: "foo", code: 0, userInfo: [:])
    }
    else if foo == 2 {
        throw NSError(domain: "foo", code: 0, userInfo: [:])
    }
    else {
        return Int(foo)
    }
}
/* ---------------------- */

Исследуйте ошибку как:

/* "External" investigation */
func bar() throws -> Int {
    return try foo()
}

func fuzz() {
    do {
        let buzz = try bar()
        print("Success: got \(buzz)")
    } catch let unknownError {
        print("Error: \(unknownError)")
        print("Error type: \(unknownError.dynamicType)")
        if let dispStyle = Mirror(reflecting: unknownError).displayStyle {
          print("Error type displaystyle: \(dispStyle)")
        }
    }
}

fuzz()
/* Output examples:

   Error: SomeError
   Error type: HiddenError
   Error type displaystyle: Enum

   //

   Error: Error Domain=foo Code=0 "(null)"
   Error type: AnotherError
   Error type displaystyle: Class

   //

   Error: Error Domain=foo Code=0 "(null)"
   Error type: NSError
   Error type displaystyle: Class             */
133
задан travis 29 August 2008 в 18:15
поделиться

11 ответов

Существует компромисс. Ваш коллега на самом деле на что-то, но я думаю, что он делает его неправильно. Я не уверен, что полностью случайное тестирование очень полезно, но это, конечно, весьма допустимо.

Программа (или единица) спецификация является гипотезой, что там существует некоторая программа, которая встречает ее. Сама программа является затем доказательством той гипотезы. То, чем должно быть поблочное тестирование, является попыткой обеспечить доказательство противного для опровержения этого работы программы согласно спецификации.

Теперь, можно записать модульные тесты вручную, но это действительно - механическая задача. Это может быть автоматизировано. Все, что необходимо сделать, записать спецификацию, и машина может генерировать партии и много модульных тестов, которые пытаются взломать код.

Я не знаю, какой язык Вы используете, но видите здесь:

Java http://functionaljava.org/

Scala (или Java) http://github.com/rickynils/scalacheck

Haskell http://www.cs.chalmers.se/~rjmh/QuickCheck/

.NET: http://blogs.msdn.com/dsyme/archive/2008/08/09/fscheck-0-2.aspx

Эти инструменты возьмут Вашу правильно построенную спецификацию, как введено и автоматически генерируют столько модульных тестов, сколько Вы хотите с автоматически сгенерированными данными. Они используют стратегии "уменьшения" (который можно настроить) найти, что самый простой тестовый сценарий взламывает код и удостоверяется, что покрывает пограничные случаи хорошо.

Счастливое тестирование!

71
ответ дан 24 November 2019 в 00:03
поделиться

Как Ваш парень может запустить тест снова, когда ему не удалось видеть, зафиксировал ли он его? Т.е. он теряет воспроизводимость тестов.

В то время как я думаю, что существует, вероятно, некоторое значение в бросании загрузки случайных данных в тестах, как упомянуто в других ответах, это больше подпадает под заголовок тестирования загрузки, чем что-либо еще. Это - в значительной степени практика "тестирования надеждой". Я думаю, что в действительности Ваш парень просто не думает о том, что он пытается протестировать и восполняет то отсутствие мысли случайностью надежды, в конечном счете захватит некоторую таинственную ошибку.

Так аргумент я использовал бы с ним, то, что он ленив. Или, другими словами, если он не не торопится для понимания то, что он пытается протестировать его, вероятно, показывает, что он действительно не понимает код, который он пишет.

-2
ответ дан 24 November 2019 в 00:03
поделиться

В зависимости от Вашего объекта/приложения случайные данные имели бы место в тестировании загрузки. Я думаю более важный, должен был бы использовать данные, которые явно тестируют граничные условия данных.

0
ответ дан 24 November 2019 в 00:03
поделиться

Сегодня мы просто столкнулись с этим. Я хотел псевдослучайный (таким образом, это будет похоже на сжатые аудиоданные с точки зрения размера). Я TODO'd, который я также хотел детерминированный. рэнд () отличался на OSX, чем на Linux. И если я не пересеял, это могло измениться в любое время. Таким образом, мы изменили его, чтобы быть детерминированными, но все еще psuedo-случайными: тест повторяем, так же как использование консервированных данных (но более удобно записанный).

Это НЕ тестировало некоторой случайной грубой силой через пути выполнения кода. Вот в чем разница: все еще детерминированный, все еще повторяемый, все еще использующие данные, которые похожи на реальный вход для выполнения ряда интересных проверок в напряжении случаи в сложной логике. Все еще модульные тесты.

Это все еще квалифицирует, случайно? Давайте обсудим пиво.:-)

0
ответ дан 24 November 2019 в 00:03
поделиться

При использовании случайного входа для тестов, необходимо зарегистрировать исходные данные, таким образом, Вы видите, каковы значения. Таким образом, если существует некоторый пограничный случай, Вы сталкиваетесь, можно записать тест для репродуцирования его. Я услышал, что те же причины от людей для того, чтобы не использовать случайный вход, но после того как у Вас есть понимание фактических значений, используемых для конкретного тестового прогона затем, это не такое количество проблемы.

Понятие "произвольных" данных также очень полезно как способ показать что-то, что не важно. У нас есть некоторые приемочные испытания, которые приходят на ум, где существует много шумовых данных, которое не является никаким отношением к тесту под рукой.

1
ответ дан 24 November 2019 в 00:03
поделиться

Ваш коллега делает тестирование пуха, хотя он не знает об этом. Они особенно ценны в системах сервера.

7
ответ дан 24 November 2019 в 00:03
поделиться

Можно ли генерировать некоторые случайные данные однажды (я имею в виду точно, после того как, не однажды на тестовый прогон), затем используйте их во всех тестах после этого?

Я могу определенно видеть значение в создании случайных данных для тестирования тех случаев, о которых Вы не думали, но Вы правы, имея модульные тесты, которые могут случайным образом передать, или сбой является плохой вещью.

4
ответ дан 24 November 2019 в 00:03
поделиться

В книге Красивый Код существует глава, названная "Красивые Тесты", где он проходит стратегию тестирования алгоритма Двоичного поиска. Один абзац называют "Случайными законами Тестирования", в котором он создает случайные массивы для полного тестирования алгоритма. Можно считать часть этого онлайн в Google Books, странице 95, но это - замечательная книга, которую стоит иметь.

Таким образом, в основном это просто показывает, что генерация случайных данных для тестирования является жизнеспособным вариантом.

12
ответ дан 24 November 2019 в 00:03
поделиться
  • если это - случайное значение и тестовые сбои, мы должны a) зафиксировать объект и b) вынудить нас протестировать на то значение каждый раз, таким образом, мы знаем, что оно работает, но так как это случайно, мы не знаем, каково значение было

Если Ваш тестовый сценарий точно не записывает то, что он тестирует, возможно, необходимо повторно кодировать тестовый сценарий. Я всегда хочу иметь журналы, к которым я могу вернуться для тестовых сценариев так, чтобы я знал точно, что заставило это перестать работать ли с помощью статических или случайных данных.

8
ответ дан 24 November 2019 в 00:03
поделиться

Существует социальная гостиница здесь, которая имеет некоторое использование, которое должно отобрать Ваш PRNG с константой. Это позволяет Вам генерировать 'случайные' данные, которые повторяемы.

Лично я действительно думаю, что существуют места, где (постоянные) случайные данные полезны в тестировании - после того, как Вы думаете, что сделали все свои carefully-thought-out углы, использование стимулов от PRNG может иногда находить другие вещи.

24
ответ дан 24 November 2019 в 00:03
поделиться

Этот вид тестирования называют тестом Обезьяны. Когда сделано правильно, это может выкурить ошибки от действительно темных углов.

Обратиться к Вашим опасениям по поводу воспроизводимости: правильный способ приблизиться к этому, состоит в том, чтобы записать неудавшиеся тестовые записи, генерировать модульный тест, который зондирует для всего семейства определенной ошибки; и включайте в модульный тест один определенный вход (от случайных данных), который вызвал начальный отказ.

37
ответ дан 24 November 2019 в 00:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: