2020
Linting & Testing

Linting & Testing in Nitro

Datum: Dezember 2020
Lesedauer: 5 Minuten


Einleitung

Nach diesem Blogpost weisst du, was Testing ist. Du kennst verschiedene Varianten und verstehst den Unterschied zum Linting. Zudem weisst du, wie du das Erlernte in Nitro anwenden kannst.

Linting

Das Ziel ist, einen gleichmässigen Code zu schreiben. Dafür müssen Regeln definiert werden, nach welchen sich die Entwickler richten müssen. Dies ist die Voraussetzung für einen sauberen Code. Beim Linting wird dann überprüft, ob diese Regeln eingehalten wurden.

In Nitro ist klar konfiguriert, wann gelintet wird. Es kann z.B. nur commitet werden, wenn alle Regeln befolgt wurden. Dies gewährleistet, dass kein unsauberer Code ins Repository gelangt.

Die Konfiguration findet man im package.json.

package.json
{
    "husky": {
        "hooks": {
            "pre-commit": "lint-staged"
        }
    },
    "lint-staged": {
        "src/**/*.{css,scss}": ["stylelint --allow-empty-input"],
        "src/**/*.json": ["prettier --write", "npm run lint:data"],
        "src/**/*.{js,jsx}": ["prettier --write", "eslint"],
        "src/**/*.md": ["prettier --write"],
        "package.json": ["env-linter --saveExact --dependenciesExactVersion"]
    }
}

CSS

CSS wird mit Hilfe von Stylelint gelintet.

Die Regeln sind in den node modules (node_modules/@namics/stylelint-config/index.js) zu finden. Dort dürfen sie aber nicht abgeändert werden, denn dieser Ordner ist nur lokal. Nehme ich dort eine Änderung vor, so sehen es die anderen Entwickler nicht. Dies führt zu Problemen. Deshalb werden diese Regeln in die stylelint.config.js Datei importiert. Dort können sie geändert werden. Zudem dürfen auch neue hinzugefügt werden.

Beispiel

Ich wollte einen Text rot färben. Dazu schrieb ich folgenden Code.

button.scss
.a-button {
    color: red;
}

Als ich diese Änderungen auf mein GitLab Repo pushen wollte, schlug dies fehl. Doch warum?

error

Studiert man diese Fehlermeldung so erkannt man, dass das Linting bei folgender Regel fehlschlug: color-named

Diese Regel ist in den node modules auf never gesetzt. Doch wie kann ich diese ändern?

index.js
'color-named': 'never',

Regeln werden auf der Website von Stylelint (opens in a new tab) beschrieben. Dort findet man auch die Optionen, unter welchen sie genutzt werden können. In diesem Fall:
string: "always-where-possible"|"never"

Nun muss ich nur noch die Konfiguration anpassen.

stylelint.config.js
lintConfig.rules['color-named'] = 'always-where-possible';

Jetzt dürfen Farben lediglich mit dem Namen angegeben werden.

Sonstiges

Neben CSS können in Nitro auch andere Dinge gelintet werden:

  • JS
  • HTML
  • Data
  • License

Testing

Beim Linting wird überprüft, wie sauber der Code geschrieben ist. Beim Testing wird geschaut, ob der Code etwas taugt.

Funktionales Testing

Beim funktionalem Testing geht es darum, die Funktion einer Komponente zu testen. Man schreibt einen Test, der immer bestanden werden muss. Nach einer Änderung im Code, kann dieser Test wieder ausgeführt werden. Dann sieht man, ob die Komponente noch den Erwartungen entspricht.

Cypress

Mit Cypress können automatisierte Tests geschrieben und durchgeführt werden:
https://vimeo.com/237527670 (opens in a new tab)

Test erstellen

Um diesen Schritten zu folgen, muss eine Nitro installation vorliegen.

Datei anlegen

Um einen Test zu erstellen, kann man unter test/cypress/integration/examples ein neues File erstellen. Der Name der Datei ist folgendermassen aufgebaut: nameDerDatei.spec.js

Das spec dient zur Identifizierung eines Tests. Obwohl es auch ohne geht, empfehle ich das spec immer zu schreiben. So ist es eindeutig, dass es sich dabei um ein Test-File handelt.

Test definieren

In dieser Datei wird nun der Test geschrieben. Kopiere dazu folgenden Code in die angelegte Datei.

describe('My First Test', () => {
    it('Does not do much!', () => {
        expect(true).to.equal(true);
    });
});
Cypress starten

Man kann einen Cypress Test auf zwei Arten starten.

npm run test:cypress

Dieser Test kann man z.B. im Hintergrund aufrufen. Die Resultate sind in der Konsole sichtbar.

npm run cypress-test

Mit diesem Aufruf sieht man den Test Visuell. Dies ist optimal zur Entwicklung. Deshalb verwenden wir ihn hier.

npm run cypress-test
Test auswählen

Es öffnet sich ein Fenster, in welchem man den gewünschten Test auswählen kann.

cypress

Resultat begutachten

Der Test ist abgeschlossen. Nun sieht man, ob alles nach Plan verlief.

result

Befehle

Cypress bietet einem eine Reihe von Befehlen an. So kann beispielsweise eine Website geöffnet werden.

describe('My First Test', () => {
    it('Visits the Namics Website', () => {
        cy.visit('https://namics.com');
    });
});

Weitere Befehle:

  • .click()
  • .dblclick()
  • .rightclick()
  • .type()
  • .clear()
  • .check()
  • .uncheck()
  • .select()
  • .trigger()

So könnte ein kleiner Test aussehen. Dieser öffnet die Namics Seite, navigiert zu den Karten und testet, ob es bei einem Match den korrekten Text anzeigt.

describe('Namics Test', function () {
    it('Correct Match Text', function () {
        cy.visit('https://namics.com');
        cy.get('#onetrust-accept-btn-handler').click();
        cy.get('.header__inner-controls > .header__btn-toggle').click();
        cy.get(
            ':nth-child(4) > .header-nav__item > .header-nav__item-inner > .header-nav__item-title'
        ).click();
        for (let i = 0; i < 6; i++) {
            cy.get(
                '.module-slider-tiles__top > .slider-indicator > .slider-indicator__next > svg > path'
            ).click();
        }
        cy.get(
            '.module-match__grid > .tiles-grid > .gr-row > :nth-child(1) > .tile > .tile__content'
        ).click();
        cy.get(
            '.module-match__grid > .tiles-grid > .gr-row > :nth-child(2) > .tile > .tile__content'
        ).click();
        cy.get(
            '.module-match__grid > .tiles-grid > .gr-row > :nth-child(3) > .tile > .tile__content'
        ).click();
        cy.get(
            '.module-match__result-teaser > .teaser-action > .teaser-action__headline'
        ).should('have.text', 'It‘s a Match! Wie wäre es mit einem Date?');
    });
});

Visuelles Testing

Bei Visuellen Testing wird das Aussehen getestet.

Beispiel

Ich habe eine fertige Webseite. Nun will ich eine kleine Änderung im Code vornehmen. Diese soll sich aber nicht auf das Aussehen der Webseite auswirken. Nach dieser Änderung kann man einen solchen Test durchführen. Somit sieht man, ob sich etwas verändert hat.

Aber die Änderungen sieht man doch auch ohne einen solchen Test, oder?
Ein Test macht Bilder einer Seite und gleicht diese mit der Referenz ab. Die Software kann minimale Unterschiede feststellen. Dies auch auf verschiedenen Grössen. Zudem sparrt man Zeit, da man nicht manuell über jede einzelne Seite navigieren muss.

Backstop

Mit Backstop kann ein solcher Visueller Test ausgeführt werden. Dies sind die grundlegenden Befehle.

BefehlEffekt
backstop initEine neue Backstop Instanz wird aufgesetzt.
npm run visual-testScreenshots werden mit der Referenz verglichen.
backstop approveDie Änderungen sind korrekt und werden jetzt als Referenz gesetzt. Beim nächsten Test werden diese Screenshots verwendet.

Führt man einen Test aus, so erkennt man, was verändert wurde.

Da diese Tests mit Docker ausgeführt werden, liefern sie auf allen Systemen die selben Ergebnisse. Mit Docker kann man nämlich Programme isoliert ausführen. Die Umgebung ist mit einer VM zu vergleichen. Mit Docker kann aber eine ganze Umgebung bereitgestellt werden und es wird weniger Speicher benötigt.

Keine Veränderung

backstop

Veränderung

backstop-diff

Ausführliche Erklärungen

Backstop: https://www.npmjs.com/package/backstopjs (opens in a new tab)
Docker: https://docs.docker.com/get-started/overview/ (opens in a new tab)