РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
979 of 1593 menu

Метод testing.F.Fuzz

Метод testing.F.Fuzz запускает фаззинг-тест, который многократно вызывает фаззинг-функцию с случайно сгенерированными значениями. Фаззинг-тестирование помогает обнаруживать ошибки и паники, которые возникают при обработке некорректных или неожиданных входных данных. Первым параметром метод принимает фаззинг-функцию (func(f *testing.F)), которая содержит логику тестирования и вызывается с различными значениями.

Синтаксис

func Fuzz(f *testing.F)

Метод Fuzz вызывается на объекте типа *testing.F. Внутри фаззинг-функции необходимо использовать метод f.Add для добавления "seed" (начальных) корпусов и f.Fuzz для определения основной логики проверки.

Пример

Давайте напишем фаззинг-тест для функции, которая принимает строку и проверяет, является ли она палиндромом. Мы добавим несколько начальных значений и определим логику проверки:

package main import ( "testing" ) func IsPalindrome(s string) bool { for i := 0; i < len(s)/2; i++ { if s[i] != s[len(s)-1-i] { return false } } return true } func FuzzIsPalindrome(f *testing.F) { // Добавляем seed корпусы f.Add("abcba") f.Add("abcd") f.Add("a") f.Add("") f.Fuzz(func(t *testing.T, s string) { result := IsPalindrome(s) if result && len(s) > 1 { // Проверяем, что палиндром читается одинаково с обеих сторон for i := 0; i < len(s)/2; i++ { if s[i] != s[len(s)-1-i] { t.Errorf("IsPalindrome(%q) = true, but it's not a palindrome", s) } } } }) }

Для запуска фаззинг-теста используйте команду:

go test -fuzz=FuzzIsPalindrome

Результат выполнения команды (пример):

"fuzz: elapsed: 0s, execs: 0 (0/sec), new interesting: 0" "fuzz: elapsed: 1s, execs: 100 (100/sec), new interesting: 2" "fuzz: elapsed: 2s, execs: 200 (100/sec), new interesting: 3" "PASS"

Пример

Фаззинг-тест может принимать несколько типов данных одновременно. Например, функция, которая конкатенирует две строки и проверяет результат:

package main import ( "testing" ) func Concat(a, b string) string { return a + b } func FuzzConcat(f *testing.F) { // Добавляем seed корпусы с несколькими параметрами f.Add("hello", "world") f.Add("foo", "bar") f.Add("", "test") f.Fuzz(func(t *testing.T, a, b string) { result := Concat(a, b) expected := a + b if result != expected { t.Errorf("Concat(%q, %q) = %q, expected %q", a, b, result, expected) } }) }

Результат выполнения фаззинг-теста:

"fuzz: elapsed: 0s, execs: 0 (0/sec), new interesting: 0" "fuzz: elapsed: 1s, execs: 50 (50/sec), new interesting: 1" "fuzz: elapsed: 2s, execs: 100 (50/sec), new interesting: 1" "PASS"

Фаззинг-тест автоматически генерирует новые комбинации входных данных, чтобы найти крайние случаи, которые могут вызвать панику или неверное поведение.

Пример

Давайте рассмотрим, как фаззинг-тест может найти ошибку в функции, которая делит два числа. Мы используем тип данных int:

package main import ( "testing" ) func Divide(a, b int) int { return a / b // Может вызвать панику при b == 0 } func FuzzDivide(f *testing.F) { // Добавляем seed корпусы f.Add(10, 2) f.Add(5, 1) f.Add(0, 1) f.Fuzz(func(t *testing.T, a, b int) { if b == 0 { t.Skip("Skipping division by zero") } result := Divide(a, b) expected := a / b if result != expected { t.Errorf("Divide(%d, %d) = %d, expected %d", a, b, result, expected) } }) }

Результат выполнения фаззинг-теста:

"fuzz: elapsed: 0s, execs: 0 (0/sec), new interesting: 0" "fuzz: elapsed: 1s, execs: 100 (100/sec), new interesting: 2" "--- PASS: FuzzDivide (0.00s)" "PASS"

Фаззинг-тест автоматически пропускает случаи с делением на ноль, но если бы мы не обрабатывали это, он бы нашел панику и сообщил о ней.

Смотрите также

  • метод testing.F.Add,
    который добавляет seed корпусы для фаззинг-теста
  • метод testing.F.Skip,
    который пропускает текущий фаззинг-тест
  • тип testing.T,
    который используется для обычных модульных тестов
  • тип testing.B,
    который используется для бенчмарков
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить