J'ai également eu pas mal de problèmes avec les tests de Xcode 5. Il semble encore assez bogué avec certains comportements étranges - cependant, j'ai trouvé la raison définitive pour laquelle votre problème particulier a été résolu. XCTAssertEqual
ne fonctionne pas.
Si nous jetons un coup d'œil au code de test, nous constatons qu'il fait en fait ce qui suit (tiré directement de XCTestsAssertionsImpl.h
- il est peut-être plus facile de l'afficher à cet endroit) :
#define _XCTPrimitiveAssertEqual(a1, a2, format...) \
({ \
@try { \
__typeof__(a1) a1value = (a1); \
__typeof__(a2) a2value = (a2); \
NSValue *a1encoded = [NSValue value:&a1value withObjCType:@encode(__typeof__(a1))]; \
NSValue *a2encoded = [NSValue value:&a2value withObjCType:@encode(__typeof__(a2))]; \
float aNaN = NAN; \
NSValue *aNaNencoded = [NSValue value:&aNaN withObjCType:@encode(__typeof__(aNaN))]; \
if ([a1encoded isEqualToValue:aNaNencoded] || [a2encoded isEqualToValue:aNaNencoded] || ![a1encoded isEqualToValue:a2encoded]) { \
_XCTRegisterFailure(_XCTFailureDescription(_XCTAssertion_Equal, 0, @#a1, @#a2, _XCTDescriptionForValue(a1encoded), _XCTDescriptionForValue(a2encoded)),format); \
} \
} \
@catch (id exception) { \
_XCTRegisterFailure(_XCTFailureDescription(_XCTAssertion_Equal, 1, @#a1, @#a2, [exception reason]),format); \
}\
})
Voilà le problème :
Ce que le test fait en réalité, c'est coder les valeurs dans un fichier de type NSValue
et ensuite les comparer. "D'accord," dites-vous, "mais quel est le problème avec ça ?" Je ne pensais pas non plus qu'il y en avait un jusqu'à ce que je fasse mon propre cas de test pour cela. Le problème est que la méthode NSValue -isEqualToValue
doit également comparer la valeur de la NSValue type de codage ainsi que sa valeur réelle. Les deux sites doivent être égales pour que la méthode renvoie YES
.
Dans votre cas, arr.count
est un NSUInteger
qui est un typedef de unsigned int
. La constante de temps de compilation 3
dégénère vraisemblablement en un signed int
au moment de l'exécution. Ainsi, lorsque les deux sont placés dans un NSValue
leurs types d'encodage ne sont pas égaux et, par conséquent, les deux ne peuvent pas être égaux selon la règle de l'égalité des chances. -[NSValue isEqualToValue]
.
Vous pouvez le prouver avec un exemple personnalisé. Le code suivant fait explicitement exactement ce que XCTAssertEqual
lo hace:
// Note explicit types
unsigned int a1 = 3;
signed int a2 = 3;
__typeof__(a1) a1value = (a1);
__typeof__(a2) a2value = (a2);
NSValue *a1encoded = [NSValue value:&a1value withObjCType:@encode(__typeof__(a1))];
NSValue *a2encoded = [NSValue value:&a2value withObjCType:@encode(__typeof__(a2))];
if (![a1encoded isEqualToValue:a2encoded]) {
NSLog(@"3 != 3 :(");
}
"3 != 3 :("
apparaîtra dans le journal à chaque fois.
Je m'empresse d'ajouter ici que c'est, en fait, un comportement attendu. NSValue
es supposée pour vérifier son encodage de type lors des comparaisons. Malheureusement, ce n'est pas ce que nous attendions en testant deux entiers ('égaux').
XCTAssertTrue
a une logique beaucoup plus simple, et se comporte généralement comme prévu (encore une fois, voir la source réelle pour savoir comment elle détermine si l'assertion échoue).