Qu'est-ce que «affirmer» en JavaScript?

263

Que assertsignifie en JavaScript?

J'ai vu quelque chose comme:

assert(function1() && function2() && function3(), "some text");

Et je voudrais savoir ce que fait la méthode assert().

frrlod
la source

Réponses:

367

Il n'y asserten a pas en JavaScript (pour l'instant, il est question d'en ajouter un , mais c'est à un stade précoce). Vous utilisez peut-être une bibliothèque qui en fournit une. La signification habituelle est de renvoyer une erreur si l'expression passée dans la fonction est fausse; cela fait partie du concept général de vérification des assertions . Habituellement, les assertions (comme on les appelle) ne sont utilisées que dans les versions de «test» ou de «débogage» et supprimées du code de production.

Supposons que vous disposiez d'une fonction qui devait toujours accepter une chaîne. Vous voudriez savoir si quelqu'un a appelé cette fonction avec quelque chose qui n'était pas une chaîne. Vous pourriez donc faire:

assert(typeof argumentName === "string");

... où assertjetterait une erreur si la condition était fausse.

Une version très simple ressemblerait à ceci:

function assert(condition, message) {
    if (!condition) {
        throw message || "Assertion failed";
    }
}

Mieux encore, utilisez l' Errorobjet si le moteur JavaScript le prend en charge (les très anciens peuvent ne pas l'être), ce qui a l'avantage de collecter une trace de pile et autres:

function assert(condition, message) {
    if (!condition) {
        message = message || "Assertion failed";
        if (typeof Error !== "undefined") {
            throw new Error(message);
        }
        throw message; // Fallback
    }
}

Même IE8 a Error(bien qu'il n'ait pas la stackpropriété, mais les moteurs modernes [y compris IE moderne] en ont).

TJ Crowder
la source
6
... se familiariser avec les types dans JS? Je dirais que c'est l'une des pires raisons assert.
cHao
137
@cHao: Il existe des cas d'utilisation valides. Ce n'était que le premier exemple qui m'est venu à l'esprit. L'exemple n'est pas le point. Le concept des assertions est le point.
TJ Crowder
4
quelque chose que j'ai ajouté à mon code dans l' if(!condition)est de réglage var throwError=true;puis debugger;ensuite envelopper la section lancer dans un if(throwError). De cette façon, si j'ai le débogueur ouvert, il se cassera, et si je le souhaite, je peux définir la valeur throwErrorfalse, puis examiner toutes les étendues tout en sortant.
Rick
8
@Rick si vous utilisez Chrome DevTools, vous pouvez simplement activer "Pause sur les exceptions non détectées" dans l'onglet Sources et il s'arrêtera automatiquement à throw. De cette façon, vous n'avez pas besoin de la debugger;déclaration. Voir developer.chrome.com/devtools/docs/… pour en savoir plus.
Vicky Chijwani
1
@machineghost: Je ne vois pas comment c'est "plus simple", vous venez d'échanger ifpour un opérateur conditionnel. De toute façon, dans le monde d'aujourd'hui, je ne prendrais pas la peine de supporter des moteurs qui n'en ont pas Error.
TJ Crowder du
157

Si vous utilisez un navigateur moderne ou nodejs, vous pouvez utiliser console.assert(expression, object).

Pour plus d'informations:

joaoprib
la source
46
Pour info, cela ressemble plus console.errorau fait que le code continue de s'exécuter.
Daniel Sokolowski
10
@DanielSokolowski, exactement. console.assertn'est pas si bon sauf s'il a le même comportement que throw.
Pacerier
23
La raison pour laquelle l'exécution se poursuit après console.assertest parce que les assertions ne sont pas des fonctions de gestion des erreurs. Ils sont conçus pour la vérification de l'exactitude du code pendant le développement uniquement. Traditionnellement, ils sont complètement désactivés dans les environnements de production pour éviter la fin des systèmes en direct à cause de quelque chose de trivial. Le navigateur est considéré comme un environnement de production, il console.assertne met donc pas fin à son exécution. Si vous comptez sur des assertions pour arrêter l'exécution, vous devez plutôt utiliser une gestion des erreurs appropriée, car ce n'est pas à cela que servent les assertions.
Malvineous
8
@RonBurk: les concepteurs de langage ont décidé "à quoi servent les assertions". En C ++ [une assertion] est conçue pour capturer les erreurs de programmation, pas les erreurs utilisateur ou d'exécution, car elle est généralement désactivée après qu'un programme quitte sa phase de débogage. PHP dit En règle générale, votre code devrait toujours pouvoir fonctionner correctement si la vérification des assertions n'est pas activée. La voix passive n'était pas destinée à donner autorité à une préférence personnelle, mais plutôt à rapporter ce qui est une pratique générale largement acceptée.
Malvineous
4
@Don: Point pris mais je citais juste des pages liées. Je crois que les assertions doivent être traitées comme si elles pouvaient être désactivées, ne serait-ce que parce que votre code pourrait un jour être utilisé par quelqu'un qui pense qu'il est sûr de le faire. Si les assertions sont essentielles à votre code, je pense qu'elles devraient vraiment être mises à niveau pour vérifier correctement les erreurs plutôt que de s'appuyer sur une méthode de débogage qui n'est pas toujours garantie de terminer l'exécution. Sans oublier que la mort répétée de votre code dans un environnement de production alors qu'il pourrait simplement renvoyer une erreur et continuer pourrait causer plus de stress qu'il n'en vaut la peine!
Malvineous
29

Les autres réponses sont bonnes: il n'y a pas de fonction d'assertion intégrée dans ECMAScript5 (par exemple JavaScript qui fonctionne essentiellement partout) mais certains navigateurs vous la fournissent ou ont des modules complémentaires qui fournissent cette fonctionnalité. Bien qu'il soit probablement préférable d'utiliser une bibliothèque bien établie / populaire / maintenue à cet effet, à des fins académiques, une fonction «affirmation du pauvre» pourrait ressembler à ceci:

const assert = function(condition, message) {
    if (!condition)
        throw Error('Assert failed: ' + (message || ''));
};

assert(1 === 1); // Executes without problem
assert(false, 'Expected true');
// Yields 'Error: Assert failed: Expected true' in console
iX3
la source
BTW, on pourrait facilement modifier cela afin qu'il ne génère qu'une erreur dans les environnements de développement (par exemple en en encapsulant un autre si / en ajoutant un autre conditionnel) et sinon ne fait rien ou affiche uniquement un avertissement. Personnellement, je pense que les assertions ne devraient être que dans le code de test (par exemple, vérifier si les résultats attendus et réels correspondent); dans le code de production , elles doivent soit être superflu (garantie correcte par la conception) et donc retiré ou seulement pour garder l' utilisateur / entrée externe auquel cas ils peuvent être remplacés par désinfectante logique et norme de gestion des exceptions (par exemple try, catch, throw)
IX3
8

assert()n'est pas une fonction javascript native. Il s'agit d'une fonction personnalisée créée par quelqu'un. Vous devrez le rechercher sur votre page ou dans vos fichiers et l'afficher pour que quiconque puisse déterminer ce qu'il fait.

Crayon Violent
la source
5

vérifiez ceci: http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-quick-and-easy-javascript-testing-with-assert/

c'est pour tester JavaScript. Étonnamment, avec à peine cinq ou six lignes, ce code offre un niveau élevé de puissance et de contrôle sur votre code lors des tests.

La fonction assert accepte deux paramètres:

résultat: un booléen, qui indique si votre test a réussi ou échoué

description: Une brève description de votre test.

La fonction assert crée ensuite simplement un élément de liste, applique une classe de «réussite» ou «échec», selon que votre test a renvoyé vrai ou faux, puis ajoute la description à l'élément de liste. Enfin, ce bloc de code est ajouté à la page. C'est fou simple, mais fonctionne parfaitement.

Amrendra
la source
4

Voici une implémentation vraiment simple d'une fonction d'assertion. Cela prend une valeur et une description de ce que vous testez.

 function assert(value, description) {
        var result = value ? "pass" : "fail";
        console.log(result + ' - ' +  description); 
    };

Si la valeur est vraie, elle passe.

assert (1===1, 'testing if 1=1');  

S'il renvoie faux, il échoue.

assert (1===2, 'testing if 1=1');
joshpierro
la source
1
Le but d'une assertion n'est pas de se connecter à stdout au niveau info, mais d'arrêter l'exécution du programme (généralement en levant une exception) et de se connecter à stderr si l'assertion est évaluée à false.
Nuno André
4

Si l'assertion est fausse, le message s'affiche. Plus précisément, si le premier argument est faux, le deuxième argument (le message de chaîne) sera enregistré dans la console des outils de développement. Si le premier argument est vrai, il ne se passe pratiquement rien. Un exemple simple - j'utilise Google Developer Tools:

var isTrue = true;
var isFalse = false;
console.assert(isTrue, 'Equals true so will NOT log to the console.');
console.assert(isFalse, 'Equals false so WILL log to the console.');
Chat fou
la source
3

Il est probablement venu avec une bibliothèque de tests qu'une partie de votre code utilise. En voici un exemple (il est probable que ce n'est pas la même bibliothèque que votre code utilise, mais cela montre l'idée générale):

http://chaijs.com/guide/styles/#assert

Matt Browne
la source
2

Le mot ou la fonction "assert" est principalement utilisé pour tester des parties de l'application.

Les fonctions d'assertion sont un moyen rapide de demander au programme de vérifier la condition (également appelée "assertion") et si la condition n'est pas vraie, elle générera une erreur.

Voyons donc à quoi cela ressemblerait dans le "code normal"

if (typeof "string" === "array") { throw Error('Error: "string" !== "array"'); }

Avec assertvous pouvez simplement écrire:

assert(typeof "string" === "array")

En Javascript, il n'y a pas de assertfonction native , vous devez donc en utiliser une à partir d'une bibliothèque.

Pour une introduction simple, vous pouvez consulter cet article:

http://fredkschott.com/post/2014/05/nodejs-testing-essentials/

J'espère que ça aide.

Pavel
la source
2

L'assertion renvoie un message d'erreur si le premier attribut est faux et le deuxième attribut est le message à lancer.

console.assert(condition,message);

Il y a beaucoup de commentaires disant que l'assertion n'existe pas en JavaScript mais console.assert()est la fonction assert en JavaScript L'idée de l'assertion est de trouver pourquoi / où le bogue se produit.

console.assert(document.getElementById("title"), "You have no element with ID 'title'");
console.assert(document.getElementById("image"), "You have no element with ID 'image'");

Ici, en fonction du message, vous pouvez trouver ce qu'est le bogue. Ces messages d'erreur seront affichés sur la console en couleur rouge comme si nous appelions console.error();
Pour voir plus de fonctions dans la console exécuterconsole.log(console);

Rahul
la source
1

Les réponses précédentes peuvent être améliorées en termes de performances et de compatibilité.

Vérifier une fois si l' Errorobjet existe, sinon le déclarer:

if (typeof Error === "undefined") {
    Error = function(message) {
        this.message = message;
    };
    Error.prototype.message = "";
}

Ensuite, chaque assertion vérifie la condition et lance toujours un Errorobjet

function assert(condition, message) {
    if (!condition) throw new Error(message || "Assertion failed");
}

Gardez à l'esprit que la console n'affichera pas le vrai numéro de ligne d'erreur, mais la ligne de la assertfonction, ce qui n'est pas utile pour le débogage.

Karl.S
la source
1

Si vous utilisez webpack, vous pouvez simplement utiliser la bibliothèque d'assertion Node.js . Bien qu'ils prétendent que ce n'est "pas destiné à être une bibliothèque d'assertions à usage général", cela semble être plus que correct pour les assertions ad hoc, et il semble qu'aucun concurrent n'existe de toute façon dans l'espace Node (Chai est conçu pour les tests unitaires).

const assert = require('assert');
...
assert(jqXHR.status == 201, "create response should be 201");

Vous devez utiliser webpack ou browserify pour pouvoir l'utiliser, donc évidemment cela n'est utile que si ceux-ci sont déjà dans votre flux de travail.

amoe
la source
1

En plus d'autres options telles que console.assert ou rouler la vôtre , vous pouvez utiliser l' invariant . Il a quelques fonctionnalités uniques:

  • Il prend en charge les messages d'erreur formatés (à l'aide d'un %sspécificateur).
  • Dans les environnements de production (comme déterminé par l'environnement Node.js ou Webpack), le message d'erreur est facultatif, permettant des fichiers .js (légèrement) plus petits.
Josh Kelley
la source
0

Comme mentionné par TJ, il n'y asserten a pas en JavaScript. Cependant, il existe un module de nœud nommé assert , qui est principalement utilisé pour les tests . ainsi, vous pourriez voir du code comme:

const assert = require('assert');
assert(5 > 7);
yuval.bl
la source