Storybook для Angular
Контекст
Nx 13 — Angular 13 — Storybook 6.5.0-alpha.36
Почему?
Чем больше растет ваше приложение, тем больше риск появления ошибок. В одном из недавних проектов у нас есть несколько видов тестов: Юнит-тесты (их очень много) и несколько интеграционных тестов. Мы работаем инкрементально, добавляем функции во время спринтов и переделываем старые с более функциональными правилами. Даже если мы тестируем все фичи юнит-тестами, наступает момент, когда ты понимаешь, что не можешь протестировать все юнит-тестами.
Мы разработали Storybook, который содержит все наши компоненты / директивы. Иногда мы проверяем некоторые из них во время разработки и удивляемся, что они сломаны :-(. Тем не менее, все наши модульные тесты в порядке…
Как?
Я искал решение, как легко внедрить несколько функциональных тестов без тестирования взаимодействия с бэкендом. Нашей целью было только функциональное тестирование нашего HMI.
Я уже слышал разговоры о Cypress и, проведя небольшое исследование, нашел идеальное решение для нас. Nx предлагает возможность включить e2e приложение с конфигурацией Cypress для тестирования нашего Storybook (Miracle).
Я установил все требования и начал писать функциональные тесты. И что удивительно, некоторые тесты провалились, в то время как все наши юнит-тесты и интеграционные тесты работают… Как ведущего разработчика, меня это сначала обмануло, потому что это означает, что я не гарантировал качество нашего приложения. Но, если подумать, какая радость видеть, что я все еще могу учиться и открывать для себя что-то новое! Я уверен, что многие из нас уже побывали в такой ситуации. Так что давайте прекратим болтать, вот как это сделать.
Установка
Полагаю, у вас уже есть проект Nx — Angular со Storybook. Здесь мы просто поговорим об установке Cypress для Storybook.
nx generate [@nrwl/storybook](http://twitter.com/nrwl/storybook):cypress-project --name={your_app_name} --linter=eslint --no-interactive
Мое приложение называется «Storybook», и вот результат выполнения команды:
nx generate [@nrwl/storybook](http://twitter.com/nrwl/storybook):cypress-project --name=storybook --linter=eslint --no-interactive
UPDATE package.json
CREATE apps/storybook-e2e/cypress.json
CREATE apps/storybook-e2e/src/fixtures/example.json
CREATE apps/storybook-e2e/src/support/commands.ts
CREATE apps/storybook-e2e/src/support/index.ts
CREATE apps/storybook-e2e/tsconfig.json
CREATE apps/storybook-e2e/project.json
UPDATE workspace.json
CREATE apps/storybook-e2e/.eslintrc.json
UPDATE nx.json
В package.json мы можем увидеть еще две dev-зависимости: @nrwl/cypress и cypress, logic.
В файле storybook-e2e/tsconfig.json мы видим следующее:
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"sourceMap": _false_,
"outDir": "../../dist/out-tsc",
"allowJs": _true_,
"types": ["cypress", "node"]
},
"include": ["src/ **/*.ts", "src/** /*.js"]
}
Ничего особенного, кроме типа «cypress».
Теперь заглянем в файл storybook-e2e/project.json:
{
"root": "apps/storybook-e2e",
"sourceRoot": "apps/storybook-e2e/src",
"projectType": "application",
"targets": {
"e2e": {
"executor": "@nrwl/cypress:cypress",
"options": {
"cypressConfig": "apps/storybook-e2e/cypress.json",
"devServerTarget": "storybook:storybook"
},
"configurations": {
"ci": {
"devServerTarget": "storybook:storybook:ci"
}
}
},
"lint": {
"executor": "@nrwl/linter:eslint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["apps/storybook-e2e/**/*.{js,ts}"]
}
}
},
"tags": [],
"implicitDependencies": ["storybook"]
}
Как мы видим, целевой сервер определен нашим приложением storybook «devServerTarget»: «storybook:storybook:ci», которое запускается в режиме ci. Таким образом, существует неявная зависимость с нашим приложением Storybook «implicitDependencies»: [«storybook»].
Вы уже можете попробовать:
nx e2e {your_app_name}-e2e
В результате произойдет сбой:
Can't run because no spec files were found.
We searched for any files inside of this folder:
...appsstorybook-e2esrcintegration
Да, у нас пока нет возможности писать тесты. Если вы не знаете, как писать тесты для cypress, вы можете прочитать документацию здесь, которая идеально подходит.
Эта команда идеально подходит для тестирования в терминале. Но некоторые из нас предпочитают видеть это в реальном окне. Чтобы открыть cypress и выполнять тесты по требованию, я предлагаю вам создать еще один cypress.json следующим образом:
// cypress.local.json
{
"fileServerFolder": ".",
"fixturesFolder": "apps/storybook-e2e/src/fixtures",
"integrationFolder": "apps/storybook-e2e/src/integration",
"modifyObstructiveCode": _false_,
"supportFile": "apps/storybook-e2e/src/support/index.ts",
"pluginsFile": _false_,
"video": _true_,
"videosFolder": "../../dist/cypress/apps/storybook-e2e/videos",
"screenshotsFolder": "../../dist/cypress/apps/storybook-e2e/screenshots",
"chromeWebSecurity": _false_,
"baseUrl": "http://localhost:4400" // set the url of your local Storybook
}
Добавьте эту команду в ваш package.json :
"test:storybook:local": "cypress open --browser ~\chrome-win\chrome.exe -C apps/storybook-e2e/cypress.local.json"
Здесь я использую chromium в качестве браузера и указываю локальный конфиг cypress.
Теперь вы можете запустить свой локальный storybook и свой локальный cypress:
nx run storybook:storybook
npm run test:storybook:local
Пока вы не напишете несколько тестов, ничего не получится.
Чтобы помочь в написании тестов для Storybook, я предлагаю вам установить следующую библиотеку:
npm i -D cypress-storybook
Затем импортируйте вспомогательные команды в индексный файл поддержки:
// apps/storybook-e2e/src/support/index.ts
import 'cypress-storybook/cypress'
Затем импортируйте это в файл предварительного просмотра книги рассказов, это поможет книге рассказов понять команды cypress:
// apps/storybook/.storybook/preview.js
import 'cypress-storybook/angular'
Наконец, в вашем тестовом файле, что вы должны сделать:
describe('MyComponent', () => {
beforeEach(() => {
cy.visitStorybook();
cy.loadStory('title-of-my-story', 'MyStoryName');
});
it('my test', () => {
...
});
});
В документации рекомендуется обернуть cy.visitStorybook(); в before, а не beforeEach, но когда я попробовал, он не сбрасывает Story в случаях формы между каждым тестом.
Заключение
Теперь вы будете более вооружены для борьбы с ошибками! Никаких оправданий, особенно если вы используете Nx, который очень помогает в настройке. Я советую вам написать несколько команд для упрощения написания тестов, например, команду fillForm, которая получает фикстуру и тег формы. Это сделает ваш тест более читабельным.
Спасибо, что прочитали.
Подробнее
- История для директивы Angular V2
- История для компонента с проекцией содержимого
- Установите Jest для Angular
- Angular для всех: Все об этом