2020
Linting & Testing

Linting & Testing in Nitro

Translated from German using DeepL.

Date: December 2020
Reading time: 5 minutes


Introduction

After reading this blog post, you will know what testing is. You know different variants and understand the difference to linting. You will also know how to apply what you have learned in Nitro.

Linting

The aim is to write consistent code. To achieve this, rules must be defined to which the developers must adhere. This is the prerequisite for clean code. Linting then checks whether these rules have been adhered to.

In Nitro, it is clearly configured when linting takes place. For example, you can only commit if all rules have been followed. This ensures that no unclean code gets into the repository.

The configuration can be found in 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 is linked with the help of Stylelint.

The rules can be found in the node modules (node_modules/@namics/stylelint-config/index.js). However, they may not be changed there, because this folder is only local. If I make a change there, the other developers will not see it. This leads to problems. Therefore, these rules are imported into the stylelint.config.js file. They can be changed there. New ones can also be added.

Example

I wanted to color a text red. To do this, I wrote the following code.

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

When I tried to push these changes to my GitLab repo, it failed. But why?

error

If you study this error message, you will see that the linting failed with the following rule: color-named

This rule is set to never in the node modules. But how can I change it?

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

Rules are described on the Stylelint website (opens in a new tab). There you will also find the options under which they can be used. In this case: string: "always-where-possible"|"never"

Now I just have to adjust the configuration.

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

Now colors may only be specified by name.

Miscellaneous

In addition to CSS, other things can also be linked in Nitro:

  • JS
  • HTML
  • Data
  • License

Testing

Linting checks how cleanly the code is written. Testing checks whether the code is any good.

Functional testing

Functional testing is about testing the function of a component. A test is written that must always be passed. After a change in the code, this test can be executed again. You can then see whether the component still meets expectations.

Cypress

Cypress can be used to write and execute automated tests: https://vimeo.com/237527670 (opens in a new tab)

Create test

A Nitro installation is required to follow these steps.

Create file

To create a test, you can create a new file under test/cypress/integration/examples. The name of the file is structured as follows: nameDerDatei.spec.js

The spec is used to identify a test. Although it is also possible without it, I recommend always writing the spec. This way it is clear that it is a test file.

Define test

The test is now written in this file. Copy the following code into the created file

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

You can start a Cypress test in two ways.

npm run test:cypress

This test can be run in the background, for example. The results are visible in the console.

npm run cypress-test

With this call you can see the test visually. This is ideal for development. That's why we use it here.

npm run cypress-test
Select test

A window opens in which you can select the desired test.

cypress

View the result

The test is complete. Now you can see whether everything went according to plan.

result

Commands

Cypress offers a range of commands. For example, a website can be opened.

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

More commands:

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

A small test could look like this. This opens the Namics page, navigates to the cards and tests whether it displays the correct text for a match.

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?');
    });
});

Visual testing

Visual testing involves testing the appearance.

Example

I have a finished website. Now I want to make a small change to the code. However, this should not affect the appearance of the website. After this change, you can carry out such a test. You can then see whether anything has changed.

But you can also see the changes without such a test, can't you?
A test takes pictures of a page and compares them with the reference. The software can detect minimal differences. This also applies to different sizes. You also save time as you don't have to navigate manually over every single page.

Backstop

Such a visual test can be carried out with Backstop. These are the basic commands.

CommandEffect
backstop initA new backstop instance is set up.
npm run visual-testScreenshots are compared with the reference.
backstop approveThe changes are correct and are now set as a reference. These screenshots will be used for the next test.

If you run a test, you can see what has been changed.

Since these tests are executed with Docker, they deliver the same results on all systems. Docker allows you to run programs in isolation. The environment is comparable to a VM. With Docker, however, an entire environment can be provided and less memory is required.

No change

backstop

Change

backstop-diff

Detailed explanations

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)