Je souhaite que mon application exécute un code spécial (par exemple, la réinitialisation de son état) lors de l'exécution en mode de test d'interface utilisateur. J'ai examiné les variables d'environnement définies lorsque l'application est exécutée à partir du test d'interface utilisateur et il n'y a pas de paramètres évidents permettant de différencier l'application fonctionnant normalement par rapport au test d'interface utilisateur. Y a-t-il un moyen de le savoir?
Deux solutions de contournement dont je ne suis pas satisfait sont les suivantes:
XCUIApplication.launchEnvironment
avec une variable que je vérifie plus tard dans l'application. Ce n'est pas bon car vous devez le définir dans la méthode setUp
de chaque fichier de test. J'ai essayé de définir la variable d'environnement à partir des paramètres du schéma, mais cela ne se propage pas à l'application elle-même lors de l'exécution des tests de test de l'interface utilisateur.__XPC_DYLD_LIBRARY_PATH
. Cela semble très compliqué et pourrait ne fonctionner que maintenant à cause d'une coïncidence dans la configuration de nos paramètres de construction cibles.J'ai moi-même étudié cette question et suis tombé sur cette question. J'ai fini par aller avec la première solution de contournement de @ LironYahdav:
Dans votre test d'interface utilisateur:
- (void)setUp
{
[super setUp];
XCUIApplication *app = [[XCUIApplication alloc] init];
app.launchEnvironment = @{@"isUITest": @YES};
[app launch];
}
Dans votre application:
NSDictionary *environment = [[NSProcessInfo processInfo] environment];
if (environment[@"isUITest"]) {
// Running in a UI test
}
Les solutions de @ JoeMasilotti sont utiles pour unit tests, car elles partagent le même temps d'exécution que l'application à tester, mais ne sont pas pertinentes pour les tests d'interface utilisateur.
Je n'ai pas réussi à définir un environnement de lancement, mais je l'ai obtenu avec des arguments de lancement.
Dans vos tests, la fonction setUp () ajoute:
let app = XCUIApplication()
app.launchArguments = ["testMode"]
app.launch()
Dans votre code de production, ajoutez un chèque tel que:
let testMode = NSProcessInfo.processInfo().arguments.contains("testMode")
if testMode {
// Do stuff
}
Vérifié à l'aide de XCode 7.1.1.
Vous pouvez utiliser Preprocessor Macros pour cela. J'ai trouvé que vous avez plusieurs choix:
Faites une copie de la cible de l'application et utilisez-la comme cible à tester. Toute macro de préprocesseur dans cette copie cible est accessible en code.
Un inconvénient est que vous devrez également ajouter de nouvelles classes/ressources à la cible de copie et parfois, il sera très facile de les oublier.
Faites une copie de la configuration de construction Debug, définissez n'importe quelle macro de préprocesseur sur cette configuration et utilisez-la pour votre test (voir les captures d'écran ci-dessous).
Une erreur mineure: chaque fois que vous voulez enregistrer une session de test d'interface utilisateur, vous devez modifier le Exécuter pour utiliser la nouvelle configuration de test.
Ajouter une configuration en double:
Utilisez-le pour votre Test:
Je viens d'ajouter cette extension
@available(iOS 9, *)
extension XCUIApplication {
func test(){
launchEnvironment = ["TEST":"true"]
launch()
}
}
Je peux donc simplement utiliser test () au lieu de launch ()
Swift 3 basé sur les réponses précédentes.
class YourApplicationUITests: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
// In UI tests it is usually best to stop immediately when a failure occurs.
continueAfterFailure = false
// UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
let app = XCUIApplication()
app.launchArguments = ["testMode"]
app.launch()
// In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testExample() {
// Use recording to get started writing UI tests.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
}
extension UIApplication {
public static var isRunningTest: Bool {
return ProcessInfo().arguments.contains("testMode")
}
}
Ensuite, appelez simplement UIApplication.isRunningTest dans votre code.
Dans Swift 3, vous pouvez rechercher la clé XCInjectBundleInto
ou quelque chose commençant par XC
.
let isInTestMode = ProcessInfo.processInfo.environment["XCInjectBundleInto"] != nil
Cela fonctionne aussi sous OS X.