Github Actions 및 Puppeter와의 지속적인 통합

최근에 제 블로그에 Puppeter를 사용하여 끝에서 끝까지 테스트를 하는 지속적인 통합을 추가했습니다.나의 주요 목표는 사용Dependabot을 허용하고 의존항을 자동으로 업데이트하는 것이다.
나의 CI 플랫폼으로서 나는 Github Actions 를 선택했다. 그것은 매우 사용하기 쉽고 기존의 Github 저장소와 완벽하게 통합되기 때문이다.전체 과정이 약 이틀의 간헐적인 작업만 걸렸는데, 나는 결과가 매우 좋다고 생각한다.
나는 정말 닉 테일러 (Nick Taylor) 에게 그가 출판 his article on the subject 을 해서 나의 이곳에서의 노력에 기반을 다졌다고 말하고 싶다. 그래서 나는 너희들도 그의 글을 읽도록 격려한다.
하지만 내 기술 창고는 완전히 다르다.몇 가지 이유로 나는 puppeteer 을 나의 끝에서 끝까지 프레임워크로 선택했다.우선, 이것은 크롬 개발 도구 뒤에 있는 사람이 작성하고 유지하는 것이기 때문에, 나는 평생 지원을 보장한다. (크롬이 사라질 때까지, 이것은 머지않아 사용할 수 없을 때까지) 그리고 사용하기 쉽다.
또 다른 이유는 집에서 WSL로 윈도우즈 노트북 (oh my zsh로 zshell을 실행하고 있음) 을 개발하고 있는데,cypress를 설정하는 것은 훨씬 어렵기 때문이다.이 두 가지 이유 모두 나로 하여금 인형을 선택하게 하였는데, 지금까지 나는 결코 후회하지 않는다.

엔드 투 엔드 테스트


엔드 투 엔드(또는 E2E) 테스트는 다른 유형의 자동화 테스트와 다릅니다.E2E 테스트는 실제 사용자를 시뮬레이션하여 화면에서 동작을 수행합니다.이러한 테스트는'정적'테스트(예를 들어 단원 테스트, 전체 응용 프로그램을 유도하지 않음)와 구성 요소 테스트(일반적으로 단일 구성 요소(또는 마이크로서비스 구조의 서비스) 사이의 공백을 메우는 데 도움이 될 것이다.
아날로그 사용자 상호작용을 통해 일반 사용자 체험으로 응용 프로그램이나 서비스를 사용하는 체험을 테스트할 수 있습니다.
우리가 따르고자 하는 격언은 사용자가 눌러야 할 단추가 일부 css 괴벽으로 인해 숨겨져 있다면 코드가 완벽하게 실행되는지는 중요하지 않다는 것이다.최종 결과는 사용자가 당신의 코드의 위대함을 영원히 느끼지 못할 것이다.

인형사 입문


Puppeter에는 작성 및 검증 테스트를 위한 구성 옵션이 있습니다.
인형 테스트는 실제 브라우저 창을 열고 테스트 중인 사이트로 이동하여 주어진 페이지에서 실행할 수 있는 "머리 가득"상태에서 실행할 수 있습니다.이렇게 하면 테스트를 작성한 개발자는 테스트에서 무슨 일이 일어났는지, 어떤 단추를 눌렀는지, 그리고 생성된 UI가 어떤 모습인지 정확하게 볼 수 있습니다."헤드 가득"과 반대로, 인형 배우는 브라우저 창을 열지 않아 CI 파이프의 이상적인 선택이 된다.
인형사는 사용하기 쉽지만, 자동화 도구를 사용하면 실행할 수 있는 동작의 수량에 놀라게 될 것이다.
기본 스크레이퍼부터 시작하여 https://dorshinar.me 로 이동하면 페이지 제목을 인쇄합니다.Puppeter 테스트를 실행하려면 종속성으로 설치해야 합니다.
npm i puppeteer
이제 우리의 기본 스크레이퍼는 다음과 같다.
const puppeteer = require("puppeteer");

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto("https://dorshinar.me");
  console.log(await page.title());

  await browser.close();
})();
우리는 여기서 매우 간단하게 한다. 우리는 puppeteer.launch() 브라우저를 열고, browser.newPage() 으로 새 페이지를 만들고, page.goto() 으로 이 블로그를 탐색한 후에 제목을 인쇄한다.Puppeter API를 사용하여 다음과 같은 작업을 수행할 수 있습니다.
페이지 컨텍스트에서 코드를 실행하려면 다음과 같이 하십시오.
(async () => {
  await page.evaluate(() => document.querySelector(".awesome-button").click());
})();
CSS 선택기를 사용하여 화면에서 요소를 클릭합니다.
(async () => {
  await page.click(".awesome-button");
})();
$ 선택기 사용(jQuery 스타일):
(async () => {
  await page.$(".awesome-button");
})();
캡처:
(async () => {
  await page.screenshot({ path: "screenshot.png" });
})();
Puppeter API를 사용하면 많은 일을 할 수 있습니다. 테스트를 작성하기 전에 먼저 그것을 보십시오. 그러나 제가 보여준 예시는 당신에게 튼튼한 기초를 제공할 것입니다.

인형과 우스갯소리의 결합


jest는 훌륭한 테스트 실행 프로그램과 단언 라이브러리이다.문서에서 다음을 수행합니다.

Jest is a delightful JavaScript Testing Framework with a focus on simplicity.


Jest를 사용하면 테스트, 아날로그 가져오기, 복잡한 단언을 쉽게 실행할 수 있습니다.Jest는createreact 프로그램과 묶여 있기 때문에 저는 업무 중에 자주 사용합니다.

너의 첫 번째 농담 테스트를 써봐.


Jest 테스트는 작성하기 쉬우므로 it, test, describe과 다른 익숙한 약속을 이용하여 다른 테스트 프레임워크를 이해하는 사람들이 익숙할 수 있습니다.
기본 테스트는 다음과 같습니다.
function subtract(a, b) {
  return a - b;
}

it("subtracts 4 from 6 and returns 2", () => {
  expect(subtract(6, 4)).toBe(2);
});
여러 테스트를 하나의 describe 아래에 그룹화하여 다른 설명을 실행하거나 보고서를 쉽게 보고할 수 있습니다.
function divide(a, b) {
  if (b === 0) {
    throw new Error("Can't divide by zero!");
  }
  return a / b;
}

describe("divide", () => {
  it("throws when dividing by zero", () => {
    expect(() => divide(6, 0)).toThrow();
  });
  it("returns 3 when dividing 6 by 3", () => {
    expect(divide(6, 3)).toBe(2);
  });
});
물론 시뮬레이션과 다른 유형의 단언 (또는 기대) 을 사용하여 더 복잡한 테스트를 만들 수 있지만, 지금은 충분합니다.
테스트도 간단합니다.
jest
Jest는 다음과 같은 일반적인 이름 지정 규칙이 있는 테스트 파일을 찾습니다.
  • 폴더의 접미사가 .js인 파일입니다.
  • 접미사가 __tests__ 인 파일입니다.
  • 접미사가 .test.js 인 파일입니다.
  • 광대 인형사


    이제 우리는 인형 배우가 농담을 잘 할 수 있도록 해야 한다.이것은 특별히 어려운 일이 아니다. 왜냐하면 jest-puppeteer라는 아주 좋은 소프트웨어 패키지가 우리를 도울 수 있기 때문이다.
    우선 종속성으로 설치해야 합니다.
    npm i jest-puppeteer
    
    지금 우리는 jest 설정을 확장해야 합니다.만약 네가 아직 없다면, 할 수 있는 많은 방법이 있다. 나는 프로필을 사용할 것이다.프로젝트 루트 디렉토리에 .spec.js 라는 파일을 만듭니다.
    touch jest.config.js
    
    이 파일에서 jest 사용 jest.config.js 의 사전 설정을 알려야 하기 때문에 다음 코드를 이 파일에 추가해야 합니다.
    module.exports = {
      preset: "jest-puppeteer" 
      // The rest of your file...
    };
    
    jest-puppeteer 파일에 특별한 시작 설정을 지정할 수 있습니다. jest Puppeter는 이 설정을 jest-puppeteer.config.js 에 전달합니다.예:
    module.exports = {
      launch: {
        headless: process.env.CI === "true",
        ignoreDefaultArgs: ["--disable-extensions"],
        args: ["--no-sandbox"],
        executablePath: "chrome.exe"
      }
    };
    
    puppeteer.launch()는 새 브라우저와 새 페이지를 열고 전역적으로 저장하기 때문에 테스트에서 전역적으로 사용할 수 있는 jest-puppeteerbrowser 대상만 사용하십시오.
    우리가 사용할 수 있는 또 다른 좋은 기능은 jest Puppeter가 테스트 기간에 서버를 실행하고 page 키로 죽일 수 있다는 것이다.
    module.exports = {
      launch: {},
      server: {
        command: "npm run serve",
        port: 9000,
        launchTimeout: 180000
      }
    };
    
    현재 jest Puppeter는 실행server, 180초(3분), 포트 9000에서 언제 시작되는지 정탐합니다.서버가 시작되면 테스트가 실행됩니다.
    이제 jest와 Puppeter를 사용하여 전체 테스트 세트를 작성할 수 있습니다.나머지는 CI 파이프를 만드는 것입니다. github 작업을 사용할 것입니다.
    테스트를 수행하기 위해 스크립트를 npm run serve 파일에 추가할 수 있습니다.
    {
      "scripts": {
        "test:e2e": "jest" 
      }
    }
    

    gist의 Github 작업


    최근 Github는 Actions라는 새로운 기능을 발표했다.기본적으로 조작은 순수한 yaml 문법으로 작업 흐름을 만들고 전용 가상 기기에서 실행할 수 있도록 합니다.당신의 업무 절차에서, 당신은 기본적인 package.json부터 더 복잡한 일까지 거의 모든 것을 할 수 있다.
    Puppeter 테스트 세트를 실행하는 기본 워크플로우를 설정하고 테스트가 통과되지 않을 때 통합을 방지하는 방법을 보여 드리겠습니다.
    가장 간단한 시작 방법은githubrepo의 npm ci && npm build && npm run test 옵션 카드를 누르는 것입니다.이전에 구성된 작업이 없으면 이전에 구성된 워크플로우 목록이 표시되며 미리 정의된 구성이 있는 워크플로우를 선택할 수 있습니다.

    우리의 예에 대해 미리 정의된 노드를 선택하십시오.제스 동작이 충분해요.생성된 yaml은 다음과 같습니다.
    name: Node CI
    
    on: [push]
    
    jobs:
      build:
        runs-on: ubuntu-latest
    
        strategy:
          matrix:
            node-version: [8.x, 10.x, 12.x]
    
        steps:
          - uses: actions/checkout@v1
          - name: Use Node.js ${{ matrix.node-version }}
            uses: actions/setup-node@v1
            with:
              node-version: ${{ matrix.node-version }}
          - name: npm install, build, and test
            run: |
              npm ci
              npm run build --if-present
              npm test
            env:
              CI: true
    
    이 파일에서 워크플로 이름, 실행할 작업, 워크플로를 실행할 시기를 설정할 수 있습니다.밀어넣기, 새 가져오기 요청 또는 반복 이벤트로 워크플로우를 실행할 수 있습니다.기본적으로 워크플로우의 작업은 병행 실행되지만 순서대로 실행되도록 설정할 수 있습니다.위의 워크플로에는 Actions 라는 작업이 있습니다.
    또한 build 키를 사용하여 워크플로우를 실행할 운영 체제를 선택할 수 있습니다(기본적으로 Windows Server 2019, Ubuntu 18.04, Ubuntu 16.04 및 macOS Catalina 10.15).runs-on 키를 사용하면 노드 버전 매트릭스에서 테스트를 실행할 수 있습니다. 이 경우 최신 LTS 전공의 최신 버전 - strategy, 8.x10.x 이 있습니다.만약 당신이 이것에 흥미가 있다면, 원형을 유지하거나, 아예 그것을 삭제하고, 당신이 원하는 특정한 버전을 사용할 수 있습니다.
    가장 재미있는 구성 옵션은 12.x 입니다.그것을 통해 우리는 우리의 파이프에서 실제로 발생하는 일을 정의했다.모든 단계는 당신이 실행할 수 있는 동작을 대표합니다. 예를 들어repo에서 코드 검출, 노드 버전 설정, 의존 항목 설치, 테스트 실행, 공작물 업로드 (나중에 사용하거나 다운로드) 등입니다.Actions Marketplace 에서 사용 가능한 광범위한 작업 목록을 찾을 수 있습니다.
    기본 설정은 의존항을 설치하고 프로젝트를 구축하며 테스트를 실행합니다.만약 더 많은 것을 필요로 한다면 (예를 들어 e2e 테스트 프로그램에 서비스를 제공하고 싶다면) 자신의 취향에 따라 변경할 수 있습니다.일단 완성되면 변경 사항을 제출하면 시작할 수 있습니다.

    병합 전 강제 통과 검사


    우리가 유일하게 해야 할 일은 우리의 업무 흐름이 성공적으로 통과되기 전에 코드가 합병될 수 없도록 확보하는 것이다.이를 위해 재구매 설정으로 이동하여 지점을 클릭하십시오.

    악성코드 (또는 테스트를 통과하지 않은 코드 하나 이상) 가 병합되지 않도록 분기 보호 규칙을 설정해야 합니다.Add rule을 클릭하고 Branch name pattern 아래에 보호된 분기 (master, dev 또는 선택한 모든 것) 를 놓으십시오.병합을 선택하기 전에 상태 검사를 통과해야 하며 어떤 검사를 통과해야 하는지 선택할 수 있습니다.

    아래의 Save changes(변경 내용 저장)를 누르면 시작합니다!

    좋은 웹페이지 즐겨찾기