toBe (vrai) vs toBeTruthy () vs toBeTrue()

Quelle est la différence entre expect(something).toBe(true), expect(something).toBeTruthy() et expect(something).toBeTrue()?

Remarque que toBeTrue() est un correspondance personnalisée introduit dans jasmine-matchers entre autres utile et pratique de rapprochement comme toHaveMethod() ou toBeArrayOfStrings().


La question est censée être générique, mais, à titre d'exemple réel, je teste qu'un élément est affiché dans protractor. Quel matcher dois-je utiliser dans ce cas?

expect(elm.isDisplayed()).toBe(true);
expect(elm.isDisplayed()).toBeTruthy();
expect(elm.isDisplayed()).toBeTrue();
87
demandé sur alecxe 2015-09-16 21:10:01

4 réponses

Ce que je fais quand je me demande quelque chose comme la question posée ici est d'aller à la source.

ToBe ()

expect().toBe() est défini comme suit:

function toBe() {
  return {
    compare: function(actual, expected) {
      return {
        pass: actual === expected
      };
    }
  };
}

, Il effectue son test avec === ce qui signifie que lorsqu'il est utilisé comme expect(foo).toBe(true), il va passer seulement si foo a réellement de la valeur true. Les valeurs véridiques ne feront pas passer le test.

Tobetruth ()

expect().toBeTruthy() est défini comme suit:

function toBeTruthy() {
  return {
    compare: function(actual) {
      return {
        pass: !!actual
      };
    }
  };
}

Type coercition

Une valeur est véridique si la coercition de cette valeur à un booléen donne la valeur true. L'opération !! teste la véracité en forçant la valeur passée à expect à un booléen. Notez que contrairement à ce que la réponse actuellement acceptée implique, == true est pas un test correct pour la véracité. Vous obtiendrez des choses drôles comme

> "hello" == true
false
> "" == true
false
> [] == true
false
> [1, 2, 3] == true
false

Alors que l'utilisation de !! donne:

> !!"hello"
true
> !!""
false
> !![1, 2, 3]
true
> !![] 
true

(oui, vide ou non, un tableau est véridique.)

ToBeTrue ()

expect().toBeTrue() fait partie de Jasmin-les allumettes (qui est enregistré sur npm comme jasmine-expect après un projet plus tard, enregistré jasmine-matchers premier).

expect().toBeTrue() est défini comme suit:

function toBeTrue(actual) {
  return actual === true ||
    is(actual, 'Boolean') &&
    actual.valueOf();
}

La différence avec expect().toBeTrue() et expect().toBe(true) que expect().toBeTrue() teste si elle fait affaire avec un Boolean objet. expect(new Boolean(true)).toBe(true) échouerait alors que expect(new Boolean(true)).toBeTrue() passerait. C'est à cause de cette drôle de chose:

> new Boolean(true) === true
false
> new Boolean(true) === false
false

Au moins c'est vrai:

> !!new Boolean(true)
true

Quel est le mieux adapté pour une utilisation avec elem.isDisplayed()?

En fin de Compte Le Rapporteur remet cette requête au sélénium. Le documentation, la valeur produite par .isDisplayed() est une promesse qui se résout boolean. Je le prendrais à la valeur nominale et l'utilisation .toBeTrue() ou .toBe(true). Si j'ai trouvé un cas où l'implémentation renvoie des valeurs vraies/fausses, Je déposerais un rapport de bogue.

110
répondu Louis 2017-05-23 11:55:07

En javascript, il y a trues et truthys. Quand quelque chose est vrai, il est évidemment vrai ou faux. Quand quelque chose est vrai, il peut ou non être un booléen, mais la valeur "cast" de est un booléen.

Exemples.

true == true; // (true) true
1 == true; // (true) truthy
"hello" == true;  // (true) truthy
[1, 2, 3] == true; // (true) truthy
[] == false; // (true) truthy
false == false; // (true) true
0 == false; // (true) truthy
"" == false; // (true) truthy
undefined == false; // (true) truthy
null == false; // (true) truthy

Cela peut rendre les choses plus simples si vous voulez vérifier si une chaîne est définie ou si un tableau a des valeurs.

var users = [];

if(users) {
  // this array is populated. do something with the array
}

var name = "";

if(!name) {
  // you forgot to enter your name!
}

Et comme indiqué. expect(something).toBe(true) et expect(something).toBeTrue() est le même. Mais expect(something).toBeTruthy() n'est pas le même que l'un de ces.

15
répondu micah 2015-09-16 18:23:32

Disclamer : Ceci est juste une supposition sauvage

Je sais que tout le monde aime une liste facile à lire:

  • toBe(<value>) - la valeur renvoyée est la même que <value>
  • toBeTrue() - vérifie si la valeur renvoyée est true
  • toBeTruthy() - Vérifiez si la valeur, lorsqu'elle est convertie en booléen, sera une valeur véridique

    Truthy valeurs sont toutes les valeurs qui ne sont pas 0, '' (chaîne vide), false, null, NaN, undefined ou [] (vide tableau)*.

    * Notez que lorsque vous exécutez !![], il retourne true, mais lorsque vous exécutez [] == false, il renvoie également true. Cela dépend de la façon dont il est mis en œuvre. En d'autres termes: (!![]) === ([] == false)


Sur votre exemple, toBe(true) et toBeTrue() donneront les mêmes résultats.

8
répondu Ismael Miguel 2015-09-16 18:38:15

, Il ya beaucoup, beaucoup de bonnes réponses, je voulais juste ajouter un scénario où l'utilisation de ces attentes pourraient être utiles. En utilisant element.all(xxx), si j'ai besoin de vérifier si tous les éléments sont affichés en une seule exécution, je peux effectuer -

expect(element.all(xxx).isDisplayed()).toBeTruthy(); //Expectation passes
expect(element.all(xxx).isDisplayed()).toBe(true); //Expectation fails
expect(element.all(xxx).isDisplayed()).toBeTrue(); //Expectation fails

Raison d'être .all() renvoie un tableau de valeurs et donc toutes sortes d'attentes(getText, isPresent, etc...) peut être effectuée avec toBeTruthy() lorsque .all() entre en image. Espérons que cette aide.

1
répondu Girish Sortur 2016-01-06 12:01:47