프론트엔드 테스트를 위한 테스트 파이프라인 101
게시 됨: 2022-03-10이 상황을 상상해 보십시오. 마감 시간이 빠르게 다가오고 있으며 CSS 파일을 많이 변경하여 이 복잡한 리팩토링을 완료하려는 목표를 달성하기 위해 모든 여유 시간을 사용하고 있습니다. 버스를 타는 동안 마지막 단계까지 작업하고 있습니다. 그러나 로컬 테스트는 매번 실패하는 것 같고 작동하도록 할 수 없습니다. 스트레스 수준이 높아지고 있습니다.
잘 알려진 시리즈에도 비슷한 장면이 있습니다. Netflix TV 시리즈 "How to Sell Drugs Online(Fast)"의 세 번째 시즌입니다.
Cypress + Vue 특집 *ON A NETFLIX TV SHOW*
— jess (@_jessicasachs) 2021년 8월 7일
"마약 파는 법(빠른)"이라는 코미디로 webdev를 가장 사실적으로 묘사했습니다.
시즌 3, 에피소드 1 @ 20:20 그리고 그 전에 한두 번. pic.twitter.com/ICSAwxyFB
글쎄, 그는 적어도 테스트를 사용하고 있다고 생각할 수 있습니다. 그는 왜 여전히 곤경에 처해 있는지 궁금할 것입니다. 테스트를 작성하더라도 이러한 상황을 방지하고 개선할 여지가 여전히 많습니다. 처음부터 코드베이스와 모든 변경 사항을 모니터링하는 것에 대해 어떻게 생각하십니까? 결과적으로 그런 불쾌한 놀라움을 경험하지 않을 것입니다. 그렇죠? 자동화된 테스트 루틴을 포함하는 것은 그리 어렵지 않습니다. 이 테스트 파이프라인을 처음부터 끝까지 함께 만들어 봅시다.
갑시다!
가장 먼저 해야 할 일: 기본 용어
빌드 루틴은 소규모 프로젝트에서도 더 복잡한 리팩토링에 대한 확신을 유지하는 데 도움이 될 수 있습니다. 하지만 그렇다고 해서 DevOps 엔지니어가 되어야 하는 것은 아닙니다. 몇 가지 용어와 전략을 배우는 것이 중요합니다. 그게 바로 당신이 여기 온 이유입니다. 맞죠? 다행히도 올바른 위치에 있습니다! 프론트엔드 프로젝트의 테스트 파이프라인을 다룰 때 곧 접하게 될 기본 용어부터 시작하겠습니다.
일반적으로 테스트의 세계를 검색하는 경우 "CI/CD"라는 용어를 첫 번째 용어 중 하나로 이미 우연히 발견했을 수 있습니다. "Continuous Integration, Continuous Delivery" 및 "Continuous Deployment"의 줄임말로 정확히 다음과 같이 설명합니다. 이미 들었을 것입니다. 이는 개발 팀에서 코드 변경 사항을 보다 자주, 안정적으로 배포하는 데 사용하는 소프트웨어 배포 방법입니다. CI/CD에는 자동화에 크게 의존하는 두 가지 보완적인 접근 방식이 포함됩니다.
- 지속적인 통합
소규모의 정기적인 코드 변경을 구현하고 이를 공유 저장소에 병합하기 위한 자동화 조치에 대한 용어입니다. 지속적인 통합에는 코드를 빌드하고 테스트하는 단계가 포함됩니다.
CD는 "Continuous Delivery"와 "Continuous Deployment"의 약자로 서로 비슷하지만 때로는 다른 맥락에서 사용되는 개념입니다. 둘의 차이점은 자동화 범위에 있습니다.
- 지속적 전달
운영 팀이 이제 라이브 프로덕션 환경에서 코드를 배포할 수 있는 이전에 이미 테스트된 코드 프로세스를 나타냅니다. 이 마지막 단계는 수동일 수 있습니다. - 지속적인 배포
이름에서 알 수 있듯이 "배포" 측면에 중점을 둡니다. 리포지토리 권한에서 프로덕션에 이르기까지 개발자 변경 사항을 완전히 자동화된 릴리스 프로세스로, 고객이 직접 사용할 수 있는 용어입니다.
이러한 프로세스는 개발자와 팀이 원하는 경우 언제든지 릴리스할 수 있는 제품을 가질 수 있도록 하는 것을 목표로 합니다. 지속적으로 모니터링, 테스트 및 배포된 응용 프로그램에 대한 확신.
잘 설계된 CI/CD 전략을 달성하기 위해 대부분의 사람과 조직은 "파이프라인"이라는 프로세스를 사용합니다. "파이프라인"은 설명 없이 이미 이 가이드에서 사용한 단어입니다. 이러한 파이프라인에 대해 생각하면 가스와 같은 것을 운송하기 위한 장거리 라인 역할을 하는 튜브에 대해 생각하는 것이 너무 무리가 아닙니다. DevOps 영역의 파이프라인은 매우 유사하게 작동합니다. 배포할 소프트웨어를 "전송"합니다.
배우고 기억해야 할 것들이 참 많은 것 같죠? 우리가 테스트에 대해 이야기하지 않았습니까? 당신이 옳았습니다. CI/CD 파이프라인의 완전한 개념을 다루면 여러 기사에 충분한 콘텐츠를 제공할 수 있으며 소규모 프론트 엔드 프로젝트에 대한 테스트 파이프라인을 처리하고자 합니다. 또는 파이프라인의 테스트 측면만 놓치고 있어 지속적인 통합 프로세스에만 집중하고 있습니다. 따라서 특히 파이프라인의 "테스트" 부분에 중점을 둘 것입니다. 따라서 이 가이드에서는 "작은" 테스트 파이프라인을 만들 것입니다.
자, "테스트 부분"이 우리의 주요 초점입니다. 이런 맥락에서 어떤 테스트가 이미 알고 있고 언뜻 생각나나요? 이런 식으로 테스트하는 것에 대해 생각하면 다음과 같은 유형의 테스트가 자연스럽게 생각납니다.
- 단위 테스트 는 단위라고 하는 응용 프로그램의 사소한 테스트 가능한 부분 또는 단위가 적절한 작동을 위해 개별적이고 독립적으로 테스트되는 일종의 테스트입니다.
- 통합 테스트 는 구성 요소 또는 시스템 간의 상호 작용에 중점을 둡니다. 이러한 종류의 테스트는 우리가 유닛의 상호 작용과 함께 작동하는 방식을 확인하고 있음을 의미합니다.
- 종단 간 테스트 또는 E2E 테스트는 실제 사용자 상호 작용이 컴퓨터에 의해 시뮬레이션됨을 의미합니다. 그렇게 함으로써 E2E 테스트는 가능한 한 많은 기능 영역과 애플리케이션에서 사용되는 기술 스택의 일부를 포함해야 합니다.
- Visual Testing 은 애플리케이션의 가시적 출력을 확인하고 예상 결과와 비교하는 프로세스입니다. 즉, 순전히 기능적인 버그와 다른 페이지나 화면의 모양에서 "시각적 버그"를 찾는 데 도움이 됩니다.
- 정적 분석 은 정확히 테스트하는 것은 아니지만 여기에서 언급하는 것이 필수적이라고 생각합니다. 맞춤법 수정처럼 작동한다고 상상할 수 있습니다. 프로그램을 실행하지 않고 코드를 디버그하고 코드 스타일 문제를 감지합니다. 이 간단한 조치로 많은 버그를 예방할 수 있습니다.
우리의 고유한 프로젝트에서 대규모 리팩토링을 병합하는 데 확신을 가지려면 테스트 파이프라인에서 이러한 모든 테스트 유형을 사용하는 것을 고려해야 합니다. 그러나 시작은 곧 좌절로 이어집니다. 이러한 테스트 유형을 평가하는 데 길을 잃을 수도 있습니다. 어디서부터 시작해야 하나요? 어떤 유형의 테스트가 몇 개나 합리적인가요?
전략: 피라미드와 트로피
파이프라인을 구축하기 전에 테스트 전략을 수립해야 합니다. 이전에 이러한 모든 질문에 대한 답변을 검색하면 몇 가지 비유에서 가능한 해결책을 찾을 수 있습니다. 웹과 특히 테스트 커뮤니티에서 사람들은 유추를 사용하여 어떤 유형의 테스트를 얼마나 많이 사용해야 하는지에 대한 아이디어를 제공하는 경향이 있습니다.
가장 먼저 접하게 될 은유는 테스트 자동화 피라미드입니다. Mike Cohn은 Martin Fowler가 "Practical Test Pyramid"로 추가 개발한 그의 책 "Succeeding with Agile"에서 이 개념을 제시했습니다. 다음과 같이 보입니다.
보시다시피, 제시된 세 가지 테스트 수준에 해당하는 세 가지 수준으로 구성되어 있습니다. 피라미드는 테스트 전략을 개발하는 동안 안내하기 위해 다양한 테스트의 올바른 조합을 명확히 하기 위한 것입니다.
- 단위
이러한 테스트는 실행이 빠르고 유지 관리가 간편하기 때문에 피라미드의 기본 계층에서 찾을 수 있습니다. 이것은 그들의 고립과 그들이 가장 작은 단위를 목표로 한다는 사실 때문입니다. 매우 작은 제품을 테스트하는 일반적인 단위 테스트의 예는 이것을 참조하십시오. - 완성
이것들은 실행 속도에 관해서는 여전히 수용 가능하지만 단위 테스트보다 사용자에게 더 가깝다는 확신을 제공하기 때문에 피라미드의 한가운데에 있습니다. 통합 유형 테스트의 예로는 API 테스트가 있으며 구성 요소 테스트도 이 유형으로 간주될 수 있습니다. - E2E 테스트 ( UI 테스트 라고도 함)
우리가 보았듯이 이러한 테스트는 실제 사용자와 상호 작용을 시뮬레이션합니다. 이러한 테스트는 실행하는 데 더 많은 시간이 필요하므로 피라미드의 맨 위에 배치되는 더 많은 비용이 듭니다. E2E 테스트의 일반적인 예를 살펴보고 싶다면 여기로 이동하세요.
그러나 최근 몇 년 동안 이 은유는 시대에 뒤떨어진 것처럼 느껴졌습니다. 그 결점 중 하나는 특히 나에게 매우 중요합니다. 이 전략에서는 정적 분석을 우회합니다. 내 의견으로는 코드 스타일 수정 프로그램이나 다른 린트 솔루션의 사용은 이 비유에서 고려되지 않은 큰 결함입니다. Lint 및 기타 정적 분석 도구는 사용 중인 파이프라인의 필수적인 부분이므로 무시해서는 안 됩니다.
따라서 이만 줄이겠습니다. 더 업데이트된 전략을 사용해야 합니다. 그러나 린트 도구가 없는 것이 유일한 결함은 아닙니다. 고려해야 할 더 중요한 사항이 있습니다. 대신에 초점을 약간 변경할 수 있습니다. 다음 인용문은 이를 매우 잘 요약합니다.
"테스트를 작성하십시오. 너무 많지 않습니다. 대부분 통합”이라고 말했다.
— 기예르모 라우흐
이에 대해 알아보기 위해 이 인용문을 분석해 보겠습니다.
- 테스트 작성
아주 자명합니다. 항상 테스트를 작성해야 합니다. 테스트는 사용자와 개발자 모두에게 애플리케이션 내부에 신뢰를 심어주는 데 중요합니다. 자신을 위해서라도! - 너무 많지 않아
무작위로 테스트를 작성하면 아무데도 얻을 수 없습니다. 테스트 피라미드는 테스트의 우선 순위를 유지하기 위해 성명서에서 여전히 유효합니다. - 대부분 통합
피라미드가 무시하는 더 "비싼" 테스트의 비장의 카드는 피라미드 위로 올라갈수록 테스트에 대한 신뢰도가 높아진다는 것입니다. 이러한 증가는 사용자와 개발자 자신 모두가 이러한 테스트를 신뢰할 가능성이 가장 높다는 것을 의미합니다.
이것은 설계상 사용자에게 더 가까운 테스트를 진행해야 함을 의미합니다. 결과적으로 더 많은 비용을 지불할 수 있지만 많은 가치를 되돌려 받을 수 있습니다. E2E 테스트를 선택하지 않는 이유가 궁금할 것입니다. 유저를 흉내내고 있으니 애초에 유저와 가장 가깝지 않은가? 이것은 사실이지만 여전히 실행 속도가 훨씬 느리고 전체 애플리케이션 스택이 필요합니다. 따라서 이러한 투자 수익은 통합 테스트보다 나중에 달성됩니다. 결과적으로 통합 테스트는 한편으로는 신뢰와 다른 한편으로는 속도와 노력 사이에서 공정한 균형을 제공합니다.
Kent C.Dodds를 따르면 이러한 주장이 친숙하게 들릴 수 있습니다. 특히 그가 쓴 이 기사를 읽으면 더욱 그렇습니다. 이러한 주장은 우연이 아닙니다. 그는 자신의 작업에서 새로운 전략을 제시했습니다. 나는 그의 요점에 강력하게 동의하며 여기에서 가장 중요한 것을 리소스 섹션에서 다른 것을 연결합니다. 그가 제안한 접근 방식은 테스트 피라미드에서 유래하지만 통합 테스트에서 더 높은 우선 순위를 반영하도록 모양을 변경하여 다른 수준으로 끌어 올립니다. "테스트 트로피"라고 합니다.
테스트 트로피는 테스트의 세분성을 약간 다른 방식으로 묘사하는 은유입니다. 테스트를 다음 테스트 유형으로 배포해야 합니다.
- 정적 분석 은 이 은유에서 중요한 역할을 합니다. 이렇게 하면 언급된 디버깅 단계를 실행하여 오타, 유형 오류 및 기타 버그를 잡을 수 있습니다.
- 단위 테스트 는 가장 작은 단위가 적절하게 테스트되었는지 확인해야 하지만 테스트 트로피는 테스트 피라미드와 같은 정도로 강조하지 않습니다.
- 통합 은 비용과 더 높은 신뢰도의 균형을 유지하는 가장 좋은 방법이므로 주요 초점입니다.
- E2E 및 Visual 테스트를 포함한 UI 테스트 는 테스트 피라미드에서의 역할과 유사하게 테스트 트로피의 맨 위에 있습니다.
저는 대부분의 프로젝트에서 이 테스트 트로피 전략을 사용했으며 이 가이드에서도 계속 그렇게 할 것입니다. 그러나 여기에서 약간의 면책 조항을 제공해야 합니다. 물론, 제 선택은 일상 생활에서 작업 중인 프로젝트를 기반으로 합니다. 따라서 일치하는 테스트 전략의 이점과 선택은 항상 작업 중인 프로젝트에 따라 다릅니다. 따라서 귀하의 요구에 맞지 않더라도 기분이 상하지 마십시오. 해당 단락의 다른 전략에 리소스를 추가하겠습니다.
사소한 스포일러 경고: 곧 보게 되겠지만 어떤 면에서는 이 개념에서도 약간 벗어나야 합니다. 그러나 나는 그것이 괜찮다고 생각하지만, 우리는 그것에 대해 조금 후에 알게 될 것입니다. 내 요점은 파이프라인을 계획하고 구현하기 전에 테스트 유형의 우선 순위 지정 및 배포에 대해 생각하는 것입니다.
이러한 파이프라인을 온라인으로 구축하는 방법(빠른)
Netflix TV 시리즈 "How To Sell Drugs Online(Fast)" 시즌 3의 주인공은 마감일이 임박한 동안 Cypress를 사용하여 E2E 테스트를 수행하는 것으로 표시되지만 실제로는 로컬 테스트에 불과했습니다. CI/CD가 보이지 않아 불필요한 스트레스를 받았습니다. 우리는 우리가 배운 이론으로 해당 에피소드에서 주어진 주인공의 압력을 피해야합니다. 그러나 이러한 학습을 현실에 어떻게 적용할 수 있습니까?
먼저 테스트 기반으로 코드베이스가 필요합니다. 이상적으로는 많은 프론트엔드 개발자가 접하게 될 프로젝트여야 합니다. 그 사용 사례는 실습 접근 방식에 적합하고 테스트 파이프라인을 처음부터 구현할 수 있도록 하는 빈번한 사용 사례여야 합니다. 그러한 프로젝트가 무엇입니까?
기본 파이프라인에 대한 나의 제안
내 마음에 가장 먼저 떠오른 것은 자명합니다. 내 웹사이트, 즉 내 포트폴리오 페이지는 우리의 열망하는 파이프라인에서 테스트할 예제 코드베이스로 간주하기에 매우 적합합니다. Github에 오픈소스로 공개되어 있어 자유롭게 보고 사용하실 수 있습니다. 사이트의 기술 스택에 대한 몇 마디: 기본적으로 저는 이 사이트를 추가 웹 프레임워크로 Nuxt.js를 사용하여 JavaScript 프레임워크로 Vue.js(불행히도 이 기사를 작성할 당시 버전 2에 있었습니다)에 구축했습니다. GitHub 리포지토리에서 전체 구현 예를 찾을 수 있습니다.
예제 코드베이스를 선택한 상태에서 학습 내용을 적용하기 시작해야 합니다. 테스트 트로피를 테스트 전략의 출발점으로 사용하고 싶다는 사실을 감안할 때 다음과 같은 개념을 생각해 냈습니다.
상대적으로 작은 코드베이스를 다루기 때문에 단위 및 통합 테스트의 일부를 병합하겠습니다. 하지만 그렇게 하는 것은 단지 하나의 작은 이유일 뿐입니다. 다른 더 중요한 이유는 다음과 같습니다.
- 단위의 정의는 종종 "토론 대상"입니다. 개발자 그룹에 단위 정의를 요청하면 대부분 다양하고 다른 대답을 얻을 것입니다. 일부는 기능, 클래스 또는 서비스(소단위)를 참조하므로 다른 개발자는 완전한 구성 요소에 포함됩니다.
- 이러한 정의의 어려움 외에도 단위와 통합 사이의 선을 그리는 것은 매우 흐릿하기 때문에 까다로울 수 있습니다. 테스트 기반을 성공적으로 검증하기 위해 종종 DOM이 필요하기 때문에 이 어려움은 특히 프론트엔드의 경우 현실적입니다.
- 일반적으로 동일한 도구와 라이브러리를 사용하여 두 통합 테스트를 모두 작성할 수 있습니다. 따라서 리소스를 병합하여 리소스를 절약할 수 있습니다.
선택 도구: GitHub 작업
파이프라인 내부에서 무엇을 그리고 싶은지 알고 있으므로 다음 단계는 CI/CD(지속적 통합 및 전달) 플랫폼을 선택하는 것입니다. 우리 프로젝트를 위해 그러한 플랫폼을 선택할 때 나는 이미 경험을 얻은 다음을 생각합니다.
- GitLab은 내 직장의 일상으로,
- 대부분의 사이드 프로젝트에서 GitHub 작업.
그러나 선택할 수 있는 다른 플랫폼이 많이 있습니다. 호환성 문제가 발생하지 않도록 사용된 기술과 프레임워크를 고려 하여 항상 프로젝트와 특정 요구 사항에 따라 선택하는 것이 좋습니다. 기억하세요. 우리는 이미 GitHub에 릴리스된 Vue 2 프로젝트를 사용하며, 우연히도 제 이전 경험과 일치합니다. 또한 언급된 GitHub 작업은 시작점으로 프로젝트의 GitHub 리포지토리만 필요합니다. 특별히 GitHub Actions 워크플로를 만들고 실행합니다. 결과적으로 이 가이드에서는 GitHub Actions를 사용하겠습니다.
따라서 이러한 GitHub 작업은 특정 이벤트가 발생하는 경우 특별히 정의된 워크플로를 실행할 수 있는 플랫폼을 제공합니다. 이러한 이벤트는 워크플로를 트리거하는 저장소의 특정 활동입니다(예: 분기에 변경 사항 푸시). 이 가이드에서 이러한 이벤트는 CI/CD에 연결되지만 이러한 워크플로는 풀 요청에 레이블을 추가하는 것과 같은 다른 워크플로도 자동화할 수 있습니다. GitHub는 Windows, Linux 및 macOS 가상 머신에서 실행할 수 있습니다.
이러한 워크플로를 시각화하려면 다음과 같습니다.
이 기사에서는 하나의 워크플로를 사용하여 하나의 파이프라인을 설명합니다. 즉, 하나의 워크플로에 정적 분석에서 모든 종류의 UI 테스트에 이르기까지 모든 테스트 단계가 포함됩니다. 다음 단락에서 "워크플로"라고 하는 이 파이프라인은 동일한 실행기에서 실행되는 단계 집합인 하나 이상의 작업으로 구성됩니다.
이 워크플로는 바로 위 그림에서 스케치하고 싶었던 구조입니다. 여기에서 우리는 여러 작업을 포함하는 이러한 러너를 자세히 살펴봅니다. 작업 자체의 단계는 다른 단계로 구성됩니다. 이러한 단계는 다음 두 가지 유형 중 하나일 수 있습니다.
- 단계는 간단한 스크립트를 실행할 수 있습니다.
- 단계는 조치를 실행할 수 있습니다. 이러한 작업은 재사용 가능한 확장이며 종종 완전한 사용자 지정 응용 프로그램입니다.
이를 염두에 두고 GitHub 작업의 실제 워크플로는 다음과 같습니다.
최초의 GitHub 작업 작성
마지막으로, 첫 번째 Github 작업을 작성하고 코드를 작성할 수 있습니다! 기본 워크플로와 묘사하려는 작업의 첫 번째 개요로 시작합니다. 테스트 트로피를 기억하면 모든 작업은 테스트 트로피의 한 레이어와 비슷할 것입니다. 이러한 단계는 해당 계층을 자동화하기 위해 수행해야 하는 작업입니다.
따라서 먼저 워크플로를 저장할 .github/workflows/
디렉터리를 만듭니다. 이 디렉토리 안에 테스트 워크플로를 포함하기 위해 tests.yml
이라는 새 파일을 만듭니다. 위 그림에 표시된 표준 워크플로 구문과 함께 다음과 같이 진행합니다.
- 워크플로의 이름을
Tests CI
로 지정하겠습니다. - 원격 분기에 푸시할 때마다 워크플로를 실행하고 파이프라인을 시작하는 수동 옵션을 제공하고 싶기 때문에
push
및workflow_dispatch
에서 실행되도록 워크플로를 구성하겠습니다. - 마지막으로 "기본 파이프라인에 대한 내 제안" 단락에 명시된 대로 내 워크플로에는 세 가지 작업이 포함됩니다.
-
static-eslint
; - 하나의 작업에 병합된 단위 및 통합 테스트를 위한
unit-integration-jest
; - 기본 E2E 테스트 및 시각적 회귀 테스트를 포함한 UI 단계로
ui-cypress
.
-
- Linux 기반 가상 머신은 모든 작업을 실행해야 하므로
ubuntu-latest
를 사용하겠습니다.
YAML
파일의 올바른 구문을 입력하면 워크플로의 첫 번째 개요가 다음과 같을 수 있습니다.
name: Tests CI on: [push, workflow_dispatch] # On push and manual jobs: static-eslint: runs-on: ubuntu-latest steps: # 1 steps unit-integration-jest: runs-on: ubuntu-latest steps: # 1 step ui-cypress: runs-on: ubuntu-latest steps: # 2 steps: e2e and visual
GitHub 작업의 워크플로에 대한 세부 정보를 보려면 언제든지 해당 설명서로 이동하십시오. 어느 쪽이든, 당신은 의심의 여지없이 단계가 여전히 누락되어 있음을 알고 있습니다. 걱정하지 마십시오. 저도 알고 있습니다. 따라서 이 워크플로 개요를 생생하게 채우려면 해당 단계를 정의하고 소규모 포트폴리오 프로젝트에 사용할 테스트 도구와 프레임워크를 결정해야 합니다. 앞으로 나올 모든 단락은 각각의 작업을 설명하고 해당 테스트의 자동화를 가능하게 하는 몇 가지 단계를 포함합니다.
정적 분석
테스트 트로피에서 알 수 있듯이 워크플로에서 린터 및 기타 코드 스타일 수정 프로그램으로 시작합니다. 이러한 맥락에서 다양한 도구 중에서 선택할 수 있으며 다음과 같은 몇 가지 예가 있습니다.
- 자바스크립트 코드 스타일 해결사로서의 Eslint.
- CSS 코드 수정을 위한 Stylelint.
- 예를 들어 코드 복잡성을 분석하기 위해 scrutinizer와 같은 도구를 볼 수 있습니다.
이러한 도구는 패턴 및 규칙의 오류를 지적한다는 공통점이 있습니다. 그러나 이러한 규칙 중 일부는 취향의 문제입니다. 얼마나 엄격하게 적용할지 결정하는 것은 사용자의 몫입니다. 예를 들어 두 개 또는 네 개의 탭 들여쓰기를 허용하려는 경우입니다. 일관된 코드 스타일을 요구하고 "==" 대 "==="를 사용하는 것과 같이 더 심각한 오류 원인을 파악하는 데 집중하는 것이 훨씬 더 중요합니다.
우리의 포트폴리오 프로젝트와 이 가이드에서는 우리가 자바스크립트를 많이 사용하기 때문에 Eslint 설치를 시작하고 싶습니다. 다음 명령으로 설치하겠습니다.
npm install eslint --save-dev
물론 NPM을 사용하지 않으려면 Yarn 패키지 관리자와 함께 대체 명령을 사용할 수도 있습니다. 설치 후 .eslintrc.json
이라는 구성 파일을 생성해야 합니다. 이 기사에서는 처음부터 Eslint를 구성하는 방법을 가르치지 않을 것이기 때문에 지금은 기본 구성을 사용하겠습니다.
{ "extends": [ "eslint:recommended", ] }
Eslint 구성에 대해 자세히 알고 싶다면 이 가이드를 참조하세요. 다음으로 Eslint 실행을 자동화하기 위한 첫 번째 단계를 수행하려고 합니다. 먼저 Eslint를 NPM 스크립트로 실행하는 명령을 설정하고 싶습니다. script
섹션의 package.json
파일에서 이 명령을 사용하여 이 작업을 수행합니다.
"scripts": { "lint": "eslint --ext .js .", },
그런 다음 GitHub 워크플로에서 새로 생성된 스크립트를 실행할 수 있습니다. 그러나 그렇게 하기 전에 프로젝트를 사용할 수 있는지 확인해야 합니다. 따라서 사전 구성된 GitHub Action actions/checkout@v2
를 사용합니다. 이 작업은 정확히 다음을 수행합니다. GitHub 작업의 워크플로가 액세스할 수 있도록 프로젝트를 체크아웃합니다. 다음 단계는 내 포트폴리오 프로젝트에 필요한 모든 NPM 종속성을 설치하는 것입니다. 그 후, 마침내 eslint 스크립트를 실행할 준비가 되었습니다! Linting을 사용하는 최종 작업은 다음과 같습니다.
static-eslint: runs-on: ubuntu-latest steps: # Action to check out my codebase - uses: actions/checkout@v2 # install NPM dependencies - run: npm install # Run lint script - run: npm run lint
이제 npm run lint
때 이 파이프라인이 자동으로 "실패"하는지 궁금할 것입니다. 예, 기본적으로 작동합니다. 워크플로 작성이 완료되는 즉시 Github에서 스크린샷을 살펴보겠습니다.
단위 및 통합
다음으로 단위 및 통합 단계가 포함된 작업을 생성하겠습니다. 이 글에서 사용된 프레임워크와 관련하여 프론트엔드 테스트를 위한 Jest 프레임워크를 소개하고자 합니다. 물론 원하지 않는다면 Jest를 사용할 필요가 없습니다. 선택할 수 있는 대안이 많이 있습니다.
- Cypress는 또한 통합 테스트에 적합한 구성 요소 테스트를 제공합니다.
- Jasmine도 살펴볼 또 다른 프레임워크입니다.
- 그리고 더 많은 것이 있습니다. 나는 단지 몇 가지 이름을 말하고 싶었습니다.
Jest는 Facebook에서 오픈 소스로 제공합니다. 프레임워크는 Vue.js, React 또는 Angular를 포함한 많은 JavaScript 프레임워크 및 프로젝트와 호환되는 동시에 단순성에 중점을 둡니다. TypeScript와 함께 jest를 사용할 수도 있습니다. 이것은 특히 내 소규모 포트폴리오 프로젝트에 대해 프레임워크를 매우 흥미롭게 만듭니다. 호환 가능하고 적합하기 때문입니다.
다음 명령을 입력하여 내 포트폴리오 프로젝트의 이 루트 폴더에서 Jest 설치를 직접 시작할 수 있습니다.
npm install --save-dev jest
설치 후 이미 테스트 작성을 시작할 수 있습니다. 그러나 이 문서에서는 Github 작업을 사용하여 이러한 테스트를 자동화하는 데 중점을 둡니다. 따라서 단위 또는 통합 테스트를 작성하는 방법을 배우려면 다음 가이드를 참조하십시오. 워크플로에서 작업을 설정할 때 static-eslint
작업과 유사하게 진행할 수 있습니다. 따라서 첫 번째 단계는 나중에 작업에 사용할 작은 NPM 스크립트를 다시 만드는 것입니다.
"scripts": { "test": "jest", },
그 후에 우리는 이전에 린터에 대해 이미 했던 것과 유사하게 unit-integration-jest
라는 작업을 정의할 것입니다. 따라서 워크플로에서 프로젝트를 확인합니다. 그 외에도 첫 번째 static-eslint
작업에 두 가지 약간의 차이점을 사용합니다.
- Node.js를 설치하는 단계로 작업을 사용합니다.
- 그런 다음 새로 만든 npm 스크립트를 사용하여 Jest 테스트를 실행합니다.
이런 식으로 unit-integration-jest
작업은 다음과 같이 보일 것입니다.
unit-integration-jest: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 # Set up node - name: Run jest uses: actions/setup-node@v1 with: node-version: '12' - run: npm install # Run jest script - run: npm test
UI 테스트: E2E 및 시각적 테스트
마지막으로 E2E 테스트와 시각적 테스트를 모두 포함하는 ui-cypress
작업을 작성할 것입니다. 둘 다에 대해 Cypress 프레임워크를 사용할 것이기 때문에 이 두 가지를 한 작업에 결합하는 것이 좋습니다. 물론 아래의 NightwatchJS 및 CodeceptJS와 같은 다른 프레임워크를 고려할 수 있습니다.
다시 말하지만, GitHub 워크플로에서 설정하기 위한 기본 사항만 다룰 것입니다. Cypress 테스트를 자세히 작성하는 방법을 배우고 싶다면 다른 가이드가 이를 정확하게 다루는 방법을 알려 드리겠습니다. 이 문서는 E2E 테스트 단계를 정의하는 데 필요한 모든 것을 안내합니다. 좋습니다. 먼저 루트 폴더에서 다음 명령을 사용하여 다른 프레임워크와 동일한 방식으로 Cypress를 설치합니다.
npm install --save-dev cypress
이번에는 NPM 스크립트를 정의할 필요가 없습니다. Cypress는 이미 사용할 자체 GitHub 작업인 cypress-io/github-action@v2
를 제공합니다. 거기에서 실행을 위해 몇 가지만 구성하면 됩니다.
- E2E 테스트에는 사용 가능한 전체 애플리케이션 스택이 필요하므로 애플리케이션이 완전히 설정되고 작동하는지 확인해야 합니다.
- 내부에서 E2E 테스트를 실행하는 브라우저의 이름을 지정해야 합니다.
- 컴퓨터가 실제 사용자처럼 작동할 수 있도록 웹 서버가 완전히 작동할 때까지 기다려야 합니다.
다행히도 Cypress 작업은 with
영역을 사용하여 이러한 모든 구성을 저장하는 데 도움이 됩니다. 이렇게 하면 현재 GitHub 작업이 다음과 같이 보입니다.
steps: - name: Checkout uses: actions/checkout@v2 # Install NPM dependencies, cache them correctly # and run all Cypress tests - name: Cypress Run uses: cypress-io/github-action@v2 with: browser: chrome headless: true # Setup: Nuxt-specific things build: npm run generate start: npm run start wait-on: 'http://localhost:3000'
시각적 테스트: 테스트에 눈을 떼지 마십시오.
이 가이드를 작성하려는 첫 번째 의도를 기억하십시오. SCSS 파일에 많은 변경 사항이 포함된 중요한 리팩토링이 있습니다. 테스트를 빌드 루틴의 일부로 추가하여 다른 것이 손상되지 않았는지 확인하고 싶습니다. 정적 분석, 단위, 통합 및 E2E 테스트가 있으므로 우리는 꽤 자신감이 있어야 합니다. 그렇죠? 사실이지만 파이프라인을 더욱 완벽하고 완벽하게 만들기 위해 내가 할 수 있는 일이 여전히 있습니다. 크리머가 되고 있다고 할 수 있습니다. 특히 CSS 리팩토링을 다룰 때 E2E 테스트는 제한된 도움만 될 수 있습니다.
다행스럽게도 작성된 명령과 개념과 별개로 버그를 잡는 또 다른 방법이 있습니다. 이를 시각적 테스트라고 합니다. 이런 종류의 테스트는 차이를 구분하는 퍼즐과 같다고 상상할 수 있습니다. 엄밀히 말하면, 시각적 테스트는 애플리케이션의 스크린샷을 찍어 현재 상태(예: 프로젝트의 주요 분기)와 비교하는 스크린샷 비교입니다. 이렇게 하면 최소한 시각적 테스트를 사용하는 영역에서 우발적인 스타일링 문제가 눈에 띄지 않게 됩니다. 이것은 적어도 내 경험에 비추어 볼 때 시각적 테스트를 대규모 CSS 리팩토링의 생명의 은인으로 바꿀 수 있습니다.
선택할 수 있는 많은 시각적 테스트 도구가 있으며 살펴볼 가치가 있습니다.
- 이 가이드에 사용하고 있는 Browserstack의 도구인 Percy.io;
- SaaS 솔루션을 사용하지 않고 동시에 완전히 오픈 소스로 전환하는 것을 선호하는 경우 Visual Regression Tracker;
- AI를 지원하는 Applitools. Smashing 매거진에 이 도구에 대한 흥미로운 가이드가 있습니다.
- Chromatic by Storybook.
이 가이드와 기본적으로 내 포트폴리오 프로젝트의 경우 시각적 테스트를 위해 기존 Cypress 테스트를 재사용하는 것이 중요했습니다. 이전에 언급했듯이 통합이 간단하기 때문에 이 예제에서는 Percy를 사용합니다. SaaS 솔루션이지만 아직 오픈소스로 제공되는 부분이 많고 오픈소스나 기타 사이드 프로젝트에 충분한 무료 플랜도 있다. 그러나 오픈 소스 도구를 사용하면서 완전히 자체 호스팅되는 것이 더 편하다면 Visual Regression Tracker를 사용해 볼 수 있습니다.
이 가이드는 Percy에 대한 간략한 개요만 제공합니다. 그렇지 않으면 완전히 새로운 기사의 콘텐츠를 제공할 것입니다. 그러나 시작하는 데 도움이 되는 정보를 알려 드리겠습니다. 지금 자세히 알아보려면 Percy의 설명서를 살펴보는 것이 좋습니다. 그렇다면 우리는 어떻게 우리의 테스트에 눈을 줄 수 있습니까? 지금쯤 이미 하나 또는 두 개의 Cypress 테스트를 작성했다고 가정해 보겠습니다. 다음과 같이 보일 것이라고 상상해보십시오.
it('should load home page (visual)', () => { cy.get('[data-cy=Polaroid]').should('be.visible'); cy.get('[data-cy=FeaturedPosts]').should('be.visible'); });
물론 Percy를 시각적 테스트 솔루션으로 설치하려면 cypress 플러그인을 사용하면 됩니다. 그래서 오늘 몇 번 했던 것처럼 NPM을 사용하여 루트 폴더에 설치합니다.
npm install --save-dev @percy/cli @percy/cypress
그런 다음 percy/cypress
패키지를 cypress/support/index.js
인덱스 파일로 가져오기만 하면 됩니다.
import '@percy/cypress';
이 가져오기를 통해 애플리케이션에서 스냅샷을 생성하는 Percy의 스냅샷 명령을 사용할 수 있습니다. 이 컨텍스트에서 스냅샷은 구성할 수 있는 다른 뷰포트 또는 브라우저에서 가져온 스크린샷 모음을 의미합니다.
it('should load home page (visual)', () => { cy.get('[data-cy=Polaroid]').should('be.visible'); cy.get('[data-cy=FeaturedPosts]').should('be.visible'); // Take a snapshot cy.percySnapshot('Home page'); });
워크플로 파일로 돌아가서 Percy 테스트를 작업의 두 번째 단계로 정의하고 싶습니다. 여기에서 npx percy exec -- cypress run
스크립트를 실행하여 Percy와 함께 테스트를 실행합니다. 테스트와 결과를 Percy 프로젝트에 연결하려면 GitHub 비밀로 숨겨진 Percy 토큰을 전달해야 합니다.
steps: # Before: Checkout, NPM, and E2E steps - name: Percy Test run: npx percy exec -- cypress run env: PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
왜 Percy 토큰이 필요합니까? Percy는 스크린샷을 유지 관리하기 위한 SaaS 솔루션이기 때문입니다. 스크린샷과 비교를 위해 현재 상태를 유지하고 스크린샷 승인 워크플로를 제공합니다. 여기에서 예정된 변경 사항을 승인하거나 거부할 수 있습니다.
작업 보기: GitHub 통합
축하합니다! 우리는 최초의 GitHub 작업 워크플로를 성공적으로 구축하고 있었습니다. 내 포트폴리오 페이지의 리포지토리에 있는 전체 워크플로 파일을 마지막으로 살펴보겠습니다. 실제 사용시 어떤 모습일지 궁금하지 않으세요? 저장소의 "작업" 탭에서 작동 중인 GitHub 작업을 찾을 수 있습니다.
여기에서 워크플로 파일에 해당하는 모든 워크플로를 찾을 수 있습니다. 내 "Tests CI" 워크플로와 같은 하나의 워크플로를 살펴보면 모든 작업을 검사할 수 있습니다.
작업 중 하나를 살펴보고 싶다면 사이드바에서도 선택할 수 있습니다. 여기에서 작업 로그를 검사할 수 있습니다.
파이프라인 내부에서 오류가 발생하면 오류를 감지할 수 있습니다. 그건 그렇고, "action" 탭은 GitHub 작업의 결과를 확인할 수 있는 유일한 장소가 아닙니다. pull 요청에서도 검사할 수 있습니다.
저는 이러한 GitHub 작업을 성공적으로 실행하는 데 필요한 방식으로 구성하는 것을 좋아합니다. 그렇지 않으면 끌어오기 요청을 내 저장소에 병합할 수 없습니다.
결론
CI/CD는 주요 리팩토링을 수행하는 데 도움이 되며 예상치 못한 상황에 직면할 위험을 극적으로 최소화합니다. CI/CD의 테스트 부분은 지속적으로 테스트되고 모니터링되는 코드베이스를 관리합니다. 결과적으로 우리는 오류를 매우 일찍 알아차릴 것입니다. 이상적으로는 누군가가 오류를 메인 브랜치에 병합하기 전에 말이죠. 또한 출근길에 현지 테스트를 수정해야 하는 곤경에 빠지지 않을 것입니다. 더 심한 경우 애플리케이션의 실제 오류도 발생합니다. 훌륭한 관점이라고 생각합니다. 맞죠?
이 테스트 빌드 루틴을 포함하기 위해 전체 DevOps 엔지니어가 될 필요는 없습니다. 일부 테스트 프레임워크 및 GitHub 작업의 도움으로 사이드 프로젝트에도 이를 구현할 수 있습니다. 짧은 시작을 하고 올바른 길로 인도할 수 있기를 바랍니다.
더 많은 테스트 파이프라인과 GitHub 작업 워크플로를 기대하고 있습니다! ️
자원
- GitHub의 CI/CD에 대한 훌륭한 가이드
- "실제 테스트 피라미드", Ham Vocke
- 읽을 가치가 있는 테스트 트로피에 대한 기사, Kent C.Dodds:
- "테스트를 작성하십시오. 너무 많지 않습니다. 대부분 통합”
- "테스트 트로피 및 테스트 분류"
- "프론트엔드 앱에 대한 정적 vs 단위 vs 통합 vs E2E 테스트"
- Cypress 실제 세계 앱의 몇 가지 예를 참조했습니다.
- 사용된 도구 및 프레임워크에 대한 문서:
- GitHub 작업
- 에스린트 문서
- 농담 문서
- 사이프러스 문서
- 퍼시 문서