우스갯소리가 담긴 실용 극작가 견본

지난주에 저는 Jest와 극작가와 함께 팀을 위해 E2E 테스트를 했습니다.극작가는 더 이상 새로운 것이 아니다. 인터넷에는 많은 극작가의 강좌와 견본이 있다.그러나 코드 생성, 디버깅, 보고서, IDE 구성 등 실제 설정이 부족합니다.그래서 나는 https://github.com/devalex88/playwright-boilerplate의 성적으로 시합에 참가하기로 결정했다.
템플릿 파일을 사용하려면 템플릿 파일을 복제하여 원하는 대로 수정합니다.템플릿 파일은 Visual Studio 코드에서 가장 잘 작동하도록 미리 구성되어 있으며 향상된 코드 작성 및 디버깅 환경을 제공합니다.다음 Visual Studio 코드 확장을 설치해야 합니다.
  • Prettier .
  • ESLint .
  • Jest Runner .
  • 실행 테스트 용례


    모든 테스트 용례를 실행하려면 명령npm test을 사용하십시오.이 프로젝트는 Jest를 테스트 프레임워크로 사용하기 때문에 문서를 읽어서 더 많은 실행 장면을 알 수 있습니다.기본 Jest 구성은 jest.config.js 에서 지정됩니다.
    > [email protected] test C:\Users\haimnguyen\data\playwright-demo
    > jest
    
    PASS   browser: chromium  tests/todomvc.test.js (6.298 s)
      TodoMVC
        √ should let users manage to-do list (5091 ms)
    
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        7 s
    Ran all test suites.
    
    성능을 최대한 높이기 위해 테스트 용례는 헤더 없는 모드에서 브라우저에 실행됩니다.다음 몇 절은 headfull 모드에서 테스트 용례를 디버깅하고 Github를 사용하여 작업 흐름을 실행하며 보고서를 검색하는 방법을 설명할 것이다.

    특정 테스트 용례 디버깅


    Visual Studio 코드에서 항목을 엽니다.위에서 언급한 확장자가 설치되어 있다면, 실행 및 디버깅 두 개의 단추가 테스트 용례 설명의 맨 위에 표시됩니다.테스트 용례를 디버깅하려면'디버깅'을 누르고 Visual Studio 코드의 디버깅기 기능(단점, 평가)을 이용하여 실행 중인 코드를 검사하십시오.
    디버그된 Jest 구성은 jest-debug.config.js 에서 지정됩니다.디버그 설정은 체험을 개선하는 설정을 통해 정상적인 설정을 확장합니다. 예를 들어 headless: falseslowMo: 200 은 무슨 일이 일어났는지 이해하는 데 도움이 됩니다.


    새로운 테스트 용례를 위한 코드 생성


    사용자 상호작용을 기록하여 E2E 테스트 용례를 작성하는 것은 아마추어처럼 들릴 수 있다.그러나 긴 테스트 용례의 모든 요소를 위한 포지셔닝 머신은 보통 지루한 작업이다.극작가는 Playwright CLI에게 고급 녹음 기능을 제공했다.일반적으로 생성된 CSS 및 XPath 로케이터는 텍스트를 기반으로 하여 클래스, ID 또는 위치와 같은 DOM 트리의 변경 사항을 조정할 수 있습니다.
    테스트 용례를 생성하려면 명령 npm run codegen http://todomvc.com/examples/react/#/ 을 사용합니다.
    const { chromium } = require('playwright');
    
    (async () => {
      const browser = await chromium.launch({
        headless: false
      });
      const context = await browser.newContext();
    
      // Open new page
      const page = await context.newPage();
    
      // Go to http://todomvc.com/examples/react/#/
      await page.goto("http://todomvc.com/examples/react/#/");
    
      // Click input[placeholder="What needs to be done?"]
      await page.click('input[placeholder="What needs to be done?"]');
    
      // Fill input[placeholder="What needs to be done?"]
      await page.fill(
        'input[placeholder="What needs to be done?"]',
        "Design a prototype"
      );
    
      // Press Enter
      await page.press('input[placeholder="What needs to be done?"]', "Enter");
    
      // Fill input[placeholder="What needs to be done?"]
      await page.fill(
        'input[placeholder="What needs to be done?"]',
        "Organize photo shoot"
      );
    
      // Press Enter
      await page.press('input[placeholder="What needs to be done?"]', "Enter");
    
      // Fill input[placeholder="What needs to be done?"]
      await page.fill(
        'input[placeholder="What needs to be done?"]',
        "Bring an umbrella"
      );
    
      // Press Enter
      await page.press('input[placeholder="What needs to be done?"]', "Enter");
    
      // Check //div[normalize-space(.)='Design a prototype']/input[normalize-space(@type)='checkbox']
      await page.check(
        "//div[normalize-space(.)='Design a prototype']/input[normalize-space(@type)='checkbox']"
      );
    
      // Check //div[normalize-space(.)='Organize photo shoot']/input[normalize-space(@type)='checkbox']
      await page.check(
        "//div[normalize-space(.)='Organize photo shoot']/input[normalize-space(@type)='checkbox']"
      );
    
      // Check //div[normalize-space(.)='Bring an umbrella']/input[normalize-space(@type)='checkbox']
      await page.check(
        "//div[normalize-space(.)='Bring an umbrella']/input[normalize-space(@type)='checkbox']"
      );
    
      // Click //div[normalize-space(.)='Bring an umbrella']/button
      await page.click("//div[normalize-space(.)='Bring an umbrella']/button");
    
      // Click input[placeholder="What needs to be done?"]
      await page.click('input[placeholder="What needs to be done?"]');
    
      // Click input[placeholder="What needs to be done?"]
      await page.click('input[placeholder="What needs to be done?"]');
    
      // Press Enter
      await page.press('input[placeholder="What needs to be done?"]', "Enter");
    
      // Press Enter
      await page.press('input[placeholder="What needs to be done?"]', "Enter");
    
      // Fill input[placeholder="What needs to be done?"]
      await page.fill(
        'input[placeholder="What needs to be done?"]',
        "Polish brand idea"
      );
    
      // Press Enter
      await page.press('input[placeholder="What needs to be done?"]', "Enter");
    
      // Click text="Completed"
      await page.click('text="Completed"');
      // assert.equal(page.url(), 'http://todomvc.com/examples/react/#/completed');
    
      // Close page
      await page.close();
    
      // ---------------------
      await context.close();
      await browser.close();
    })();
    
    9-86 줄의 내용을 사용하여 테스트 용례tests/todomvc.test.js를 만듭니다.서문과 결말은 이미 jest-playwright-preset 처리되었기 때문에 불필요한 것이다.
    const { chromium } = require("playwright");
    
    describe("TodoMVC", () => {
      it("should let users manage to-do list", async () => {
    
        // Open new page
        const page = await context.newPage();
    
        // Go to http://todomvc.com/examples/react/#/
        await page.goto("http://todomvc.com/examples/react/#/");
    
        // Click input[placeholder="What needs to be done?"]
        await page.click('input[placeholder="What needs to be done?"]');
    
        // Fill input[placeholder="What needs to be done?"]
        await page.fill(
          'input[placeholder="What needs to be done?"]',
          "Design a prototype"
        );
    
        // Press Enter
        await page.press('input[placeholder="What needs to be done?"]', "Enter");
    
        // Fill input[placeholder="What needs to be done?"]
        await page.fill(
          'input[placeholder="What needs to be done?"]',
          "Organize photo shoot"
        );
    
        // Press Enter
        await page.press('input[placeholder="What needs to be done?"]', "Enter");
    
        // Fill input[placeholder="What needs to be done?"]
        await page.fill(
          'input[placeholder="What needs to be done?"]',
          "Bring an umbrella"
        );
    
        // Press Enter
        await page.press('input[placeholder="What needs to be done?"]', "Enter");
    
        // Check //div[normalize-space(.)='Design a prototype']/input[normalize-space(@type)='checkbox']
        await page.check(
          "//div[normalize-space(.)='Design a prototype']/input[normalize-space(@type)='checkbox']"
        );
    
        // Check //div[normalize-space(.)='Organize photo shoot']/input[normalize-space(@type)='checkbox']
        await page.check(
          "//div[normalize-space(.)='Organize photo shoot']/input[normalize-space(@type)='checkbox']"
        );
    
        // Check //div[normalize-space(.)='Bring an umbrella']/input[normalize-space(@type)='checkbox']
        await page.check(
          "//div[normalize-space(.)='Bring an umbrella']/input[normalize-space(@type)='checkbox']"
        );
    
        // Click //div[normalize-space(.)='Bring an umbrella']/button
        await page.click("//div[normalize-space(.)='Bring an umbrella']/button");
    
        // Click input[placeholder="What needs to be done?"]
        await page.click('input[placeholder="What needs to be done?"]');
    
        // Click input[placeholder="What needs to be done?"]
        await page.click('input[placeholder="What needs to be done?"]');
    
        // Press Enter
        await page.press('input[placeholder="What needs to be done?"]', "Enter");
    
        // Press Enter
        await page.press('input[placeholder="What needs to be done?"]', "Enter");
    
        // Fill input[placeholder="What needs to be done?"]
        await page.fill(
          'input[placeholder="What needs to be done?"]',
          "Polish brand idea"
        );
    
        // Press Enter
        await page.press('input[placeholder="What needs to be done?"]', "Enter");
    
        // Click text="Completed"
        await page.click('text="Completed"');
        // assert.equal(page.url(), 'http://todomvc.com/examples/react/#/completed');
      });
    });
    
    상태를 단언하기 위해 Jest에 내장된 expect API나 극작가 커뮤니티에서 제공하는 편리한 expect-playwright 라이브러리를 사용할 수 있습니다.또 다른 편리함을 증명하는 단언 라이브러리는 jest-extend .

    연속 통합(CI)


    물론 사건이 발생했을 때 테스트 용례를 자동으로 집행하는 능력이 없다면 자동 테스트는 무용하다.Github Action, Azure DevOps, Circle CI 등 상당히 많은 CI 소프트웨어가 있습니다. Playwright는 설치 후 브라우저를 다운로드하는 데 매우 잘하고 헤더 없는 모드를 지원합니다.따라서 모든 클라우드 CI 또는 Docker를 사용하여 파이핑을 구성하는 것은 매우 간단합니다.이 템플릿에서는 Github 작업의 예제 구성만 .github/workflows/test.yml 에 포함합니다.
    name: Test
    
    on:
      push:
        branches: [master]
      pull_request:
        branches: [master]
    
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v2
          - name: Set up Node.js
            uses: actions/setup-node@v1
            with:
              node-version: 12.x
          - run: npm install && npm test
          - name: Upload reports to Katalon TestOps
            uses: katalon-studio/[email protected]
            env:
              PASSWORD: ${{ secrets.KATALON_API_KEY }}
              PROJECT_ID: ${{ secrets.KATALON_PROJECT_ID }}
              TYPE: junit
              REPORT_PATH: ${{ github.workspace }}/reports
    
    집행이 끝난 후, 우리는 통상적으로 검사 결과를 필요로 한다.만약 많은 테스트 용례가 있다면, 심사, 조사, 디버깅 실패가 매우 지루하다는 것을 발견할 수 있을 것이다.이것이 바로 내가 jest-junit 견본에 포함시킨 이유다.이 Jest의 기자 덕분에 결과는 reports/junit.xml로 도출될 것이다.이 보고서들은 JUnit의 XML 형식을 사용하고 테스트 관리와 지속적인 통합 소프트웨어는 거의 보편적으로 이런 형식을 이해한다.
    <?xml version="1.0" encoding="UTF-8"?>
    <testsuites name="jest tests" tests="1" failures="0" errors="0" time="7.005">
      <testsuite name="TodoMVC" errors="0" failures="0" skipped="0" timestamp="2020-10-15T07:56:27" time="6.298" tests="1">
        <testcase classname="TodoMVC should let users manage to-do list" name="TodoMVC should let users manage to-do list" time="5.091">
        </testcase>
      </testsuite>
    </testsuites>
    
    예시 Github 작업 흐름에서도 보고서가 업로드됩니다 Katalon TestOps. (면책 성명: 저는 이 프로젝트에 종사하고 있습니다. 그러나 Katalon Test Ops는 무료이기 때문에 이것도 합리적인 선택이라고 생각합니다. 가장 좋아하는 도구로 JUnit XML 보고서를 사용할 수 있습니다.)Katalon TestOps에서 제공하는 계기판과 분석은 테스트 활동에 대해 깊이 있게 이해할 수 있습니다.또한 Jira 통합 기능을 사용하여 테스트 용례를 다른 Jira 데이터와 연결하여 테스트 용례와 업무 수요를 일치시킬 수 있습니다.

    이것이 바로 이 템플릿이 지원하는 모든 주요 장면이다.기능이나 사용자 정의에 대한 요구가 있으면 즉시 문제를 제기하십시오.
    감사합니다, 즐거운 코드!

    좋은 웹페이지 즐겨찾기