Maison >développement back-end >Golang >Comment puis-je obtenir une couverture de test précise pour le code Go à l'aide de « os.Exit() » ?

Comment puis-je obtenir une couverture de test précise pour le code Go à l'aide de « os.Exit() » ?

DDD
DDDoriginal
2024-12-23 14:39:22306parcourir

How Can I Achieve Accurate Test Coverage for Go Code Using `os.Exit()`?

Test des scénarios os.Exit dans Go avec informations de couverture (coveralls.io/Goveralls)

Cette question concerne les scénarios de test impliquant OS. Exit() dans Go, en particulier comment capturer les informations de couverture pour ces scénarios. L'exemple de code fourni démontre une méthode de réexécution, mais elle souffre de limitations en termes d'outils de couverture et de fragilité.

Défis de couverture

Une difficulté est que les cadres de couverture tels que coveralls.io peut ne pas enregistrer la couverture des tests qui évoquent os.Exit(). En effet, l'instrumentation de couverture n'est pas appliquée lorsque le binaire de test est réexécuté.

Méthode de réexécution modifiée

Pour résoudre ce problème, une ré-exécution modifiée La méthode exec peut être utilisée. Le code original est refactorisé pour extraire os.Exit en tant que variable nommée osExit. Le code de test remplace ensuite osExit par une fonction fictive qui enregistre le code de sortie. Cela permet de capturer les informations de couverture pour les appels osExit.

Couverture des appels externes

La même technique peut être appliquée pour couvrir les appels à des fonctions telles que log.Fatalf() , qui invoque indirectement os.Exit. La fonction logFatalf est remplacée par une fonction fictive qui enregistre le format du message et les arguments qui lui sont transmis. Cela garantit la couverture des scénarios dans lesquels os.Exit est appelé à partir de fonctions externes.

Exemple

Le code et le test modifiés sont les suivants :

// bar.go
package foo

import (
    "fmt"
    "os"
)

var osExit = os.Exit

func Crasher() {
    fmt.Println("Going down in flames!")
    osExit(1)
}
// bar_test.go
package foo

import (
    "reflect"
    "testing"
)

var logFatalf = log.Fatalf

func TestCrasher(t *testing.T) {
    // Save original functions and restore at the end
    oldOsExit := osExit
    oldLogFatalf := logFatalf
    defer func() {
        osExit = oldOsExit
        logFatalf = oldLogFatalf
    }()

    // Mock osExit
    var got int
    myExit := func(code int) {
        got = code
    }
    osExit = myExit

    // Mock logFatalf
    var gotFormat string
    var gotV []interface{}
    myFatalf := func(format string, v ...interface{}) {
        gotFormat, gotV = format, v
    }
    logFatalf = myFatalf

    // Run test
    Crasher()

    // Check results
    exp := 1
    if got != exp {
        t.Errorf("Expected exit code: %d, got: %d", exp, got)
    }

    expFormat, expV := "Exiting with code: %d", []interface{}{1}
    if gotFormat != expFormat || !reflect.DeepEqual(gotV, expV) {
        t.Error("Something went wrong")
    }
}

En isolant les fonctionnalités liées à la sortie et en utilisant des fonctions fictives, les appels os.Exit et les fonctions externes qui déclenchent os.Exit peuvent être couverts dans Go essais. Cette approche garantit des rapports de couverture précis pour les scénarios impliquant l'arrêt du processus.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn