📌 Что такое интеграционные тесты ?



💬 Спрашивают в 8% собеседований



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



🤔 Зачем они нужны?



1️⃣Проверка взаимодействия компонентов:

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



2️⃣Выявление ошибок интеграции:

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



3️⃣Проверка реальных сценариев использования:

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



🤔 Как их писать?



1️⃣Создание тестовой среды:

Интеграционные тесты могут требовать наличия нескольких зависимостей, таких как база данных, внешние API или другие сервисы. Настройте тестовую среду, которая будет эмулировать реальную среду.



2️⃣Пример:

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

      // 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)

}

}




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



🔥 ТОП ВОПРОСОВ С СОБЕСОВ



🔒 База собесов | 🔒 База тестовых