Manual:JavaScript unit testing/QUnit guidelines/cs
Srovnání
Používejte porovnávací funkce, jako například strictEqual() a propEqual().
Vyhněte se předávání výrazů do ok().
Nechat porovnání provádět QUnit má několik výhod:
- Umožňuje spouštěči testu zobrazit rozdíl mezi očekávanými a skutečnými hodnotami. Při použití
ok()je nutné použít inline výraz, čímž se tato informace ztratí. To je obzvláště důležité při práci s testovacími protokoly generovanými externě (např. z Jenkins nebo Karma), v takovém případě máte k dispozici pouze výstup testu. (Při ručním spouštění testů v prohlížeči lokálně je možné nastavit zarážky atd.) - Předání explicitní očekávané hodnoty slouží k samodokumentování očekávaného výsledku.
- Použití explicitní očekávané hodnoty zabraňuje nechtěnému skrytí regresí v důsledku přetypování a nestriktního porovnávání.
// Není to moc užitečné, porovnání se provádí inline a ok() může vědět pouze o výsledku porovnání.
var x = 'foo';
assert.ok( x === 'bar' ); // Neúspěšné.
assert.ok( x === 'foo' ); // Prošlo.
// Užitečné! Jednotkovému testu jsou přiřazeny obě hodnoty, což umožňuje jejich uvedení ve výstupu:
var x = 'foo';
assert.strictEqual( x, 'bar' ); // Neúspěšné. Očekávané: "bar". Výsledek: "foo"
assert.strictEqual( x, 'foo' ); // Prošlo. Očekávané: "foo"
V případech, kdy je přesná hodnota příliš variabilní nebo na ní nezáleží, můžete stále provést explicitní porovnání kontrolou jejího typu (v případě funkce) nebo její délky (v případě pole nebo řetězce). Například:
// Špatný příklad:
// - Neuspěje nebo projde bez dalších informací.
// - Toleruje příliš mnoho neočekávaných výsledků.
assert.ok( mw.Example, 'Quux is defined' );
assert.ok( mw.foo.barName, 'Name is set' );
assert.strictEqual( typeof mw.Example, 'function', 'Quux is defined' );
// Neúspěšné. Očekávané: "function" Výsledek: "undefined"
// Prošlo. Očekávané: "function"
assert.strictEqual( typeof mw.foo.barName, 'string', 'Name is set' );
// Neúspěšné. Očekávané: "string". Výsledek: "number"
// Prošlo. Očekávané: "string"
Při práci s objekty (jako jsou pole, objektové literály nebo jiné objekty) nelze k porovnání obsahu použít equal.
V takovém případě je nutné použít propEqual, který projde objekt a porovná každý klíč/hodnotu zvlášť.
Například:
var a = ['foo', 'bar'];
assert.equal(a, ['foo', 'bar'], 'The array');
assert.strictEqual(a, ['foo', 'bar'], 'The array');
// Failed, because objects are compared by identity.
assert.deepEqual(a, ['foo', 'bar'], 'The array.');
// Passed. Expected: ['foo', 'bar']
Testovací prvky
Spouštěc QUnit automaticky zajišťuje existenci prvku <div id="qunit-fixture"></div> a je před každým testem QUnit vyčištěn.
Použijte to pro všechny prvky, které je třeba propojit s dokumentem.
Nepřidávejte uzly jinam v dokumentu, protože by mohly zůstat pozadu a ovlivnit další testy.
Asynchronní
Testy, které potvrzují výsledek asynchronní metody (nebo metody, která vrací promise), by měly mít návratovou hodnotu vrácenou funkcí QUnit.test().
Díky tomu může QUnit automaticky sledovat promise, aniž by ho musel ručně propojovat s assert.async.
To má výhodu v tom, že se také automaticky potvrdí, že je Promise vyřešen, a pokud byl promise odmítnut, test selže s chybou odmítnutí.
Nejsou potřeba žádné příručky assert.ok(true/false).
Pokud se očekává odmítnutí asynchronní metody, nikoli její vyřešení, lze použít assert.rejects(), která se chová stejně jako vrácení Promise metodě QUnit.test, s tím rozdílem, že očekává odmítnutí, nikoli vyřešení.
A konečně, pokud je test asynchronní, ale přirozeně neposkytuje Promise, můžete k jeho ručnímu sledování použít assert.async().
Toto je upřednostňováno před vytvářením vlastních obalů Promise nebo Deferred.
Data sourcing/seeding in Ajax requests
Because QUnit tests shouldn't depend by the data registered on the back-end (unless the test is not meant to verify a specific data-set available by default upon installation) the Ajax calls performed during tests requests should be handled using the following strategy:
- if the result of an Ajax request only depends from the data provided by the client, or additional data retrieved on the server do not depend by a specific data-set, then a real Ajax request can be performed during the test, and the test can be verified either using
assert.asyncin conjunction withdoneor using a trigger - if the result of an Ajax request depends by a specific data-set registered on the back-end, then the result should be either overridden with data provided by the QUnit function, or the success callback should be directly executed with the provided data without performing the Ajax request.
The rationale is that if a QUnit test relies on specific data-set server-side, unless they are seeded on the back-end as part of the test, and unless such data is not installed by default, in a different environment the Javascript tests will fail as long as the same data-set won't be found. This is of course true for every Ajax request involved from the test, also indirectly, so check carefully all the workflow of your script to prevent errors!
Common Pitfalls
Event-Based Tests Fail in CI but Pass Locally
Symptom: A QUnit test that fires events through Metrics Platform works fine on a local machine but fails in CI with no clear error message.
Cause: The test environment does not have the correct user permissions set, causing event submissions to fail.
Fix: Ensure that mw.config includes the necessary user groups before events are fired by adding the following line at the start of the test. This ensures that the test environment has the right permissions to handle event submissions.
See Troubleshooting QUnit Test Failures for a more detailed debugging guide.