Co to jest „asert” w JavaScript?

263

Co assertoznacza JavaScript?

Widziałem coś takiego:

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

I chciałbym wiedzieć, co assert()robi metoda .

frrlod
źródło

Odpowiedzi:

367

assertJavaScript nie ma (jeszcze; mówi się o dodaniu jednego , ale jest na wczesnym etapie). Być może korzystasz z biblioteki, która ją udostępnia. Zwykle oznacza rzucanie błędu, jeśli wyrażenie przekazane do funkcji jest fałszywe; jest to część ogólnej koncepcji sprawdzania asercji . Zazwyczaj asercje (jak się je nazywa) są używane tylko w kompilacjach „testujących” lub „debugujących” i usuwane z kodu produkcyjnego.

Załóżmy, że masz funkcję, która zawsze powinna akceptować ciąg. Chcesz wiedzieć, czy ktoś wywołał tę funkcję z czymś, co nie było łańcuchem. Więc możesz zrobić:

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

... gdzie assertrzuci błąd, jeśli warunek będzie fałszywy.

Bardzo prosta wersja wyglądałaby tak:

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

Jeszcze lepiej, skorzystaj z Errorobiektu, jeśli silnik JavaScript go obsługuje (tak naprawdę stare nie mogą), co ma tę zaletę, że gromadzi ślad stosu i takie:

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

Nawet IE8 ma Error(chociaż nie ma tej stackwłaściwości, ale nowoczesne silniki [w tym współczesne IE] mają).

TJ Crowder
źródło
6
... masz uprzejmość na temat typów w JS? Twierdziłbym, że to jeden z najgorszych powodów assert.
cHao
137
@cHao: Istnieją ważne przypadki użycia. To był tylko pierwszy przykład, który przyszedł mi do głowy. Ten przykład nie ma sensu. Istotą jest koncepcja twierdzeń.
TJ Crowder,
4
coś, co dodałem do mojego kodu w if(!condition)ustawieniach, var throwError=true;a debugger;następnie zawiń sekcję rzucania w if(throwError). W ten sposób, jeśli mam otwarty debugger, pęknie, a jeśli zechcę, mogę ustawić wartość throwErrorfalse, a następnie sprawdzić wszystkie zakresy podczas wychodzenia.
Rick
8
@ Rick, jeśli korzystasz z Chrome DevTools, możesz po prostu włączyć „Wstrzymaj w przypadku nieprzechwyconych wyjątków” na karcie Źródła, a automatycznie się zepsuje throw. W ten sposób nie potrzebujesz debugger;oświadczenia. Więcej informacji znajdziesz na stronie developer.chrome.com/devtools/docs/… .
Vicky Chijwani,
1
@machineghost: Nie rozumiem, jak to jest „prostsze”, właśnie wymieniłeś się ifna operatora warunkowego. W każdym razie w dzisiejszym świecie nie zawracałbym sobie głowy obsługą silników, które tego nie mają Error.
TJ Crowder
157

Jeśli używasz nowoczesnej przeglądarki lub nodejs, możesz użyć console.assert(expression, object).

Po więcej informacji:

joaoprib
źródło
46
Do twojej wiadomości, działa to bardziej tak, console.errorże kod nadal się wykonuje.
Daniel Sokolowski
10
@DanielSokolowski, Dokładnie. console.assertnie jest tak dobry, chyba że ma takie samo zachowanie jak throw.
Pacerier
23
Powodem, dla którego wykonywanie jest kontynuowane, console.assertjest to, że asercje nie są funkcjami obsługi błędów. Są przeznaczone do sprawdzania poprawności kodu tylko podczas programowania. Tradycyjnie są one całkowicie wyłączone w środowiskach produkcyjnych, aby uniknąć zamykania aktywnych systemów z powodu czegoś trywialnego. Przeglądarka jest uważana za środowisko produkcyjne, więc console.assertnie przerywa tam wykonywania. Jeśli polegasz na asercjach, aby zatrzymać wykonywanie, powinieneś zamiast tego korzystać z odpowiedniej obsługi błędów, ponieważ nie do tego służą asercje.
Malvineous,
8
@RonBurk: Projektanci języków zdecydowali „do czego służą twierdzenia”. W C ++ [asercja] służy do wychwytywania błędów programistycznych, a nie błędów użytkownika lub czasu wykonywania, ponieważ zazwyczaj jest wyłączona po wyjściu programu z fazy debugowania. PHP mówi Zasadniczo twój kod powinien zawsze być w stanie działać poprawnie, jeśli sprawdzanie asercji nie jest aktywowane. Głos pasywny nie miał na celu nadania autorytetu osobistym preferencjom, ale raczej poinformowanie o ogólnie przyjętej praktyce ogólnej.
Malvineous
4
@ Don: Punkt zajęty, ale właśnie cytowałem z połączonych stron. Uważam, że twierdzenia należy traktować tak, jakby można je było wyłączyć, choćby dlatego, że pewnego dnia kod może zostać wykorzystany przez kogoś, kto uważa, że ​​jest to bezpieczne. Jeśli asercje są krytyczne dla twojego kodu, to myślę, że powinny one zostać zaktualizowane do poprawnego sprawdzania błędów zamiast polegać na metodzie debugowania, która nie zawsze gwarantuje zakończenie wykonywania. Nie wspominając już o tym, że Twój kod wielokrotnie umiera w środowisku produkcyjnym, gdy może po prostu zwrócić błąd i kontynuować, może powodować więcej stresu niż jest to warte!
Malvineous,
29

Inne odpowiedzi są dobre: ​​w ECMAScript5 nie ma wbudowanej funkcji asercji (np. JavaScript, który działa właściwie wszędzie), ale niektóre przeglądarki dają ci to lub mają dodatki zapewniające tę funkcjonalność. Chociaż najlepiej jest do tego użyć dobrze ugruntowanej / popularnej / utrzymanej biblioteki, do celów akademickich funkcja „twierdzenia biedaka” może wyglądać mniej więcej tak:

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
źródło
BTW, można łatwo to zmodyfikować, tak aby powodowało to błąd tylko w środowiskach programistycznych (np. Przez zawijanie innego, jeśli / dodawanie innego warunkowego), a poza tym nic nie robi lub wyświetla tylko ostrzeżenie. Osobiście uważam, że stwierdzenia powinny znajdować się tylko w kodzie testowym (np. Sprawdzanie, czy oczekiwane i rzeczywiste wyniki są zgodne); w produkcji kodu powinny też być zbędny (gwarantowane poprawna konstrukcji) i w ten sposób usuwa się albo tylko dla kontroli wejściowymi / zewnętrzny, w którym to przypadku mogą być zastąpione przez logikę odkażania i standardowe obsługę wyjątków (na przykład try, catch, throw)
iX3
8

assert()nie jest rodzimą funkcją javascript. Jest to niestandardowa funkcja, którą ktoś stworzył. Będziesz musiał poszukać go na swojej stronie lub w swoich plikach i opublikować, aby ktokolwiek pomógł ustalić, co robi.

Kredka Gwałtowna
źródło
5

sprawdź to: http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-quick-and-easy-javascript-testing-with-assert/

służy do testowania JavaScript. O dziwo, przy zaledwie pięciu lub sześciu liniach kod ten zapewnia dużą moc i kontrolę nad twoim kodem podczas testowania.

Funkcja assert akceptuje dwa parametry:

wynik: wartość logiczna, która określa, czy test przeszedł pomyślnie, czy nie

opis: krótki opis twojego testu.

Funkcja potwierdzenia następnie tworzy element listy, stosuje klasę „pozytywny” lub „negatywny”, w zależności od tego, czy test zwrócił wartość prawda czy fałsz, a następnie dołącza opis do elementu listy. Na koniec ten kodowany kod jest dodawany do strony. To szalone proste, ale działa idealnie.

Amrendra
źródło
4

Oto naprawdę prosta implementacja funkcji asercji. Wymaga wartości i opisu tego, co testujesz.

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

Jeśli wartość ma wartość true, przechodzi.

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

Jeśli zwróci fałsz, nie powiedzie się.

assert (1===2, 'testing if 1=1');
joshpierro
źródło
1
Celem asercji nie jest rejestrowanie na stdout na poziomie informacji, ale zatrzymanie wykonywania programu (zwykle zgłaszającego wyjątek) i rejestrowanie na stderr, jeśli asercja jest oceniana na false.
Nuno André,
4

Jeśli twierdzenie jest fałszywe, wyświetlany jest komunikat. W szczególności, jeśli pierwszy argument jest fałszywy, drugi argument (komunikat tekstowy) zostanie zarejestrowany w konsoli narzędzi programistycznych. Jeśli pierwszy argument jest prawdziwy, w zasadzie nic się nie dzieje. Prosty przykład - używam Narzędzi Google dla programistów:

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.');
Szalony kot
źródło
3

Prawdopodobnie przyszedł z biblioteką testową, z której korzysta część twojego kodu. Oto przykład jednego (istnieje prawdopodobieństwo, że nie jest to ta sama biblioteka, z której korzysta Twój kod, ale pokazuje ogólny pomysł):

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

Matt Browne
źródło
2

Słowo lub funkcja „aser” jest najczęściej używana w testowaniu części aplikacji.

Funkcje asercji to krótki sposób instruowania programu, aby sprawdził warunek (zwany także „asercją”), a jeśli warunek nie jest spełniony, spowoduje zgłoszenie błędu.

Zobaczmy więc, jak by to wyglądało w „normalnym kodzie”

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

Dzięki assertnie możesz po prostu napisać:

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

W Javascript nie ma assertfunkcji natywnej , więc musisz użyć jednej z jakiejś biblioteki.

Dla prostego wprowadzenia możesz sprawdzić ten artykuł:

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

Mam nadzieję, że to pomoże.

Pavel
źródło
2

Asercja generuje komunikat o błędzie, jeśli pierwszy atrybut jest fałszywy, a drugi atrybut to komunikat, który ma zostać zgłoszony.

console.assert(condition,message);

Istnieje wiele komentarzy mówiących, że asercja nie istnieje w JavaScript, ale console.assert()jest funkcją asercji w JavaScript. Ideą asercji jest ustalenie, dlaczego / gdzie występuje błąd.

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

Tutaj, w zależności od komunikatu, możesz znaleźć błąd. Te komunikaty o błędach będą wyświetlane na konsoli w kolorze czerwonym, tak jakbyśmy zadzwonili console.error();
Aby zobaczyć więcej funkcji w konsoliconsole.log(console);

Rahul
źródło
1

Poprzednie odpowiedzi można poprawić pod względem wydajności i kompatybilności.

Sprawdź raz, czy Errorobiekt istnieje, jeśli nie, zadeklaruj go:

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

Następnie każde stwierdzenie sprawdzi warunek i zawsze rzuci Errorobiekt

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

Należy pamiętać, że konsola nie wyświetla rzeczywistego numeru linii błędu, ale linię assertfunkcji, która nie jest przydatna do debugowania.

Karl.S
źródło
1

Jeśli używasz WebPACK, można po prostu użyć node.js bibliotekę twierdzenie . Chociaż twierdzą, że „nie jest to biblioteka asercji ogólnego przeznaczenia”, wydaje się, że jest bardziej niż OK dla asercji ad hoc, i wydaje się, że w przestrzeni Węzła nie istnieje żaden konkurent (Chai jest przeznaczony do testowania jednostkowego).

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

Aby móc z niego korzystać, musisz użyć pakietu internetowego lub przeglądarki, więc jest to przydatne tylko wtedy, gdy są już w toku pracy.

amoe
źródło
1

Oprócz innych opcji, takich jak console.assert lub rozwijanie własnych , możesz użyć niezmiennika . Ma kilka unikalnych funkcji:

  • Obsługuje sformatowane komunikaty o błędach (przy użyciu %sspecyfikatora).
  • W środowiskach produkcyjnych (określonych przez środowisko Node.js lub Webpack) komunikat o błędzie jest opcjonalny, pozwalając na (nieco) mniejsze .js.
Josh Kelley
źródło
0

Jak wspomniano przez TJ, assertJavaScript nie istnieje . Istnieje jednak moduł węzła o nazwie assert , który jest używany głównie do testowania . więc możesz zobaczyć kod taki jak:

const assert = require('assert');
assert(5 > 7);
yuval.bl
źródło