wake-up-neo.com

jasmin parametrisierter Einheitstest

Okay, als C # NUnit-Typ könnte das merkwürdig sein.

Aber erlaubt Jasmin einen parametrisierten Unit-Test?

Ich bin nicht sicher, ob es gegen das "Erklären" und "Es" verstößt, um die Dinge für Nicht-Programmierer lesbar zu machen.

Ich habe einige Plug-Ins von Drittanbietern gesehen, aber sie sind irgendwie alt, nicht sicher, ob sie zu Jasmin hinzugefügt wurden. Wenn ich ein Plug-In verwenden möchte

Um jedem zu helfen, der dies in der Zukunft findet, wurde mir auf dem Jasmin-Forum gesagt, dass es keine erstklassige Unterstützung für parametrisierte Tests in Jasmine selbst gibt.

21
Ashley Kilgour

Basierend auf piotreks Antwort und dem Artikel Parametrisierte Tests in Javascript können Sie auch den folgenden Ansatz verwenden, der die ES6-Syntax verwendet:

[
  ['abc', 3],
  ['ab', 2],
  ['', 0],
].forEach(([string, expectedLength]) => {
  it(`should return length ${expectedLength} for string "${string}"`, () => {
    expect(string.length).toBe(expectedLength);
  });
});

Ich habe es mit dem Jest-Test-Framework getestet, aber es sollte auch mit Jasmine funktionieren.

28
Marco Eckstein

Bessere Lösung (besonders wenn Sie TypeScript verwenden)

Eine andere Lösung ist die Verwendung von Array of Objects anstelle von Array of Arrays . Es passt besser, wenn Sie ein Typsystem wie TypeScript verwenden.


Geben Sie das Problem ein

Stellen Sie sich vor, Sie haben den folgenden parametrisierten Test:

it('action(value) should reset the forms pool only if value is true', () => {
  [
    [true, 1],
    [false, 0],
  ].forEach(([value, calledTimes]) => {
    spyResetFormsPool.calls.reset();

    component.action(value); // type error #1

    expect(spyResetFormsPool).toHaveBeenCalledTimes(calledTimes); // type error #2
  });
});

mit TypeScript wird der Fehler nicht kompiliert und es werden zwei Fehler angezeigt:

fehler # 1:

fehler TS2345: Argument der Typnummer | boolean 'kann keinem Parameter des Typs' boolean 'zugewiesen werden.

fehler # 2: 

fehler TS2345: Argument der Typnummer | boolean 'kann keinem Parameter vom Typ' number 'zugewiesen werden. Typ 'true' ist nicht Dem Typ 'number' zuweisbar.

Das liegt daran, dass TypeScript ein Array von ' number | sieht boolean '.

Wir könnten diese Warnung schnell lösen, indem wir einen expliziten Cast verwenden:

it('action(value) should reset the forms pool only if value is true', () => {
  [
    [true, 1],
    [false, 0],
  ].forEach(([value, calledTimes]) => {
    spyResetFormsPool.calls.reset();

    component.action(value as boolean); // necessary cast

    expect(spyResetFormsPool).toHaveBeenCalledTimes(calledTimes as number);  // necessary cast
  });
});

diese Lösung ist jedoch nicht sehr schön.


Lösung

Ein besserer Weg ist die Verwendung von Array of Objects , sodass die Typen standardmäßig korrekt behandelt werden und keine explizite Umwandlung erforderlich ist :

it('action(value) should reset the forms pool only if value is true', () => {
  [
    { value: true, calledTimes: 1 },
    { value: false, calledTimes: 0 },
  ].forEach(({ value, calledTimes }) => {
    spyResetFormsPool.calls.reset();

    component.action(value);

    expect(spyResetFormsPool).toHaveBeenCalledTimes(calledTimes);
  });
});

Möchten Sie for anstelle von forEach verwenden (finde ich persönlich lesbarer)? Das ist auch möglich:

it('action(value) should reset the forms pool only if value is true', () => {
    for (const {value, calledTimes} of [
      {value: true, calledTimes: 1},
      {value: false, calledTimes: 0},
    ]) {
      spyResetFormsPool.calls.reset();

      component.action(value);

      expect(spyResetFormsPool).toHaveBeenCalledTimes(calledTimes);
    }
 });
12
Francesco Borzi

ich habe schon lange nicht mehr mit Jasmin gearbeitet, aber es war ziemlich einfach, parametrisierte Tests hinzuzufügen:

  ['abc', 3,
   'ab',  4,
   '',    0].
it('should contain string length', function(string, expected){
   expect(string.length).toBe(expected);
});

mit nur wenigen Zeilen Infrastrukturcode:

Array.prototype.it = function(description, testCaseFunction) {
     _(this)
      .chunk(testCaseFunction.length)
      .each(function(innerArray){
                it(description + ' ' + JSON.stringify(innerArray), function(){
                   testCaseFunction.apply(this, innerArray);
                });     
      })
      .value();
};

abhängig von Ihrer gewünschten Syntax und der Bereitschaft, Standard-Js-Objekte zu ändern, haben Sie viele Optionen: http://blog.piotrturski.net/2015/04/jasmine-parameterized-tests.html

3
piotrek

Sie können die folgende Konvention verwenden, um die Lesbarkeit zu verbessern:

const testCases = [
    {actualValue: true, expectedValue: true},
    {actualValue: false, expectedValue: false}
]

testCases.forEach(({actualValue, expectedValue}) => {
    it(`should be the same given: ${actualValue} and expected :${expectedValue} values`, () => {
      expect(actualValue).toBe(expectedValue)
    })
})

Folgende Testfälle werden ausgeführt:

Test Results
+ should be the same given: true and expected: true values
+ should be the same given: false and expected: false values
1

Also fing ich an zu kombinieren: 

  • YAML unter Verwendung von js-yaml
  • jasminjs
  • Typoskript 

um zu schaffen, was meiner Meinung nach lesbare parametrisierte Tests sind: 

import YamlTableReader, {fixtureData, TestData} from "./YamlTableReader";    

describe("TestSuite", () => {
        describe("Real TestCase with Data Fixture", () => {

            // now using tagged template-string to auto convert into YamlTableReader. 

            var testdata = fixtureData ` 

            |   ID  | Value1 | Value2 | Squared |
            |   0   |1       | 1      | 1       |
            |   1   |2       | 2      | 4       |
            |   2   |3       | 3      | 91       |

            `;
            // This actually creates a test for each row of the table above
            testdata.describeEach("Square Test","[ID={ID}]:{Value1} x {Value2} should be equal to {Squared}",
                (row: {Value1: number, Value2: number, Squared: number}) => {
                    expect((row.Value1 * row.Value2)).toBe(row.Squared)
                }
            );
        });

Wenn Sie dies ausführen, erhalten Sie folgende Ergebnisse: 

Failures:
1) TestSuite 2 Real TestCase with Data Fixture Square Test : [ID=2]:3 x 3 should be equal to 91
  Message:
    Expected 9 to be 91.

Quellen: https://github.com/deicongmbh/jasmine-param-tests

0
Dieter