web-dev-qa-db-fra.com

Le test rapide donne l'erreur "Symboles non définis pour l'architecture x86_64"

J'exécute Swift test à partir de la ligne de commande pour exécuter les cas de test. C'est le cas de test:

import XCTest
@testable import vnk_Swift

class KeyMappingTests: XCTestCase {
    static var allTests : [(String, (KeyMappingTests) -> () throws -> Void)] {
        return [
            // ("testExample", testExample),
        ]
    }

    func testExample() {
        let keyMapping = KeyMapping()
        XCTAssertNotNil(keyMapping , "PASS")
    }
}

Et voici le message de sortie.

image

Si je supprime l'utilisation de KeyMapping, tout fonctionne correctement:

    func testExample() {
        // let keyMapping = KeyMapping()
        XCTAssertNotNil(true , "PASS")
    }

image

On dirait qu'il y a un problème lorsque j'essaie d'utiliser une classe. Comment puis-je réparer ça?

(Je n'ai pas utilisé XCode pour ce projet car j'ai commencé avec Swift package init, le code source de ce projet est ici: https://github.com/trungdq88/vnk-Swift )}

24
TrungDQ

J'ai réussi à construire et à tester votre paquet en faisant les modifications suivantes:

  • renommé le nom du package en VnkSwift, pour certaines raisons, l'outil de compilation n'aime pas les tirets dans le nom du package, ni ne fonctionne lorsque le nom du package généré est souligné (renommez donc le package en vnk_Swift correspondance de nom n'a pas fonctionné)
  • a renommé le dossier de test en VnkSwiftTests afin que l'éditeur de liens sache avec quoi faire le lien; semble que c’est une condition préalable pour que l’éditeur de liens sache faire le lien avec le paquet
  • enfin, renommé main.Swift en quelque chose d’autre (j’ai utilisé utils.Swift). Le fait est que la présence de main.Swift indique à l’outil de construction de générer un fichier exécutable, et que la liaison avec un fichier exécutable ne fonctionne pas très bien. Après le changement de nom, il a fallu commenter le code if, car le code global en cours ne peut appartenir qu'à main.Swift.

De conclure:

  • Évitez les noms de package non alphanumériques
  • Le nom du package et le nom du répertoire de test doivent être synchronisés
  • Assurez-vous de ne pas avoir de fichier main.Swift pour vous assurer que le paquet peut être lié

Pourquoi une unité ne peut-elle pas tester le lien cible avec des exécutables?

C'est parce que l'ensemble de tests et l'exécutable ont tous deux un code d'exécution global (c'est-à-dire la fonction principale), de sorte que l'éditeur de liens ne sait pas lequel choisir. Lors des tests à partir de Xcode, l'ensemble de tests est exécuté dans le contexte de l'application - il n'est pas lié à cela, comme dans la situation actuelle. 

Xcode rencontre également ce problème lors de la création d’un outil de ligne de commande. Vous ne pouvez pas tester d’unité cette cible. Si vous souhaitez tester le code, vous devez créer une bibliothèque qui sera liée à la fois à l’outil et à la cible de test ( ou inclure les fichiers dans les deux cibles)

28
Cristik

Cela semble être dû au fait que j'ai un main.Swift dans votre répertoire de modules. Cela se traduit par la création d'un exécutable, au lieu d'une bibliothèque à laquelle vos scénarios de test peuvent être liés.

J'ai résolu ce problème en scindant mon code en deux modules. Une bibliothèque pour laquelle j'ai des cas de test et l'application qui contient uniquement main.Swift:

Package.Swift
Sources\FooBarLib\
Sources\FooBarLib\Something.Swift
Sources\FooBarLib\MoreStuff.Swift
Sources\FooBarApp\main.Swift
Tests\FooBarLibTests\TestSomething.Swift

Ensuite, dans mon Package.Swift, assurez-vous que FooBarApp dépend de FooBarLib

import PackageDescription

let package = Package(
    name: "FooBar",
    targets: [
        Target(name: "FooBarLib"),
        Target(name: "FooBarApp", dependencies: ["FooBarLib"])
    ],
)

Ensuite, dans TestSomething. Swift vous importez le module FooBarLib

@testable import FooBarLib
import XCTest

class TestSomething: XCTestCase {
    func testFunc() {
    }
}
14
Frank

Ajoutez à la réponse de @ Frank.

Dans Swift 4, vérifiez si votre .testTarget dépend de FooBarLib

    .testTarget(
        name: "FooBarLibTests",
        dependencies: ["FooBarLib"]),
1
Jianing

Dans mon cas, j'active le test en sélectionnant Navigateur test en xcode, en cliquant avec le bouton droit de la souris et en activant le test. Et ça a fonctionné.

0
Cao Văn An

En se basant sur la réponse de @ Cristik, il s’agit vraiment de ce qui se trouve dans votre dossier Sources. Pour moi, j'avais un dossier dans Sources qui devait être exactement identique à ce qui était dans Tests sauf que ce qui est dans Tests devait être suffixé de Tests. Donc, si vous avez Sources -> Foo-Bar, vous devez avoir Tests -> Foo-BarTests. AUCUNE EXCEPTION

Autre remarque: tous les tirets seront convertis en traits de soulignement. Vous devrez donc ajouter @testable import Foo_Bar en haut de vos fichiers de test. 

0
SushiGrass Jacob

Je vois que dans les répertoires vous avez vnk-Swift, mais dans les instructions d'importation et dans le nom mutilé, vous avez vnk_Swift. Peut-être qu’il s’agit d’un bogue Xcode/compiler avec le traitement des tirets. Essayez de reproduire sur un répertoire et un projet sans trait d'union, juste vnkswift par exemple.

J'espère que ça aide

0
Alistra