web-dev-qa-db-fra.com

Quel est le but de la méthode setUp de XCTestCase?

Par le commentaire dans le modèle par défaut pour XCTestCase concernant setUp:

Put setup code here; it will be run once, before the first test case.

Cependant, dans XCTestCase.h, le commentaire ci-dessus setUp indique différemment:

Setup method called before the invocation of each test method in the class.

Pour confirmer le comportement réel, j'ai mis un NSLog dans setUp pour compter combien de fois il a été appelé:

static int count = 0;

- (void)setUp
{
    [super setUp];
    count++;

    NSLog(@"Call Count = %d", count);
}

Cela a entraîné l'appel de la méthode setUp avant chaque méthode de test (confirmant le commentaire sur XCTestCase.h).

Je voulais utiliser la méthode setUp pour créer des objets test/maquette ne fois (par exemple pour configurer une pile de test Core Data). Les créer plusieurs fois serait un processeur intensif et potentiellement très lent.

Alors,

1) À quoi est destiné setUp? Les développeurs n'y créent-ils pas encore et encore des objets?

2) Comment puis-je créer ces objets uniquement ne fois dans un XCTestCase?

38
JRG-Developer

Il y a quelques points à discuter ici: le comportement des méthodes setUp et les meilleures pratiques générales de test.

Il existe en fait deux setUp méthodes:

+ (void)setUp;
- (void)setUp;

La méthode de classe (+ (void)setUp) n'est exécutée qu'une seule fois pendant toute la durée du test.

La méthode d'instance (- (void)setUp) est celle du modèle par défaut; il est exécuté avant chaque test. Avec un peu de chance, dans une future version hypothétique de Xcode, ce commentaire aura été changé en // Put setup code here. This method is called before the invocation of each test method in the class. WINK WINK

Donc, grâce à ces deux méthodes, les deux comportements que vous avez décrits sont possibles.

Concernant votre commentaire:

"Les développeurs ne créent sûrement pas des objets dedans encore et encore?"

Ma réponse serait "Oui, ils le sont habituellement". Un acronyme populaire pour les "bons" tests unitaires est PREMIER:

  • Vite
  • Isolé
  • Répétable
  • Auto-vérification
  • Opportun

Isolée est la clé de cette discussion: vos tests ne doivent pas s'appuyer sur un état précédent laissé par d'autres tests. Idéalement, vous devez démonter et recréer votre pile de données de base en mémoire pour chaque test, afin que vous sachiez que vous partez d'une table rase. Un bon exemple est dans cet article de Graham Lee . Vous voulez utiliser une pile en mémoire car a) vous pouvez facilement la jeter, et b) elle devrait être très rapide car elle est juste en mémoire et ne frappe pas votre disque.

Si vous constatez que vos tests s'exécutent lentement à la suite de cela (n'optimisez pas prématurément), alors je pense qu'une prochaine étape raisonnable serait de créer la pile dans votre fonction + (void)setUp, mais créez à chaque fois un nouveau contexte dans votre méthode - (void)setUp.

87
James Frost

Je suis venu ici avec presque le même problème: comment effectuer le setUpne seule fois et dans Swift. Voici la solution:

override class func setUp() {
    super.setUp()    
    // ...
}

override class func tearDown() {    
    // ...
    super.tearDown()
}

En ce moment je cherche toujours une solution pour un asynchronesetUp!

4
Zeb