Create-React-app이 인기 있는 도구가 된 이후, React에 대한 많은 튜토리얼에서 이를 시작 도구로 사용합니다. 하지만 Create-React-App이 우리에게 어떤 역할을 했는지 배우고 툴에 의존하지 않고 테스트 환경도 설정할 수 있도록 스스로 환경을 설정하기로 결정했습니다.
인기 있는 스타터 프로젝트를 관찰하고 이러한 설정을 최상의 방식으로 작성하는 데 필요한 코드를 취했습니다. 따라서 create-react-app의 일부 코드가 표시됩니다.
데모 저장소
완벽한 예를 보고 싶다면, 제가 시연용 상용구를 만들었습니다. https://github.com/tabsteveyang/react-jest-rtl-boilerplate
구성 설정
종속성
이것들은 당신에게 필요한 패키지입니다. 별도로 설치하거나 아래 코드를 패키지의 devDependencies 블록에 추가할 수 있습니다.json 파일 및 설치:
"babel-preset-react-app": "^10.0.0",
"react-app-polyfill": "^2.0.0",
"react-test-renderer": "^17.0.2", // (optional) for snapshot test
"redux-mock-store": "^1.5.4", // (optional) for mocking redux
"babel-jest": "^26.6.0",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^11.2.7",
"@testing-library/user-event": "^12.8.3",
"jest": "26.6.0",
"jest-circus": "26.6.0",
"jest-resolve": "26.6.0",
"jest-watch-typeahead": "0.6.1"
진입점
1. 진입점의 파일
이것은 환경 변수를 설정하고 명령으로부터 인수를 받은 후 테스트를 시작하기 위해 농담하는 JS 파일입니다.
// jest/scripts/test.js
process.env.BABEL_ENV = 'test'
process.env.NODE_ENV = 'test'
process.env.PUBLIC_URL = ''
const jest = require('jest')
const argv = process.argv.slice(2)
jest.run(argv)
2. 스크립트 업데이트
패키지에서 스크립트 블록의 테스트 특성을 업데이트합니다.json 파일을 사용하면 npm run test
를 실행하여 테스트를 시작할 수 있습니다.
"scripts": {
"test": "node jest/scripts/test.js",
}
3. 변환을 위한 JS 파일
JS 파일은 jest가 사용할 수 있는 형태로 특정 확장자의 파일을 변환하기 위한 것이다.
- babelTransform.js
'use strict'
const babelJest = require('babel-jest')
const hasJsxRuntime = (() => {
if (process.env.DISABLE_NEW_JSX_TRANSFORM === 'true') {
return false
}
try {
require.resolve('react/jsx-runtime')
return true
} catch (e) {
return false
}
})()
module.exports = babelJest.createTransformer({
presets: [
[
require.resolve('babel-preset-react-app'),
{
runtime: hasJsxRuntime ? 'automatic' : 'classic'
}
]
],
babelrc: false,
configFile: false
})
- cssTransform.js
'use strict'
// This is a custom Jest transformer turning style imports into empty objects.
// http://facebook.github.io/jest/docs/en/webpack.html
module.exports = {
process() {
return 'module.exports = {};'
},
getCacheKey() {
// The output is always the same.
return 'cssTransform'
}
}
- 파일Transform.js
'use strict'
const path = require('path')
const camelcase = require('camelcase')
// This is a custom Jest transformer turning file imports into filenames.
// http://facebook.github.io/jest/docs/en/webpack.html
module.exports = {
process(src, filename) {
const assetFilename = JSON.stringify(path.basename(filename))
if (filename.match(/\.svg$/)) {
// Based on how SVGR generates a component name:
// https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6
const pascalCaseFilename = camelcase(path.parse(filename).name, {
pascalCase: true
})
const componentName = `Svg${pascalCaseFilename}`
return `const React = require('react');
module.exports = {
__esModule: true,
default: ${assetFilename},
ReactComponent: React.forwardRef(function ${componentName}(props, ref) {
return {
$$typeof: Symbol.for('react.element'),
type: 'svg',
ref: ref,
key: null,
props: Object.assign({}, props, {
children: ${assetFilename}
})
};
}),
};`
}
return `module.exports = ${assetFilename};`
}
}
4. 테스트를 실행하기 전에 실행되는 JS 파일
테스트를 실행하기 전에 실행해야 하는 모든 논리를 넣을 파일을 만듭니다. 일반적으로 설정이라고 합니다.tests.js 및 파일의 코드는 다음과 같아야 합니다.
// import the modules that most tests will need
import '@testing-library/jest-dom'
import React from 'react'
import ReactDom from 'react-dom'
import PropTypes from 'prop-types'
// if there are some settings like below in your webpack.config.js, you can mock it in this way:
// new webpack.ProvidePlugin({
// React: 'react',
// ReactDom: 'react-dom',
// PropTypes: 'prop-types'
// })
global.React = React
global.ReactDom = ReactDom
global.PropTypes = PropTypes
5. Jest 구성
위의 단계를 마친 후, 우리는 마침내 장난삼아 구성을 작성하고 모든 설정을 연결할 수 있습니다!
서류에 따르면 제이에스트의 구성을 패키지에 넣을 수 있습니다.json 파일 또는 jest.config.js 파일. 구성에 변수를 사용하고 패키지를 보관해야 할 경우를 대비해서 jeast.config.js 파일에 설정을 넣기로 했어요.json 파일을 정리합니다.
module.exports = {
roots: [
'<rootDir>/src'
],
collectCoverageFrom: [
'src/**/*.{js,jsx,ts,tsx}',
'!src/**/*.d.ts'
],
setupFiles: [
'react-app-polyfill/jsdom'
],
setupFilesAfterEnv: [
'<rootDir>/jest/scripts/setupTests.js'
],
testMatch: [
'<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}',
'<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}'
],
testEnvironment: 'jsdom',
transform: {
'^.+\\.(js|jsx|mjs|cjs|ts|tsx)$': '<rootDir>/jest/transforms/babelTransform.js',
'^.+\\.css$': '<rootDir>/jest/transforms/cssTransform.js',
'^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|json)$)': '<rootDir>/jest/transforms/fileTransform.js'
},
transformIgnorePatterns: [
'[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs|cjs|ts|tsx)$',
'^.+\\.module\\.(css|sass|scss)$'
],
modulePaths: [],
moduleFileExtensions: [
'web.js',
'js',
'web.ts',
'ts',
'web.tsx',
'tsx',
'json',
'web.jsx',
'jsx',
'node'
],
watchPlugins: [
'jest-watch-typeahead/filename',
'jest-watch-typeahead/testname'
],
resetMocks: true
}
웹 팩.config.js 파일에 별칭을 선언했다고 가정합니다. 이 경우 테스트를 실행할 때 별칭이 작동하도록 moduleNameMapper 설정을 추가해야 할 수도 있습니다.
moduleNameMapper: {
'^@js(.*)$': '<rootDir>/src/js$1',
'^@scss(.*)$': '<rootDir>/src/scss$1',
'^@img(.*)$': '<rootDir>/img$1'
},
설정 확인을 위한 첫 번째 테스트 파일
마지막으로 모든 설정을 마친 후 간단한 테스트 파일을 생성하여 예상대로 작동하는지 확인할 수 있습니다.
// src/js/components/_tests_/TestPage.test.jsx,
// for testing: src/js/components/TestPage.jsx file.
import { render, screen } from '@testing-library/react'
import TestPage from '../TestPage'
test('renders Hello World', () => {
render(<TestPage />)
const linkElement = screen.getByText(/Hello World/i)
expect(linkElement).toBeInTheDocument()
})
그리고 명령행에서 명령을 실행하여 테스트를 시작합니다.
cd <project_path>
npm run test
jeast와 상호 작용하려면 코드를 대신 실행할 수 있습니다.
프로세스가 테스트 후 종료되지 않고 사용자가 프로세스를 닫을 때까지 대기합니다.
node run test -- --watch
or
node jest/scripts/test.js --watch
아래 답변을 받으시면 다 준비되었습니다!
끝내기
리액트 구성 요소의 유닛 테스트를 위한 환경 설정은 간단한 작업이 아니기 때문에 최종적으로 작동 방법을 파악한 단계를 기록하기로 했습니다.
안타깝게도, 시험지를 작성하는 것 또한 까다롭습니다. 어떻게 대처해야 할지 고민하는 재미가 있지만, 그래도 구체적인 시나리오를 테스트하기 위해 실제로 할 수 있는 것을 더 많이 얻을 수 있었으면 좋겠다. 그래서 저는 고민하면서 얻은 경험을 공유하기 위해 또 다른 글을 쓸 것입니다
'javascript' 카테고리의 다른 글
응답의 useContext() hook (0) | 2022.01.13 |
---|---|
노르웨이의 파손된 주택에 대한 예언적 시각(충만) (0) | 2022.01.13 |
C# en Unity para programadores/JavaScript처럼 (0) | 2022.01.13 |
그거 디버그해. (0) | 2022.01.13 |
JavaScript 개체 깊이 (1) | 2022.01.13 |
댓글