약자 전략의 Atomic Design 및 테스트 선정[React+TypeScript]
15059 단어 ReactTypeScriptAtomicDesign
저는 React와 TypeScript에 대한 경험이 많지 않습니다. 프로젝트에서 이런 것을 사용할 때 일정한 품질과 유지보수성을 보장할 수 있는 코드를 쓰기 위해 고려하는 것입니다.
품질 및 서비스 용이성
나는 품질과 보수성이라는 두 단어를 각각 다음과 같이 정리했다.
Atom Design이란 무엇입니까?
Atomic Design은 UI를 구성하는 요소를 원자에 비유하여 구현하는 UI 설계 방법 중 하나입니다.다음은 Atomic Design을 설명할 때 자주 나타나는 그림입니다.
(참조: http://atomicdesign.bradfrost.com/)
Atoms라는 최소 단위의 구성 요소를 조합하여 Pages(실제 페이지)로 만듭니다.
여기서부터 각 계층을 간단히 설명한다.
Atoms
UI 구성 요소의 최소 단위입니다.구성 요소에는 몇 가지 기능이 필요합니다.따라서 Atoms는 UI 기능을 손상시키지 않는 최소 요소라고 할 수 있습니다.
예: 입력, 버튼, 텍스트, 헤딩, 풍선, 카드, 휘장 등
Molecules
Atoms와 결합하여 사용자 동기의 기능 단위로 UI를 구성하는 것이 Molecules입니다.
예를 들어 검색 폼도 마찬가지다.어떤 키워드로 검색하고 싶은지 동기화하는 기능을 제공합니다.버튼, 텍스트 입력, 텍스트 세 개의 Atoms를 조합하여 만들 수 있습니다.
Organisms
Molecules와 Atoms를 사용합니다. 때로는 Organisms 층의 구성 요소 자체로 만든 구성 요소입니다.
Molecules는 사용자의 모든 취미에 기능을 제공하지만,Organisms층은 구성 요소로 완성된 내용을 제공합니다.
예를 들어'좋아요'를 누르면 숫자를 계산하는 Molecule를 프로필 아이콘 구성 요소와 글 구성 요소와 함께 놓으면'반응할 수 있는 사용자 투고 글'이라는 독립된 내용을 만들 수 있다.
Templates
이것은 Organisms, Molecules, Atoms 등 구성 요소를 실제 서비스와 같은 층으로 배치하는 데 사용된다.이 층의 목적은 구성 요소가 페이지에 정확하게 배치되었는지 확인하는 것이다.이 구성 요소를 사용하여 레이아웃을 테스트합니다.
Pages
어셈블리가 속한 레이어가 아니라 제품 자체입니다.실제 데이터를 템플릿에 입력합니다.
기쁜 일
지금 저는 이 Atomic Design에 따라 구성 요소를 실시하고 있습니다. 기쁜 일도 있지만 어려움도 있습니다.
재사용성이 높은 부품을 자연스럽게 제작할 수 있게 돼 기쁘다.또 설계 방침에 대한 이해를 바탕으로 논의할 수 있다.
만약 이런 방침이 없다면, "이것은 다른 구성 요소로 자르는 것이 좋겠다"는 토론만 진행할 수 있을 것이다.
번거로운 것은 현재 자신이 만든 구성 요소가 어느 층에 속하는지 때때로 망설이는 것이다.만약에 gog가 알면 Atomic Design을 사용하는 다른 기업의 엔지니어들도 그곳에서 다양한 어려움을 겪고 각자의 조직에서 공감대를 형성하여 추진하고 있다고 생각합니다.
Container Component 및 Presentational Component
Atomic Design의 입도에 따라 구성 요소를 제작할 때 각 구성 요소는 구성 요소의 관심사에 따라 구분할 수 있습니다.바로 Container Component와 Presentational Component입니다.
Container Component는 주로'어떻게 일하는가'에 주목하고 데이터를 획득, 가공, 성형한 후에 데이터를props로presentational Component에 전달한다.
Presentational Component는 주로'어떻게 보이는가'에 주목하고 대량의 DOM 태그를 가지고 있다.
이렇게 구성 요소의 흥미를 구분함으로써 미세한 외관 차이를 가진 구성 요소를 만들 때 다시 Container Component를 사용할 수 있다.const Container: FC<ContainerProps> = ({ addNumber, addedNumber, presenter }) => {
const sum = addedNumber + addNumber
presenter({ sum })
}
const Presenter: FC<PresenterProps> = ({ sum }) => <p>{sum}</p>
const UnderlinedPresenter: FC<{ sum: number }> = ({ sum }) => <p className="underlined">{sum}</p>
const UnderlinedComponent: FC<Props> = ({ addNumber, addedNumber }) => {
return <Container addNumber={addNumber} addedNumber={addedNumber} presenter={presenterProps => <UnderlinedPresenter {...presenterProps} />} />
}
테스트
다음은 상술한 설계 방침에 따라 제작된 구성 요소를 어떻게 테스트하는지 적어 보겠습니다.처음에 말한 바와 같이 품질과 보수성을 확보하기 위해 우리는 주로 다음과 같은 테스트를 쓴다.
Atomic Design의 입도에 따라 구성 요소를 제작할 때 각 구성 요소는 구성 요소의 관심사에 따라 구분할 수 있습니다.바로 Container Component와 Presentational Component입니다.
Container Component는 주로'어떻게 일하는가'에 주목하고 데이터를 획득, 가공, 성형한 후에 데이터를props로presentational Component에 전달한다.
Presentational Component는 주로'어떻게 보이는가'에 주목하고 대량의 DOM 태그를 가지고 있다.
이렇게 구성 요소의 흥미를 구분함으로써 미세한 외관 차이를 가진 구성 요소를 만들 때 다시 Container Component를 사용할 수 있다.
const Container: FC<ContainerProps> = ({ addNumber, addedNumber, presenter }) => {
const sum = addedNumber + addNumber
presenter({ sum })
}
const Presenter: FC<PresenterProps> = ({ sum }) => <p>{sum}</p>
const UnderlinedPresenter: FC<{ sum: number }> = ({ sum }) => <p className="underlined">{sum}</p>
const UnderlinedComponent: FC<Props> = ({ addNumber, addedNumber }) => {
return <Container addNumber={addNumber} addedNumber={addedNumber} presenter={presenterProps => <UnderlinedPresenter {...presenterProps} />} />
}
테스트
다음은 상술한 설계 방침에 따라 제작된 구성 요소를 어떻게 테스트하는지 적어 보겠습니다.처음에 말한 바와 같이 품질과 보수성을 확보하기 위해 우리는 주로 다음과 같은 테스트를 쓴다.
논리 테스트
논리 테스트 테스트는 방금 설명한 Container Component가 담당하는 논리 부분을 테스트합니다.Jest를 사용합니다.
앞의 코드를 보고 눈치챈 사람도 있을 것 같습니다. 주로 제가 속한 항목은 클래스 구성 요소가 아니라 함수 구성 요소로 썼기 때문에 되돌아오는 값을 확인하기 위해presenter의props를 보는 형식으로 테스트를 진행했습니다.
describe('HogeContainer', () => {
const presenter: FC<PresenterProps> = props => {
return <React.Component {...props} />
}
it('returns sum', () => {
const { sum } = Container({ 1, 3, presenter })
expect(sum).toBe(4)
})
}
상호 테스트
상호작용 테스트 시뮬레이션과 사용자 상호작용 검사.Enzyme를 사용하여 Shallow 렌더링 (하위 구성 요소를 모크로 대체하여 렌더링) 을 수행하고 입력한 함수 등을 테스트합니다.
describe('HogeComponent', () => {
it('callbacks on mouse functions', () => {
const mockMouseEnter = jest.fn()
const mockMouseLeave = jest.fn()
const wrapper = mount(
<Hoge
onMouseEnter={mockMouseEnter}
onMouseLeave={mockMouseLeave}
/>
)
wrapper
.find('div span')
.at(1)
.simulate('mouseenter')
wrapper
.find('div span')
.at(1)
.simulate('mouseleave')
expect(onMouseEnter.mock.calls.length).toBe(1)
expect(onMouseLeave.mock.calls.length).toBe(1)
})
})
E2E 테스트
E2E 테스트는 jest-puppeteer를 사용하기로 결정했습니다.
const timeout = 5000
describe('/ (Home Page)', () => {
let page
beforeAll(async () => {
page = await global.__BROWSER__.newPage()
await page.goto('https://google.com')
}, timeout)
it('should load without error', async () => {
const text = await page.evaluate(() => document.body.textContent)
expect(text).toContain('google')
});
},
timeout,
)
참조: https://jestjs.io/docs/ja/puppeteer마지막
급하지만 저처럼 경험이 부족한 엔지니어도 일정한 수량의 품질과 유지보수성을 보장하는 구조로서의 Atomic 설계와 테스트를 썼습니다.
시간이 없어서 자세히 못 썼는데 테스트를 쓰면 한마디라도 하나씩 쓰고 싶지 않으면 이중으로 설치하는 느낌이 든다.나는 이 부근이 경험을 쌓으면서 똑똑히 볼 수 있다면 속도와 품질, 보수성이 높아질 것이라고 생각한다.
나의 보도는 여기서 끝난다.
내일은tatsuo48씨의 보도입니다!
Reference
이 문제에 관하여(약자 전략의 Atomic Design 및 테스트 선정[React+TypeScript]), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/sasumasax/items/05a8235a9ae9b098d331
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(약자 전략의 Atomic Design 및 테스트 선정[React+TypeScript]), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/sasumasax/items/05a8235a9ae9b098d331텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)