Как мы знаем, тестирование — это проверка того, дает ли определенный фрагмент кода желаемый результат или нет. Testing is Go используется для следующих целей:

  • Покрытие
  • Бенчмаркинг
  • Параллелизм
  • Срывать

Тестирование возможно в ходу следующими способами:

(a) Сравнение ванили:

Включено в Go:

  • == и !=
  • отразить.DeepEqual
  • github.com/google/go-cmp

(b) Пакеты утверждений

В основном операторы равенства, предоставляемые Go, проверяют, действительно ли два заданных значения равны или нет, тогда как gocmp помогает нам определить, являются ли два предоставленных значения/структуры семантически равными или нет. Семантическое равенство — это когда данные, предоставленные двумя разными объектами, имеют одинаковое значение.

Давайте начнем с тестирования функций go обычным способом, то есть с использованием оператора равенства. Возьмем простую функцию:

func SumSimple(a, b int) int {
return a + b
}

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

func TestSumSimple(t *testing.T) {
t.Parallel()
type input struct {
a int
b int
}
tests := []struct {
name     string
input    input
expected int
}{
{
"OK: 1+2",
input{1, 2},
4,
},
{
"OK: 2-2",
input{2, -2},
0,
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()
if actual := operation.SumSimple(test.input.a, test.input.b); actual != test.expected {
t.Fatalf("expected %d, actual %d", test.expected, actual)
}
})
}
}

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

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

func ConcatenateSlice(a, b []int) []int {
res := make([]int, len(a), len(a)+len(b))
_ = copy(res, a)
res = append(res, b...)
return res
}

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

func TestConcatenateSlice_Equally(t *testing.T) {
t.Parallel()
type (
input struct {
a []int
b []int
}
)
tests := []struct {
name     string
input    input
expected []int
}{
{
"OK",
input{
[]int{1, 2},
[]int{-1, -2},
},
[]int{1, 2, -1, -2},
},
}
for _, test := range tests {
test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()
actual := operation.ConcatenateSlice(test.input.a, test.input.b)
if len(actual) != len(test.expected) {
t.Fatalf("result lenghts are different: expected %d, actual %d", len(test.expected), len(actual))
}
for i, v := range actual {
if v != test.expected[i] {
t.Fatalf("values at %d index are different: expected %d, actual %d", i, test.expected[i], v)
}
}
})
}
}

Таким образом, если ввод равен [1,2] и [-1,-2], вывод будет в порядке, что «точно равно» [1,2,-1,-2]:

И если входные данные равны [1,-2] и [-1.2], он возвращает ошибку, поскольку значения не совсем равны.

Итак, эта функция только проверяет, равны ли значения в точности или нет, поэтому нам нужно определить другую функцию для семантического равенства.

func TestCmp_SlicesSematicallySorting(t *testing.T) {
t.Parallel()
tests := []struct {
name   string
input  []int
output []int
}{
{"OK",
[]int{1, 2, 3},
[]int{2, 1, 3}
},
}
for _, test := range tests {
test := testt.Run(test.name, func(t *testing.T) {
t.Parallel()
opt := cmpopts.SortSlices(func(a, b int) bool {
return a < b
})
if !cmp.Equal(test.input, test.output, opt) {
t.Fatalf("values are not the same %s", cmp.Diff(test.input, test.output, opt))
}
})
}
}

Когда функция проверяется таким образом, она проверяет, равны ли значения семантически или нет. Будь то [1,2],[-1,-2] или [1,-2],[-1,2] вывод всегда будет:

Итак, вот как gocmp помогает нам проверить, равны ли значения семантически или нет.

Для справки:

операция «github.com/MarioCarrion/videos/2021/01/23-go-package-equality-google-go-cmp»