Интеграционные тесты — это тесты, которые проверяют взаимодействие между различными компонентами системы. В отличие от юнит-тестов, которые фокусируются на проверке отдельных функций или методов, интеграционные проверяют, как компоненты работают вместе, обеспечивая целостность и корректность всей системы.
Интеграционные тесты помогают убедиться, что различные части системы правильно взаимодействуют друг с другом. Это важно для выявления проблем на границах между компонентами, которые могут не проявиться в юнит-тестах.
Такие тесты помогают обнаруживать ошибки, возникающие при объединении модулей. Это могут быть проблемы с форматами данных, неправильное использование интерфейсов и другие ошибки, связанные с интеграцией.
Интеграционные тесты могут включать сценарии, приближенные к реальным условиям эксплуатации системы, что позволяет убедиться, что система работает правильно в реальной среде.
Интеграционные тесты могут требовать наличия нескольких зависимостей, таких как база данных, внешние API или другие сервисы. Настройте тестовую среду, которая будет эмулировать реальную среду.
Рассмотрим пример интеграционного теста для приложения, которое работает с базой данных. В этом примере мы будем тестировать функции создания и получения пользователя.
// main.go
package main
import (
"database/sql"
_ "github.com/mattn/go-sqlite3"
"log"
)
type User struct {
ID int
Name string
}
func CreateUser(db *sql.DB, name string) (int, error) {
res, err := db.Exec("INSERT INTO users(name) VALUES(?)", name)
if err != nil {
return 0, err
}
id, err := res.LastInsertId()
if err != nil {
return 0, err
}
return int(id), nil
}
func GetUser(db *sql.DB, id int) (User, error) {
var user User
err := db.QueryRow("SELECT id, name FROM users WHERE id = ?", id).Scan(&user.ID, &user.Name)
if err != nil {
return user, err
}
return user, nil
}
func main() {
db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
log.Fatal(err)
}
defer db.Close()
_, err = db.Exec("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)")
if err != nil {
log.Fatal(err)
}
}
// main_test.go
package main
import (
"database/sql"
"testing"
_ "github.com/mattn/go-sqlite3"
)
func setupTestDB(t *testing.T) *sql.DB {
db, err := sql.Open("sqlite3", ":memory:")
if err != nil {
t.Fatal(err)
}
_, err = db.Exec("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)")
if err != nil {
t.Fatal(err)
}
return db
}
func TestCreateAndGetUser(t *testing.T) {
db := setupTestDB(t)
defer db.Close()
// Создание пользователя
userID, err := CreateUser(db, "John Doe")
if err != nil {
t.Fatalf("Failed to create user: %v", err)
}
// Получение пользователя
user, err := GetUser(db, userID)
if err != nil {
t.Fatalf("Failed to get user: %v", err)
}
// Проверка результатов
if user.Name != "John Doe" {
t.Errorf("Expected name to be 'John Doe', got %s", user.Name)
}
}
Интеграционные тесты проверяют, как различные компоненты системы работают вместе. Они помогают выявлять ошибки на границах между модулями и обеспечивают целостность системы. Пишутся аналогично юнит-тестам, но включают взаимодействие между компонентами и часто требуют настройки тестовой среды.