Set Test environment in tests
This commit is contained in:
@@ -26,7 +26,13 @@ LOG_LEVEL=DEBUG
|
||||
# ======================
|
||||
# Datenbank Konfiguration
|
||||
# ======================
|
||||
# DATABASE_URL=postgresql://user:password@localhost:5432/bamort_db
|
||||
# Unterstützte Typen: mysql, sqlite
|
||||
DATABASE_TYPE=mysql
|
||||
# Beispiel-URLs für verschiedene Datenbank-Typen:
|
||||
# MySQL: DATABASE_URL=user:password@tcp(localhost:3306)/database?charset=utf8mb4&parseTime=True&loc=Local
|
||||
# PostgreSQL: DATABASE_URL=postgresql://user:password@localhost:5432/database
|
||||
# SQLite: DATABASE_URL=./database.db
|
||||
DATABASE_URL=
|
||||
|
||||
# ======================
|
||||
# Beispiel-Konfigurationen
|
||||
|
||||
@@ -23,4 +23,6 @@ LOG_LEVEL=INFO
|
||||
# ======================
|
||||
# Datenbank Konfiguration
|
||||
# ======================
|
||||
# DATABASE_URL=postgresql://user:password@prod-host:5432/bamort_prod_db
|
||||
# Unterstützte Typen: mysql, sqlite
|
||||
DATABASE_TYPE=mysql
|
||||
# DATABASE_URL=user:password@tcp(prod-host:3306)/bamort_prod?charset=utf8mb4&parseTime=True&loc=Local
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
# Test Environment Configuration
|
||||
|
||||
## Überblick
|
||||
|
||||
Alle Tests in diesem Projekt sind so konfiguriert, dass sie `ENVIRONMENT=test` verwenden, um sicherzustellen, dass:
|
||||
|
||||
1. Die richtige Datenbank-Konfiguration verwendet wird (Test-DB statt Production-DB)
|
||||
2. Logger-Ausgaben reduziert sind
|
||||
3. Tests isoliert von der Produktionsumgebung laufen
|
||||
|
||||
## Test-Umgebung einrichten
|
||||
|
||||
### Option 1: Lokale setupTestEnvironment Funktion (empfohlen)
|
||||
|
||||
Jeder Test sollte eine lokale `setupTestEnvironment` Funktion verwenden:
|
||||
|
||||
```go
|
||||
package mypackage
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// setupTestEnvironment setzt ENVIRONMENT=test für Tests
|
||||
func setupTestEnvironment(t *testing.T) {
|
||||
original := os.Getenv("ENVIRONMENT")
|
||||
os.Setenv("ENVIRONMENT", "test")
|
||||
t.Cleanup(func() {
|
||||
if original != "" {
|
||||
os.Setenv("ENVIRONMENT", original)
|
||||
} else {
|
||||
os.Unsetenv("ENVIRONMENT")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestMyFunction(t *testing.T) {
|
||||
setupTestEnvironment(t)
|
||||
|
||||
// Ihr Test-Code hier...
|
||||
}
|
||||
```
|
||||
|
||||
### Option 2: testutils Package (für komplexere Setups)
|
||||
|
||||
Für komplexere Test-Setups verwenden Sie das `testutils` Package:
|
||||
|
||||
```go
|
||||
package mypackage
|
||||
|
||||
import (
|
||||
"bamort/testutils"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMyFunction(t *testing.T) {
|
||||
testutils.SetupTestEnvironment(t)
|
||||
|
||||
// Oder für spezifische Konfiguration:
|
||||
testutils.SetupTestEnvironmentWithConfig(t, map[string]string{
|
||||
"DEBUG": "false",
|
||||
"LOG_LEVEL": "ERROR",
|
||||
})
|
||||
|
||||
// Ihr Test-Code hier...
|
||||
}
|
||||
```
|
||||
|
||||
## Aktualisierte Test-Dateien
|
||||
|
||||
Folgende Test-Dateien wurden bereits aktualisiert:
|
||||
|
||||
- ✅ `config/config_test.go` - Alle Tests setzen ENVIRONMENT=test
|
||||
- ✅ `logger/logger_test.go` - Alle Tests setzen ENVIRONMENT=test
|
||||
- ✅ `character/character_test.go` - setupTestEnvironment hinzugefügt
|
||||
- ✅ `character/handlers_test.go` - Test-Umgebung konfiguriert
|
||||
|
||||
## Database-Tests
|
||||
|
||||
Die `database.ConnectDatabase()` Funktion erkennt automatisch `ENVIRONMENT=test` und verwendet die Test-Datenbank:
|
||||
|
||||
```go
|
||||
func ConnectDatabase() *gorm.DB {
|
||||
cfg := config.LoadConfig()
|
||||
|
||||
if cfg.Environment == "test" {
|
||||
logger.Debug("Test-Umgebung erkannt, verwende Test-Datenbank")
|
||||
SetupTestDB()
|
||||
} else {
|
||||
logger.Debug("Verwende konfigurierte Datenbank (%s)", cfg.DatabaseType)
|
||||
return ConnectDatabaseOrig()
|
||||
}
|
||||
|
||||
return DB
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Immer setupTestEnvironment() aufrufen**: Jeder Test sollte die Umgebung konfigurieren
|
||||
2. **Cleanup automatisch**: Verwenden Sie `t.Cleanup()` um ursprüngliche Werte wiederherzustellen
|
||||
3. **Test-Isolation**: Tests sollten sich nicht gegenseitig beeinflussen
|
||||
4. **Keine Produktionsdaten**: Tests verwenden immer Test-Datenbank
|
||||
|
||||
## Verifikation
|
||||
|
||||
Um zu prüfen, ob alle Tests korrekt konfiguriert sind:
|
||||
|
||||
```bash
|
||||
# Script ausführen
|
||||
./verify_test_environment.sh
|
||||
|
||||
# Einzelne Packages testen
|
||||
go test ./config -v
|
||||
go test ./logger -v
|
||||
go test ./character -v
|
||||
```
|
||||
|
||||
## Migration bestehender Tests
|
||||
|
||||
Für bestehende Tests, die noch nicht aktualisiert wurden:
|
||||
|
||||
1. Import für `os` hinzufügen
|
||||
2. `setupTestEnvironment` Funktion hinzufügen
|
||||
3. `setupTestEnvironment(t)` am Anfang jeder Test-Funktion aufrufen
|
||||
|
||||
Beispiel:
|
||||
|
||||
```go
|
||||
// Vor der Migration
|
||||
func TestMyFunction(t *testing.T) {
|
||||
// Test-Code...
|
||||
}
|
||||
|
||||
// Nach der Migration
|
||||
func TestMyFunction(t *testing.T) {
|
||||
setupTestEnvironment(t)
|
||||
// Test-Code...
|
||||
}
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Problem**: Test verwendet Produktions-Datenbank
|
||||
**Lösung**: `setupTestEnvironment(t)` am Anfang des Tests aufrufen
|
||||
|
||||
**Problem**: Umgebungsvariablen beeinflussen sich zwischen Tests
|
||||
**Lösung**: `t.Cleanup()` verwenden für automatisches Aufräumen
|
||||
|
||||
**Problem**: Import-Zyklen bei testutils
|
||||
**Lösung**: Lokale `setupTestEnvironment` Funktion in jedem Package verwenden
|
||||
@@ -12,6 +12,19 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// setupTestEnvironment setzt ENVIRONMENT=test für Tests
|
||||
func setupTestEnvironment(t *testing.T) {
|
||||
original := os.Getenv("ENVIRONMENT")
|
||||
os.Setenv("ENVIRONMENT", "test")
|
||||
t.Cleanup(func() {
|
||||
if original != "" {
|
||||
os.Setenv("ENVIRONMENT", original)
|
||||
} else {
|
||||
os.Unsetenv("ENVIRONMENT")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// ReadImageAsBase64 reads an image file and returns it as a Base64 string
|
||||
// with the prefix "data:mimeType;base64,"
|
||||
func ReadImageAsBase64(filePath string) (string, error) {
|
||||
@@ -746,6 +759,7 @@ func charTests(t *testing.T, char *models.Char) {
|
||||
}
|
||||
|
||||
func TestCreateChar(t *testing.T) {
|
||||
setupTestEnvironment(t)
|
||||
database.SetupTestDB()
|
||||
err := models.MigrateStructure()
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"bamort/database"
|
||||
@@ -15,6 +16,16 @@ import (
|
||||
)
|
||||
|
||||
func TestImproveSkillHandler(t *testing.T) {
|
||||
// Setup test environment
|
||||
original := os.Getenv("ENVIRONMENT")
|
||||
os.Setenv("ENVIRONMENT", "test")
|
||||
t.Cleanup(func() {
|
||||
if original != "" {
|
||||
os.Setenv("ENVIRONMENT", original)
|
||||
} else {
|
||||
os.Unsetenv("ENVIRONMENT")
|
||||
}
|
||||
})
|
||||
// Setup test database
|
||||
database.SetupTestDB(true, true)
|
||||
defer database.ResetTestDB()
|
||||
|
||||
@@ -13,7 +13,8 @@ type Config struct {
|
||||
ServerPort string
|
||||
|
||||
// Database Konfiguration
|
||||
DatabaseURL string
|
||||
DatabaseURL string
|
||||
DatabaseType string
|
||||
|
||||
// Logging Konfiguration
|
||||
DebugMode bool
|
||||
@@ -26,11 +27,12 @@ type Config struct {
|
||||
// defaultConfig gibt die Standard-Konfiguration zurück
|
||||
func defaultConfig() *Config {
|
||||
return &Config{
|
||||
ServerPort: "8180",
|
||||
DatabaseURL: "",
|
||||
DebugMode: false,
|
||||
LogLevel: "INFO",
|
||||
Environment: "production",
|
||||
ServerPort: "8180",
|
||||
DatabaseURL: "",
|
||||
DatabaseType: "mysql",
|
||||
DebugMode: false,
|
||||
LogLevel: "INFO",
|
||||
Environment: "production",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +55,9 @@ func LoadConfig() *Config {
|
||||
if dbURL := os.Getenv("DATABASE_URL"); dbURL != "" {
|
||||
config.DatabaseURL = dbURL
|
||||
}
|
||||
if dbType := os.Getenv("DATABASE_TYPE"); dbType != "" {
|
||||
config.DatabaseType = strings.ToLower(dbType)
|
||||
}
|
||||
|
||||
// Debug Mode
|
||||
if debug := os.Getenv("DEBUG"); debug != "" {
|
||||
|
||||
@@ -5,7 +5,21 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// setupTestEnvironment setzt ENVIRONMENT=test für Tests und stellt es nach dem Test wieder her
|
||||
func setupTestEnvironment(t *testing.T) {
|
||||
original := os.Getenv("ENVIRONMENT")
|
||||
os.Setenv("ENVIRONMENT", "test")
|
||||
t.Cleanup(func() {
|
||||
if original != "" {
|
||||
os.Setenv("ENVIRONMENT", original)
|
||||
} else {
|
||||
os.Unsetenv("ENVIRONMENT")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestLoadEnvFile(t *testing.T) {
|
||||
setupTestEnvironment(t)
|
||||
// Test-Datei erstellen
|
||||
envContent := `# Test .env file
|
||||
DEBUG=true
|
||||
@@ -97,6 +111,8 @@ QUOTED_VALUE='single quotes'
|
||||
}
|
||||
|
||||
func TestEnvVariablesPrecedence(t *testing.T) {
|
||||
setupTestEnvironment(t)
|
||||
|
||||
// Test, dass bereits gesetzte Umgebungsvariablen Vorrang haben
|
||||
envContent := `DEBUG=false
|
||||
LOG_LEVEL=ERROR`
|
||||
@@ -130,6 +146,8 @@ LOG_LEVEL=ERROR`
|
||||
}
|
||||
|
||||
func TestLoadConfigWithEnvFile(t *testing.T) {
|
||||
setupTestEnvironment(t)
|
||||
|
||||
// Test-Konfiguration mit .env-Datei
|
||||
envContent := `ENVIRONMENT=development
|
||||
DEBUG=true
|
||||
|
||||
+47
-10
@@ -1,6 +1,8 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"bamort/config"
|
||||
"bamort/logger"
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
@@ -10,6 +12,7 @@ import (
|
||||
"log"
|
||||
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
@@ -37,22 +40,56 @@ var (
|
||||
)
|
||||
|
||||
func ConnectDatabase() *gorm.DB {
|
||||
SetupTestDB()
|
||||
/*
|
||||
db, err := gorm.Open(sqlite.Open(PreparedTestDB), &gorm.Config{})
|
||||
if err != nil {
|
||||
log.Fatal("Failed to connect to database:", err)
|
||||
}
|
||||
DB = db
|
||||
*/
|
||||
// Konfiguration laden um zu entscheiden, welche Datenbank verwendet werden soll
|
||||
cfg := config.LoadConfig()
|
||||
|
||||
// In Test-Umgebung verwende Test-DB, sonst die konfigurierte Datenbank
|
||||
if cfg.Environment == "test" {
|
||||
logger.Debug("Test-Umgebung erkannt, verwende Test-Datenbank")
|
||||
SetupTestDB()
|
||||
} else {
|
||||
logger.Debug("Verwende konfigurierte Datenbank (%s)", cfg.DatabaseType)
|
||||
return ConnectDatabaseOrig()
|
||||
}
|
||||
|
||||
return DB
|
||||
}
|
||||
func ConnectDatabaseOrig() *gorm.DB {
|
||||
dsn := "bamort:bG4)efozrc@tcp(192.168.0.5:3306)/bamort?charset=utf8mb4&parseTime=True&loc=Local"
|
||||
database, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
||||
// Konfiguration laden
|
||||
cfg := config.LoadConfig()
|
||||
|
||||
logger.Debug("Datenbank-Konfiguration geladen: Type=%s, URL=%s", cfg.DatabaseType, cfg.DatabaseURL)
|
||||
|
||||
// Falls keine URL konfiguriert ist, verwende Standard-MySQL-Konfiguration als Fallback
|
||||
dbURL := cfg.DatabaseURL
|
||||
if dbURL == "" {
|
||||
dbURL = "bamort:bG4)efozrc@tcp(192.168.0.5:3306)/bamort?charset=utf8mb4&parseTime=True&loc=Local"
|
||||
logger.Warn("Keine DATABASE_URL konfiguriert, verwende Standard-MySQL-Konfiguration")
|
||||
cfg.DatabaseType = "mysql"
|
||||
}
|
||||
|
||||
var database *gorm.DB
|
||||
var err error
|
||||
|
||||
// Datenbanktyp-spezifische Verbindung
|
||||
switch cfg.DatabaseType {
|
||||
case "mysql":
|
||||
logger.Debug("Verbinde mit MySQL-Datenbank...")
|
||||
database, err = gorm.Open(mysql.Open(dbURL), &gorm.Config{})
|
||||
case "sqlite":
|
||||
logger.Debug("Verbinde mit SQLite-Datenbank...")
|
||||
database, err = gorm.Open(sqlite.Open(dbURL), &gorm.Config{})
|
||||
default:
|
||||
logger.Error("Nicht unterstützter Datenbanktyp: %s. Verwende MySQL als Fallback.", cfg.DatabaseType)
|
||||
database, err = gorm.Open(mysql.Open(dbURL), &gorm.Config{})
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logger.Error("Fehler beim Verbinden mit der Datenbank (%s): %s", cfg.DatabaseType, err.Error())
|
||||
log.Fatal("Failed to connect to database:", err)
|
||||
}
|
||||
|
||||
logger.Info("Erfolgreich mit %s-Datenbank verbunden", cfg.DatabaseType)
|
||||
DB = database
|
||||
return DB
|
||||
}
|
||||
|
||||
@@ -5,7 +5,21 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// setupTestEnvironment setzt ENVIRONMENT=test für Tests
|
||||
func setupTestEnvironment(t *testing.T) {
|
||||
original := os.Getenv("ENVIRONMENT")
|
||||
os.Setenv("ENVIRONMENT", "test")
|
||||
t.Cleanup(func() {
|
||||
if original != "" {
|
||||
os.Setenv("ENVIRONMENT", original)
|
||||
} else {
|
||||
os.Unsetenv("ENVIRONMENT")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestLogLevels(t *testing.T) {
|
||||
setupTestEnvironment(t)
|
||||
// Test String-Representation der Log-Levels
|
||||
tests := []struct {
|
||||
level LogLevel
|
||||
@@ -25,6 +39,8 @@ func TestLogLevels(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDebugModeFromEnv(t *testing.T) {
|
||||
setupTestEnvironment(t)
|
||||
|
||||
// Test verschiedene Umgebungsvariablen-Werte
|
||||
tests := []struct {
|
||||
envValue string
|
||||
@@ -55,6 +71,8 @@ func TestDebugModeFromEnv(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMinLogLevelFromEnv(t *testing.T) {
|
||||
setupTestEnvironment(t)
|
||||
|
||||
// Test verschiedene LOG_LEVEL Werte
|
||||
tests := []struct {
|
||||
envValue string
|
||||
@@ -97,6 +115,8 @@ func TestMinLogLevelFromEnv(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSetDebugMode(t *testing.T) {
|
||||
setupTestEnvironment(t)
|
||||
|
||||
// Test Debug-Modus aktivieren
|
||||
SetDebugMode(true)
|
||||
if !IsDebugEnabled() {
|
||||
@@ -111,6 +131,8 @@ func TestSetDebugMode(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSetMinLogLevel(t *testing.T) {
|
||||
setupTestEnvironment(t)
|
||||
|
||||
// Test verschiedene Log-Level setzen
|
||||
levels := []LogLevel{DEBUG, INFO, WARN, ERROR}
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
package testutils
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// SetupTestEnvironment konfiguriert die Umgebung für Tests
|
||||
// Diese Funktion setzt ENVIRONMENT=test und stellt sicher, dass nach dem Test
|
||||
// die ursprüngliche Umgebung wiederhergestellt wird
|
||||
func SetupTestEnvironment(t *testing.T) {
|
||||
// Sicherstellen, dass ENVIRONMENT auf "test" gesetzt ist
|
||||
originalEnv := os.Getenv("ENVIRONMENT")
|
||||
os.Setenv("ENVIRONMENT", "test")
|
||||
|
||||
// Cleanup-Funktion registrieren
|
||||
t.Cleanup(func() {
|
||||
if originalEnv != "" {
|
||||
os.Setenv("ENVIRONMENT", originalEnv)
|
||||
} else {
|
||||
os.Unsetenv("ENVIRONMENT")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// SetupTestEnvironmentWithConfig konfiguriert die Test-Umgebung mit spezifischen Werten
|
||||
func SetupTestEnvironmentWithConfig(t *testing.T, envVars map[string]string) {
|
||||
// Ursprüngliche Werte sichern
|
||||
originalVars := make(map[string]string)
|
||||
for key := range envVars {
|
||||
originalVars[key] = os.Getenv(key)
|
||||
}
|
||||
|
||||
// Sicherstellen, dass ENVIRONMENT auf "test" gesetzt ist
|
||||
envVars["ENVIRONMENT"] = "test"
|
||||
|
||||
// Test-Umgebungsvariablen setzen
|
||||
for key, value := range envVars {
|
||||
os.Setenv(key, value)
|
||||
}
|
||||
|
||||
// Cleanup-Funktion registrieren
|
||||
t.Cleanup(func() {
|
||||
for key, originalValue := range originalVars {
|
||||
if originalValue != "" {
|
||||
os.Setenv(key, originalValue)
|
||||
} else {
|
||||
os.Unsetenv(key)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// EnsureTestEnvironment ist eine einfache Prüfung, ob die Test-Umgebung korrekt ist
|
||||
// Kann in Tests verwendet werden um sicherzustellen, dass ENVIRONMENT=test gesetzt ist
|
||||
func EnsureTestEnvironment(t *testing.T) {
|
||||
if os.Getenv("ENVIRONMENT") != "test" {
|
||||
t.Errorf("ENVIRONMENT sollte 'test' sein, ist aber '%s'. Vergessen Sie SetupTestEnvironment() aufzurufen?",
|
||||
os.Getenv("ENVIRONMENT"))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user