각도기-퀵 가이드
이 장에서는이 테스트 프레임 워크의 기원과이 도구의 작동 및 제한 사항을 선택해야하는 이유에 대해 배울 수있는 Protractor를 소개합니다.
각도기는 무엇입니까?
Protractor는 Angular 및 AngularJS 애플리케이션을위한 오픈 소스 엔드-투-엔드 테스트 프레임 워크입니다. WebDriver 위에 Google이 구축했습니다. 또한“Angular Scenario Runner”라고하는 기존 AngularJS E2E 테스트 프레임 워크를 대체합니다.
또한 NodeJS, Selenium, Jasmine, WebDriver, Cucumber, Mocha 등과 같은 강력한 기술을 결합한 솔루션 통합 자 역할을합니다. AngularJS 애플리케이션 테스트와 함께 일반 웹 애플리케이션에 대한 자동 회귀 테스트도 작성합니다. 실제 브라우저를 사용하여 테스트를 실행하기 때문에 실제 사용자처럼 애플리케이션을 테스트 할 수 있습니다.
다음 다이어그램은 각도기의 간략한 개요를 제공합니다-
위의 다이어그램에서 우리는-
Protractor − 앞서 논의했듯이, 특히 각도 앱을 위해 설계된 WebDriver JS에 대한 래퍼입니다.
Jasmine− 기본적으로 JavaScript 코드를 테스트하기위한 동작 중심 개발 프레임 워크입니다. Jasmine으로 쉽게 테스트를 작성할 수 있습니다.
WebDriver JS − 셀레늄 2.0 / WebDriver를위한 Node JS 바인딩 구현입니다.
Selenium − 단순히 브라우저를 자동화합니다.
유래
앞서 말했듯이 Protractor는 "Angular Scenario Runner"라는 기존 AngularJS E2E 테스트 프레임 워크를 대체합니다. 기본적으로 Protractor의 기원은 Scenario Runner의 끝에서 시작됩니다. 여기서 제기되는 질문은 왜 우리가 Protractor를 구축해야 하는가입니다. 이를 이해하려면 먼저 이전 모델 인 Scenario Runner에 대해 확인해야합니다.
각도기의 시작
Protractor 개발의 주요 기여자 인 Julie Ralph는 Google 내의 다른 프로젝트에서 Angular Scenario Runner에 대해 다음과 같은 경험을했습니다. 이것은 특히 간격을 메우기 위해 Protractor를 구축하는 동기가되었습니다.
“Scenario Runner를 사용해 보았지만 실제로 테스트에 필요한 작업을 수행 할 수 없다는 것을 알게되었습니다. 로그인과 같은 것을 테스트해야했습니다. 귀하의 로그인 페이지는 Angular 페이지가 아니며 Scenario Runner는이를 처리 할 수 없습니다. 팝업 및 여러 창, 브라우저 기록 탐색 등을 처리 할 수 없습니다. "
Protractor의 가장 큰 장점은 Selenium 프로젝트의 성숙도이며 Angular 프로젝트에 쉽게 사용할 수 있도록 방법을 정리했습니다. Protractor의 디자인은 응용 프로그램의 웹 UI, 백엔드 서비스, 지속성 계층 등과 같은 모든 계층을 테스트하는 방식으로 구축됩니다.
왜 각도기?
거의 모든 응용 프로그램이 개발을 위해 JavaScript를 사용하고 있다는 것을 알고 있습니다. JavaScript의 크기가 커지면 테스터의 작업이 어려워지고 응용 프로그램 자체의 수가 증가하여 응용 프로그램이 복잡해집니다. 대부분의 경우 AngularJS 애플리케이션에서 웹 요소를 캡처하고 JUnit 또는 Selenium WebDriver를 사용하여 확장 된 HTML 구문을 사용하여 웹 애플리케이션 구성 요소를 표현하는 것이 매우 어려워집니다.
여기서 질문은 Selenium Web Driver가 AngularJS 웹 요소를 찾을 수없는 이유입니다. 그 이유는 AngularJS 애플리케이션이 Selenium 로케이터에 포함되지 않은 ng-repeater, ng-controller 및 ng-model 등과 같은 확장 된 HTML 속성을 가지고 있기 때문입니다.
여기에서 Protractor의 중요성은 Selenium 위에있는 Protractor가 AngularJS 웹 애플리케이션에서 확장 된 HTML 요소를 처리하고 제어 할 수 있기 때문에 존재합니다. 그렇기 때문에 대부분의 프레임 워크가 AngularJS 애플리케이션에 대한 단위 테스트를 수행하는 데 초점을 맞추고 있다고 말할 수 있습니다. Protractor는 애플리케이션의 실제 기능을 테스트하는 데 사용되었습니다.
각도기의 작동
테스트 프레임 워크 인 Protractor는 Selenium과 함께 작동하여 브라우저 또는 모바일 장치에서 실행되는 AngularJS 애플리케이션과 사용자의 상호 작용을 시뮬레이션하기위한 자동화 된 테스트 인프라를 제공합니다.
각도기의 작동은 다음 단계의 도움으로 이해할 수 있습니다-
Step 1− 첫 번째 단계에서는 테스트를 작성해야합니다. Jasmine 또는 Mocha 또는 Cucumber의 도움으로 할 수 있습니다.
Step 2− 이제 Protractor의 도움으로 수행 할 수있는 테스트를 실행해야합니다. 테스트 러너라고도합니다.
Step 3 −이 단계에서 Selenium 서버는 브라우저 관리를 도와줍니다.
Step 4 − 마지막으로 브라우저 API는 Selenium WebDriver의 도움으로 호출됩니다.
장점
이 오픈 소스 엔드-투-엔드 테스트 프레임 워크는 다음과 같은 이점을 제공합니다.
오픈 소스 도구 인 Protractor는 설치 및 설정이 매우 쉽습니다.
Jasmine 프레임 워크와 잘 작동하여 테스트를 만듭니다.
TDD (테스트 주도 개발)를 지원합니다.
자동 대기를 포함하므로 테스트에 대기 및 수면을 명시 적으로 추가 할 필요가 없습니다.
Selenium WebDriver의 모든 장점을 제공합니다.
여러 브라우저를 통한 병렬 테스트를 지원합니다.
자동 동기화의 이점을 제공합니다.
테스트 속도가 뛰어납니다.
한계
이 오픈 소스 엔드-투-엔드 테스트 프레임 워크에는 다음과 같은 제한 사항이 있습니다.
WebDriver JS의 래퍼이기 때문에 브라우저 자동화의 카테고리를 밝히지 않습니다.
JavaScript에서만 사용할 수 있기 때문에 JavaScript에 대한 지식은 사용자에게 필수적입니다.
UI 기반 테스트 도구이기 때문에 프런트 엔드 테스트 만 제공합니다.
Protractor를 사용하려면 JavaScript에 대한 지식이 필수적이므로이 장에서는 JavaScript 테스트의 개념을 자세히 이해하겠습니다.
JavaScript 테스트 및 자동화
JavaScript는 동적으로 입력되고 해석되는 가장 널리 사용되는 스크립팅 언어이지만 가장 어려운 작업은 코드를 테스트하는 것입니다. JAVA 및 C ++와 같은 다른 컴파일 된 언어와 달리 JavaScript에는 테스터가 오류를 파악하는 데 도움이되는 컴파일 단계가 없기 때문입니다. 게다가 브라우저 기반 테스트는 시간이 많이 걸립니다. 따라서 JavaScript에 대한 자동화 된 테스트를 지원하는 도구가 필요합니다.
자동화 된 테스트의 개념
코드를 더 좋게 만들기 때문에 항상 테스트를 작성하는 것이 좋습니다. 수동 테스트의 문제는 시간이 많이 걸리고 오류가 발생하기 쉽다는 것입니다. 수동 테스트 프로세스는 프로세스를 반복하고 테스트 사양을 작성하며 코드를 변경하고 브라우저를 여러 번 새로 고쳐야하기 때문에 프로그래머에게도 매우 지루합니다. 게다가 수동 테스트는 개발 프로세스를 늦 춥니 다.
위의 이유 때문에 이러한 테스트를 자동화하고 프로그래머가 이러한 반복적이고 지루한 단계를 제거하는 데 도움이되는 몇 가지 도구를 사용하는 것이 항상 유용합니다. 개발자는 테스트 프로세스를 자동화하기 위해 무엇을해야합니까?
기본적으로 개발자는 CLI (Command Line Interpreter) 또는 개발 IDE (통합 개발 환경)에서 도구 세트를 구현할 수 있습니다. 그런 다음 이러한 테스트는 개발자의 입력 없이도 별도의 프로세스에서 지속적으로 실행됩니다. JavaScript의 자동화 된 테스트도 새로운 것은 아니며 Karma, Protractor, CasperJS 등과 같은 많은 도구가 개발되었습니다.
자바 스크립트 테스트 유형
목적에 따라 다른 테스트가있을 수 있습니다. 예를 들어, 일부 테스트는 프로그램에서 함수의 동작을 확인하기 위해 작성되고 다른 테스트는 모듈 또는 기능의 흐름을 테스트하기 위해 작성됩니다. 따라서 다음 두 가지 유형의 테스트가 있습니다.
단위 테스트
테스트는 단위라고하는 프로그램에서 테스트 가능한 가장 작은 부분에서 수행됩니다. 이 장치는 기본적으로 다른 부품에 대한 해당 장치의 종속성없이 격리 된 상태로 테스트됩니다. JavaScript의 경우 특정 동작을 갖는 개별 메서드 또는 함수는 코드 단위가 될 수 있으며 이러한 코드 단위는 격리 된 방식으로 테스트되어야합니다.
유닛 테스트의 장점 중 하나는 유닛이 서로 독립적이기 때문에 유닛 테스트를 순서에 상관없이 수행 할 수 있다는 것입니다. 정말 중요한 단위 테스트의 또 다른 장점은 다음과 같이 언제든지 테스트를 실행할 수 있다는 것입니다.
- 개발 프로세스의 시작부터.
- 모듈 / 기능 개발을 완료 한 후.
- 모듈 / 기능을 수정 한 후.
- 기존 애플리케이션에 새로운 기능을 추가 한 후.
JavaScript 애플리케이션의 자동화 된 단위 테스트를 위해 Mocha, Jasmine 및 QUnit과 같은 많은 테스트 도구 및 프레임 워크에서 선택할 수 있습니다.
종단 간 테스트
애플리케이션의 처음부터 끝까지 (한 쪽 끝에서 다른 쪽 끝으로) 흐름이 설계에 따라 제대로 작동하는지 테스트하는 데 사용되는 테스트 방법론으로 정의 할 수 있습니다.
종단 간 테스트를 기능 / 흐름 테스트라고도합니다. 단위 테스트와 달리 종단 간 테스트는 개별 구성 요소가 응용 프로그램으로 함께 작동하는 방식을 테스트합니다. 이것이 단위 테스트와 종단 간 테스트의 주요 차이점입니다.
예를 들어, 사용자가 등록을 완료하기 위해 유효한 정보를 제공해야하는 등록 모듈이있는 경우 해당 특정 모듈에 대한 E2E 테스트는 테스트를 완료하기 위해 다음 단계를 따릅니다.
- 먼저 폼이나 모듈을로드 / 컴파일합니다.
- 이제 양식 요소의 DOM (문서 개체 모델)을 가져옵니다.
- 다음으로 제출 버튼의 클릭 이벤트를 트리거하여 작동 여부를 확인합니다.
- 이제 유효성 검사를 위해 입력 필드에서 값을 수집합니다.
- 다음으로 입력 필드의 유효성을 검사해야합니다.
- 테스트 목적으로 가짜 API를 호출하여 데이터를 저장하십시오.
모든 단계는 예상 결과 세트와 비교할 자체 결과를 제공합니다.
이제 제기되는 질문은 이러한 종류의 E2E 또는 기능 테스트를 수동으로 수행 할 수도 있지만이를 위해 자동화가 필요한 이유는 무엇입니까? 주된 이유는 자동화가이 테스트 프로세스를 쉽게 만들 수 있기 때문입니다. 이를 위해 모든 애플리케이션과 쉽게 통합 할 수있는 사용 가능한 도구 중 일부는 Selenium, PhantomJS 및 Protractor입니다.
테스트 도구 및 프레임 워크
Angular 테스트를위한 다양한 테스트 도구와 프레임 워크가 있습니다. 다음은 잘 알려진 도구와 프레임 워크 중 일부입니다.
업
Vojta Jina가 만든 Karma는 테스트 러너입니다. 원래이 프로젝트는 Testacular라고 불 렸습니다. 이는 테스트 프레임 워크가 아니므로 실제 브라우저에서 JavaScript 단위 테스트를 쉽고 자동으로 실행할 수있는 기능을 제공합니다. Karma 이전에는 웹 기반 JavaScript 개발자를위한 자동화 된 테스트 도구가 없었기 때문에 Karma는 AngularJS 용으로 구축되었습니다. 반면에 Karma가 제공하는 자동화를 통해 개발자는 간단한 단일 명령을 실행하고 전체 테스트 스위트가 통과했는지 실패했는지 확인할 수 있습니다.
Karma 사용의 장점
다음은 수동 프로세스와 비교하여 Karma를 사용하는 몇 가지 장점입니다.
- 여러 브라우저 및 장치에서 테스트를 자동화합니다.
- 파일에서 오류를 모니터링하고 수정합니다.
- 온라인 지원 및 문서를 제공합니다.
- 지속적 통합 서버와의 통합을 용이하게합니다.
Karma 사용의 단점
다음은 Karma 사용의 몇 가지 단점입니다-
Karma 사용의 가장 큰 단점은 구성 및 유지 관리를 위해 추가 도구가 필요하다는 것입니다.
Jasmine과 함께 Karma 테스트 실행기를 사용하는 경우 하나의 요소에 대해 여러 개의 ID가있는 경우 CSS 설정에 대한 정보를 찾는 데 사용할 수있는 문서가 적습니다.
재스민 속
JavaScript 코드 테스트를위한 동작 중심 개발 프레임 워크 인 Jasmine은 Pivotal Labs에서 개발되었습니다. Jasmine 프레임 워크가 활발히 개발되기 전에 JsUnit이라는 유사한 단위 테스트 프레임 워크도 테스트 실행기가 내장 된 Pivotal Labs에서 개발했습니다. 브라우저 테스트는 SpecRunner.html 파일을 포함하거나 명령 줄 테스트 실행기로 사용하여 Jasmine 테스트를 통해 실행할 수 있습니다. Karma의 유무에 관계없이 사용할 수 있습니다.
Jasmine 사용의 장점
다음은 Jasmine을 사용하는 몇 가지 장점입니다.
브라우저, 플랫폼 및 언어에 독립적 인 프레임 워크입니다.
행동 기반 개발과 함께 테스트 기반 개발 (TDD)을 지원합니다.
Karma와 기본 통합이 있습니다.
이해하기 쉬운 구문.
추가 기능으로 테스트를 지원하는 테스트 스파이, 가짜 및 통과 기능을 제공합니다.
Jasmine 사용의 단점
다음은 Jasmine 사용의 단점입니다.
테스트를 실행하는 동안 Jasmine에서 사용할 수있는 파일 감시 기능이 없기 때문에 테스트는 변경 될 때 사용자가 반환해야합니다.
모카
Node.js 애플리케이션 용으로 작성된 Mocha는 테스트 프레임 워크이지만 브라우저 테스트도 지원합니다. Jasmine과 매우 비슷하지만 Mocha는 테스트 프레임 워크로 독립형으로 실행할 수 없기 때문에 플러그인과 라이브러리가 필요하다는 점이 가장 큰 차이점입니다. 반면 Jasmine은 독립형입니다. 그러나 Mocha는 Jasmine보다 사용하기가 더 유연합니다.
Mocha 사용의 장점
다음은 Mocha를 사용하는 몇 가지 장점입니다-
- Mocha는 설치 및 구성이 매우 쉽습니다.
- 사용자 친화적이고 간단한 문서.
- 여러 노드 프로젝트가있는 플러그인이 포함되어 있습니다.
모카 사용의 단점
다음은 Mocha 사용의 몇 가지 단점입니다-
- 단언, 스파이 등에 대한 별도의 모듈이 필요합니다.
- 또한 Karma와 함께 사용하려면 추가 구성이 필요합니다.
QUnit
JQuery의 일부로 2008 년 John Resig가 처음 개발 한 QUint는 강력하면서도 사용하기 쉬운 JavaScript 단위 테스트 제품군입니다. 일반 JavaScript 코드를 테스트하는 데 사용할 수 있습니다. 브라우저에서 JavaScript 테스트에 초점을 맞추고 있지만 개발자가 사용하는 것이 매우 편리합니다.
QUnit 사용의 장점
다음은 QUnit을 사용하는 몇 가지 장점입니다-
- 설치 및 구성이 쉽습니다.
- 사용자 친화적이고 간단한 문서.
QUnit 사용의 단점
다음은 QUnit 사용의 단점입니다-
- 주로 jQuery 용으로 개발되었으므로 다른 프레임 워크와 함께 사용하기에 적합하지 않습니다.
셀렌
2004 년에 Jason Huggins가 ThoughtWorks의 내부 도구로 개발 한 Selenium은 오픈 소스 테스트 자동화 도구입니다. Selenium은 스스로를“Selenium은 브라우저를 자동화합니다. 그게 다야!”. 브라우저 자동화는 개발자가 브라우저와 매우 쉽게 상호 작용할 수 있음을 의미합니다.
셀레늄 사용의 장점
다음은 Selenium을 사용하는 몇 가지 장점입니다-
- 큰 기능 세트를 포함합니다.
- 분산 테스트를 지원합니다.
- Sauce Labs와 같은 서비스를 통해 SaaS를 지원합니다.
- 간단한 문서와 풍부한 리소스로 사용하기 쉽습니다.
Selenium 사용의 단점
다음은 셀레늄 사용의 몇 가지 단점입니다-
- Selenium 사용의 주요 단점은 별도의 프로세스로 실행해야한다는 것입니다.
- 개발자가 여러 단계를 수행해야하므로 구성이 약간 번거 롭습니다.
이전 장에서 우리는 각도기의 기초를 배웠습니다. 이 장에서는이를 설치하고 구성하는 방법에 대해 알아 보겠습니다.
전제 조건
컴퓨터에 Protractor를 설치하기 전에 다음 전제 조건을 충족해야합니다.
Node.js
Protractor는 Node.js 모듈이므로 매우 중요한 전제 조건은 컴퓨터에 Node.js가 설치되어 있어야한다는 것입니다. Node.js와 함께 제공되는 npm (JavaScript 패키지 관리자)을 사용하여 Protractor 패키지를 설치합니다.
Node.js를 설치하려면 공식 링크를 따르십시오- https://nodejs.org/en/download/. Node.js를 설치 한 후 다음 명령을 작성하여 Node.js 및 npm의 버전을 확인할 수 있습니다.node --version 과 npm --version 아래와 같이 명령 프롬프트에서-
크롬
Google에서 만든 웹 브라우저 인 Google Chrome은 Selenium 서버 없이도 Protractor에서 엔드 투 엔드 테스트를 실행하는 데 사용됩니다. 링크를 클릭하여 크롬을 다운로드 할 수 있습니다-https://www.google.com/chrome/.
Chrome 용 Selenium WebDriver
이 도구는 Protractor npm 모듈과 함께 제공되며 웹 애플리케이션과 상호 작용할 수 있습니다.
각도기 설치
컴퓨터에 Node.js를 설치 한 후 다음 명령을 사용하여 Protractor를 설치할 수 있습니다.
npm install -g protractor
각도기가 성공적으로 설치되면 다음을 작성하여 버전을 확인할 수 있습니다. protractor --version 아래와 같이 명령 프롬프트에서 명령-
Chrome 용 WebDriver 설치
Protractor를 설치 한 후 Chrome 용 Selenium WebDriver를 설치해야합니다. 다음 명령을 사용하여 설치할 수 있습니다.
webdriver-manager update
위의 명령은 프로젝트에서 사용되는 필수 Chrome 드라이버가 포함 된 Selenium 디렉토리를 생성합니다.
설치 및 구성 확인
Protractor 설치 후 예제에 제공된 conf.js를 약간 변경하여 Protractor의 설치 및 구성을 확인할 수 있습니다. 이 conf.js 파일은 루트 디렉토리에서 찾을 수 있습니다.node_modules/Protractor/example.
이를 위해 먼저 동일한 디렉토리에 testingconfig.js라는 새 파일을 만듭니다. node_modules/Protractor/example.
이제 conf.js 파일의 소스 파일 선언 매개 변수 아래에 testingconfig.js를 작성하십시오.
다음으로 모든 파일을 저장하고 닫고 명령 프롬프트를 엽니 다. 아래 스크린 샷과 같이 conf.js 파일을 실행합니다.
아래 그림과 같이 출력이 나오면 Protractor의 구성 및 설치가 완료된 것입니다.
위 출력은 conf.js 파일의 소스 파일 선언 매개 변수에 빈 파일을 제공했기 때문에 사양이 없음을 보여줍니다. 그러나 위의 출력에서 각도기와 WebDriver가 모두 성공적으로 실행되고 있음을 알 수 있습니다.
설치 및 구성 문제
Protractor 및 WebDriver를 설치하고 구성하는 동안 다음과 같은 일반적인 문제가 발생할 수 있습니다.
셀레늄이 올바르게 설치되지 않았습니다.
WebDriver를 설치하는 동안 발생하는 가장 일반적인 문제입니다. 이 문제는 WebDriver를 업데이트하지 않으면 발생합니다. WebDriver를 업데이트해야합니다. 그렇지 않으면 Protractor 설치에 참조 할 수 없습니다.
테스트를 찾을 수 없음
또 다른 일반적인 문제는 Protractor를 실행 한 후 테스트를 찾을 수 없다는 것입니다. 이를 위해 상대 경로, 파일 이름 또는 확장자가 올바른지 확인해야합니다. 또한 conf.js 파일은 구성 파일 자체로 시작하므로 매우 신중하게 작성해야합니다.
앞서 논의한 바와 같이 Protractor는 Angular 및 AngularJS 애플리케이션을위한 오픈 소스 엔드-투-엔드 테스트 프레임 워크입니다. Node.js 프로그램입니다. 반면 Selenium은 Selenium Server, WebDriver API 및 WebDriver 브라우저 드라이버를 포함하는 브라우저 자동화 프레임 워크입니다.
셀레늄을 사용한 각도기
Protractor와 Selenium의 결합에 대해 이야기하면 Protractor는 Selenium 서버와 함께 작동하여 자동화 된 테스트 인프라를 제공 할 수 있습니다. 인프라는 브라우저 또는 모바일 장치에서 실행되는 각도 응용 프로그램과 사용자의 상호 작용을 시뮬레이션 할 수 있습니다. Protractor와 Selenium의 결합은 다음 다이어그램과 같이 테스트, 서버 및 브라우저의 세 파티션으로 나눌 수 있습니다.
Selenium WebDriver 프로세스
위의 다이어그램에서 보았 듯이 Selenium WebDriver를 사용한 테스트에는 다음 세 가지 프로세스가 포함됩니다.
- 테스트 스크립트
- 서버
- 브라우저
이 섹션에서는이 세 가지 프로세스 간의 통신에 대해 설명합니다.
테스트 스크립트와 서버 간의 통신
처음 두 프로세스-테스트 스크립트와 서버 간의 통신은 Selenium Server의 작동에 따라 다릅니다. 즉, Selenium 서버가 실행되는 방식이 테스트 스크립트와 서버 간의 통신 프로세스에 모양을 제공한다고 말할 수 있습니다.
Selenium 서버는 독립형 Selenium 서버 (selenium-server-standalone.jar)로 컴퓨터에서 로컬로 실행하거나 서비스 (Sauce Labs)를 통해 원격으로 실행할 수 있습니다. 독립형 Selenium 서버의 경우 Node.js와 셀레늄 서버 사이에 http 통신이 있습니다.
서버와 브라우저 간의 통신
서버는 테스트 스크립트에서 동일한 내용을 해석 한 후 브라우저에 명령을 전달하는 역할을합니다. 그렇기 때문에 서버와 브라우저에도 통신 매체가 필요하며 여기서 통신은JSON WebDriver Wire Protocol. 명령을 해석하는 데 사용되는 브라우저 드라이버로 확장 된 브라우저입니다.
Selenium WebDriver 프로세스 및 통신에 대한 위의 개념은 다음 다이어그램의 도움으로 이해할 수 있습니다.
Protractor로 작업하는 동안 첫 번째 프로세스 인 테스트 스크립트는 Node.js를 사용하여 실행되지만 브라우저에서 작업을 수행하기 전에 테스트중인 응용 프로그램이 안정화되었는지 확인하는 추가 명령을 보냅니다.
Selenium 서버 설정
Selenium Server는 테스트 스크립트와 브라우저 드라이버 사이에서 프록시 서버처럼 작동합니다. 기본적으로 테스트 스크립트에서 WebDriver로 명령을 전달하고 WebDriver의 응답을 테스트 스크립트로 반환합니다. 에 포함 된 Selenium 서버를 설정하기위한 다음 옵션이 있습니다.conf.js 테스트 스크립트 파일 −
독립형 Selenium 서버
로컬 컴퓨터에서 서버를 실행하려면 독립형 셀레늄 서버를 설치해야합니다. 독립형 셀레늄 서버를 설치하기위한 전제 조건은 JDK (Java Development Kit)입니다. 로컬 컴퓨터에 JDK가 설치되어 있어야합니다. 명령 줄에서 다음 명령을 실행하여 확인할 수 있습니다.
java -version
이제 수동으로 또는 테스트 스크립트에서 Selenium Server를 설치하고 시작할 수있는 옵션이 있습니다.
수동으로 Selenium 서버 설치 및 시작
Selenium 서버를 수동으로 설치하고 시작하려면 Protractor와 함께 제공되는 WebDriver-Manager 명령 줄 도구를 사용해야합니다. Selenium 서버를 설치하고 시작하는 단계는 다음과 같습니다.
Step 1− 첫 번째 단계는 Selenium 서버와 ChromeDriver를 설치하는 것입니다. 다음 명령을 실행하여 수행 할 수 있습니다.
webdriver-manager update
Step 2− 다음으로 서버를 시작해야합니다. 다음 명령을 실행하여 수행 할 수 있습니다.
webdriver-manager start
Step 3− 마지막으로 설정 파일의 seleniumAddress를 실행중인 서버의 주소로 설정해야합니다. 기본 주소는 다음과 같습니다.http://localhost:4444/wd/hub.
테스트 스크립트에서 Selenium 서버 시작
테스트 스크립트에서 Selenium 서버를 시작하려면 구성 파일에서 다음 옵션을 설정해야합니다.
Location of jar file − seleniumServerJar를 설정하여 config 파일에서 독립형 Selenium 서버의 jar 파일 위치를 설정해야합니다.
Specifying the port− 또한 독립형 Selenium 서버를 시작하는 데 사용할 포트를 지정해야합니다. seleniumPort를 설정하여 구성 파일에서 지정할 수 있습니다. 기본 포트는 4444입니다.
Array of command line options− 또한 서버에 전달할 명령 줄 옵션 배열을 설정해야합니다. seleniumArgs를 설정하여 구성 파일에서 지정할 수 있습니다. 명령 배열의 전체 목록이 필요한 경우 다음을 사용하여 서버를 시작하십시오.-help 깃발.
원격 Selenium 서버 작업
테스트를 실행하는 또 다른 옵션은 Selenium 서버를 원격으로 사용하는 것입니다. 서버를 원격으로 사용하기위한 전제 조건은 서버를 호스팅하는 서비스가있는 계정이 있어야한다는 것입니다. Protractor로 작업하는 동안 서버를 호스팅하는 다음 서비스에 대한 지원이 내장되어 있습니다.
TestObject
TestObject를 원격 Selenium Server로 사용하려면 TestObject 계정의 사용자 이름 인 testobjectUser와 TestObject 계정의 API 키인 testobjectKey를 설정해야합니다.
BrowserStack
BrowserStack을 원격 Selenium 서버로 사용하려면 browserstackUser, BrowserStack 계정의 사용자 이름 및 BrowserStack 계정의 API 키인 browserstackKey를 설정해야합니다.
소스 랩
Sauce Labs를 원격 Selenium 서버로 사용하려면 Sauce Labs 계정의 사용자 이름 인 sauceUser와 Sauce Labs 계정의 API 키인 SauceKey를 설정해야합니다.
Kobiton
Kobiton을 원격 Selenium 서버로 사용하려면 Kobiton 계정의 사용자 이름 인 kobitonUser와 Kobiton 계정의 API 키인 kobitonKey를 설정해야합니다.
Selenium 서버를 사용하지 않고 브라우저 드라이버에 직접 연결
테스트를 실행하는 또 다른 옵션은 Selenium 서버를 사용하지 않고 브라우저 드라이버에 직접 연결하는 것입니다. 각도기는 구성 파일에서 directConnect : true를 설정하여 Chrome 및 Firefox에 대해 Selenium Server를 사용하지 않고 직접 테스트 할 수 있습니다.
브라우저 설정
브라우저를 구성하고 설정하기 전에 Protractor에서 지원하는 브라우저를 알아야합니다. 다음은 Protractor에서 지원하는 브라우저 목록입니다-
- ChromeDriver
- FirefoxDriver
- SafariDriver
- IEDriver
- Appium-iOS/Safari
- Appium-Android/Chrome
- Selendroid
- PhantomJS
브라우저 설정 및 구성을 위해 브라우저 설정은 config 파일의 기능 개체 내에서 이루어지기 때문에 Protractor의 config 파일로 이동해야합니다.
Chrome 설정
Chrome 브라우저를 설정하려면 다음과 같이 기능 개체를 설정해야합니다.
capabilities: {
'browserName': 'chrome'
}
또한 chromeOptions에 중첩 된 Chrome 관련 옵션을 추가 할 수 있으며 전체 목록은 다음에서 볼 수 있습니다. https://sites.google.com/a/chromium.org/chromedriver/capabilities.
예를 들어, 오른쪽 상단에 FPS 카운터를 추가하려면 config 파일에서 다음과 같이 수행 할 수 있습니다.
capabilities: {
'browserName': 'chrome',
'chromeOptions': {
'args': ['show-fps-counter=true']
}
},
Firefox 설정
Firefox 브라우저를 설정하려면 다음과 같이 기능 개체를 설정해야합니다.
capabilities: {
'browserName': 'firefox'
}
또한 moz : firefoxOptions 객체에 중첩 된 Firefox 관련 옵션을 추가 할 수 있으며 전체 목록은 다음에서 볼 수 있습니다. https://github.com/mozilla/geckodriver#firefox-capabilities.
예를 들어, Firefox에서 안전 모드로 테스트를 실행하려면 구성 파일에서 다음과 같이 수행 할 수 있습니다.
capabilities: {
'browserName': 'firefox',
'moz:firefoxOptions': {
'args': ['—safe-mode']
}
},
다른 브라우저 설정
Chrome 또는 Firefox 이외의 다른 브라우저를 설정하려면 다음과 같은 별도의 바이너리를 설치해야합니다. https://docs.seleniumhq.org/download/.
PhantonJS 설정
실제로 PhantomJS는 충돌 문제로 인해 더 이상 지원되지 않습니다. 대신 헤드리스 Chrome 또는 헤드리스 Firefox를 사용하는 것이 좋습니다. 다음과 같이 설정할 수 있습니다.
헤드리스 Chrome을 설정하려면 다음과 같이 –headless 플래그로 Chrome을 시작해야합니다.
capabilities: {
'browserName': 'chrome',
'chromeOptions': {
'args': [“--headless”, “--disable-gpu”, “--window-size=800,600”]
}
},
헤드리스 Firefox를 설정하려면 다음을 사용하여 Firefox를 시작해야합니다. –headless 다음과 같이 플래그-
capabilities: {
'browserName': 'firefox',
'moz:firefoxOptions': {
'args': [“--headless”]
}
},
테스트를 위해 여러 브라우저 설정
여러 브라우저에 대해 테스트 할 수도 있습니다. 이를 위해 다음과 같이 multiCapabilities 구성 옵션을 사용해야합니다.
multiCapabilities: [{
'browserName': 'chrome'
},{
'browserName': 'firefox'
}]
어떤 프레임 워크?
Protractor는 두 개의 BDD (행동 주도 개발) 테스트 프레임 워크 인 Jasmine과 Mocha를 지원합니다. 두 프레임 워크 모두 JavaScript와 Node.js를 기반으로합니다. 테스트 작성 및 관리에 필요한 구문, 보고서 및 스캐 폴딩은 이러한 프레임 워크에서 제공됩니다.
다음으로 다양한 프레임 워크를 설치하는 방법을 살펴 봅니다.
Jasmine 프레임 워크
Protractor의 기본 테스트 프레임 워크입니다. Protractor를 설치하면 Jasmine 2.x 버전이 함께 제공됩니다. 별도로 설치할 필요가 없습니다.
모카 프레임 워크
Mocha는 기본적으로 Node.js에서 실행되는 또 다른 JavaScript 테스트 프레임 워크입니다. Mocha를 테스트 프레임 워크로 사용하려면 BDD (행동 주도 개발) 인터페이스와 Chai As Promised와 함께 Chai 어설 션을 사용해야합니다. 다음 명령을 사용하여 설치를 수행 할 수 있습니다.
npm install -g mocha
npm install chai
npm install chai-as-promised
보시다시피 mocha를 설치할 때 -g 옵션을 사용하는 것은 -g 옵션을 사용하여 Protractor를 전역 적으로 설치했기 때문입니다. 설치 후 테스트 파일에서 Chai를 요구하고 설정해야합니다. 다음과 같이 할 수 있습니다-
var chai = require('chai');
var chaiAsPromised = require('chai-as-promised');
chai.use(chaiAsPromised);
var expect = chai.expect;
그런 다음 Chai As Promised를 그대로 사용할 수 있습니다.
expect(myElement.getText()).to.eventually.equal('some text');
이제 프레임 워크 'mocha'를 추가하여 프레임 워크 속성을 구성 파일의 mocha로 설정해야합니다. mocha에 대한 'reporter'및 'slow'와 같은 옵션은 다음과 같이 구성 파일에 추가 할 수 있습니다.
mochaOpts: {
reporter: "spec", slow: 3000
}
오이 프레임 워크
Cucumber를 테스트 프레임 워크로 사용하려면 프레임 워크 옵션을 사용하여 Protractor와 통합해야합니다. custom. 다음 명령을 사용하여 설치를 수행 할 수 있습니다.
npm install -g cucumber
npm install --save-dev protractor-cucumber-framework
보시다시피 Cucumber를 설치하는 동안 -g 옵션을 사용하는 것은 우리가 Protractor를 전역 적으로 설치했기 때문입니다. 다음으로 프레임 워크 속성을 다음과 같이 설정해야합니다.custom 오이 Conf.js라는 구성 파일에 프레임 워크 : 'custom'및 frameworkPath : 'Protractor-cucumber-framework'를 추가하여 구성 파일의.
아래에 표시된 샘플 코드는 Protractor로 오이 기능 파일을 실행하는 데 사용할 수있는 기본 cucumberConf.js 파일입니다.
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
baseUrl: 'https://angularjs.org/',
capabilities: {
browserName:'Firefox'
},
framework: 'custom',
frameworkPath: require.resolve('protractor-cucumber-framework'),
specs: [
'./cucumber/*.feature'
],
// cucumber command line options
cucumberOpts: {
require: ['./cucumber/*.js'],
tags: [],
strict: true,
format: ["pretty"],
'dry-run': false,
compiler: []
},
onPrepare: function () {
browser.manage().window().maximize();
}
};
이 장에서는 각도기에서 첫 번째 테스트를 작성하는 방법을 이해하겠습니다.
각도기에 필요한 파일
각도기는 실행하려면 다음 두 파일이 필요합니다-
사양 또는 테스트 파일
Protractor를 실행하는 데 중요한 파일 중 하나입니다. 이 파일에서 실제 테스트 코드를 작성합니다. 테스트 코드는 테스트 프레임 워크의 구문을 사용하여 작성됩니다.
예를 들어, 우리가 Jasmine 다음의 구문을 사용하여 테스트 코드가 작성됩니다. Jasmine. 이 파일에는 테스트의 모든 기능 흐름과 어설 션이 포함됩니다.
간단히 말해서이 파일에는 응용 프로그램과 상호 작용하는 논리 및 로케이터가 포함되어 있다고 말할 수 있습니다.
예
다음은 URL로 이동하고 페이지 제목을 확인하는 테스트 케이스가있는 간단한 스크립트 인 TestSpecification.js입니다.
//TestSpecification.js
describe('Protractor Demo', function() {
it('to check the page title', function() {
browser.ignoreSynchronization = true;
browser.get('https://www.tutorialspoint.com/tutorialslibrary.htm');
browser.driver.getTitle().then(function(pageTitle) {
expect(pageTitle).toEqual('Free Online Tutorials and Courses');
});
});
});
코드 설명
위 사양 파일의 코드는 다음과 같이 설명 할 수 있습니다.
브라우저
모든 브라우저 수준 명령을 처리하기 위해 Protractor에서 만든 전역 변수입니다. 기본적으로 WebDriver 인스턴스를 둘러싼 래퍼입니다. browser.get ()은 Protractor에게 특정 페이지를로드하도록 지시하는 간단한 Selenium 메소드입니다.
describe 과 it− 둘 다 Jasmine 테스트 프레임 워크의 구문입니다. 그만큼’Describe’ 테스트 케이스의 종단 간 흐름을 포함하는 데 사용되는 반면 ‘it’일부 테스트 시나리오가 포함되어 있습니다. 우리는 여러‘it’ 테스트 케이스 프로그램의 블록.
Expect − 웹 페이지 제목을 미리 정의 된 데이터와 비교하는 주장입니다.
ignoreSynchronization− 각도가 아닌 웹 사이트를 테스트하려고 할 때 사용하는 브라우저의 태그입니다. 각도기는 각도 웹 사이트에서만 작동 할 것으로 예상하지만 각도가 아닌 웹 사이트로 작업하려면이 태그를 다음으로 설정해야합니다.“true”.
구성 파일
이름에서 알 수 있듯이이 파일은 모든 각도기 구성 옵션에 대한 설명을 제공합니다. 기본적으로 각도기에게 다음을 알려줍니다.
- 테스트 또는 사양 파일을 찾을 수있는 위치
- 선택할 브라우저
- 사용할 테스트 프레임 워크
- Selenium 서버와 대화 할 위치
예
다음은 간단한 스크립트 config.js입니다.
// config.js
exports.config = {
directConnect: true,
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
// Framework to use. Jasmine is recommended.
framework: 'jasmine',
// Spec patterns are relative to the current working directory when
// protractor is called.
specs: ['TestSpecification.js'],
코드 설명
세 가지 기본 매개 변수가있는 위 구성 파일의 코드는 다음과 같이 설명 할 수 있습니다.
기능 매개 변수
이 매개 변수는 브라우저의 이름을 지정하는 데 사용됩니다. conf.js 파일의 다음 코드 블록에서 볼 수 있습니다.
exports.config = {
directConnect: true,
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
위에서 볼 수 있듯이 여기에 제공된 브라우저의 이름은 Protractor의 기본 브라우저 인 'chrome'입니다. 브라우저 이름을 변경할 수도 있습니다.
프레임 워크 매개 변수
이 매개 변수는 테스트 프레임 워크의 이름을 지정하는 데 사용됩니다. config.js 파일의 다음 코드 블록에서 볼 수 있습니다.
exports.config = {
directConnect: true,
// Framework to use. Jasmine is recommended.
framework: 'jasmine',
여기서는 'jasmine'테스트 프레임 워크를 사용합니다.
소스 파일 선언 매개 변수
이 매개 변수는 소스 파일 선언의 이름을 지정하는 데 사용됩니다. conf.js 파일의 다음 코드 블록에서 볼 수 있습니다.
exports.config = {
directConnect: true,
// Spec patterns are relative to the current working
directory when protractor is called.
specs: ['TsetSpecification.js'],
위에서 본 것처럼 여기에 제공된 소스 파일 선언의 이름은 다음과 같습니다. ‘TestSpecification.js’. 이 예에서는 이름이 지정된 사양 파일을 만들었 기 때문입니다.TestSpecification.js.
코드 실행
Protractor를 실행하는 데 필요한 파일과 코딩에 대한 기본적인 이해를 얻었으므로 예제를 실행 해 보겠습니다. 이 예제를 실행하려면 다음 단계를 따를 수 있습니다.
Step 1 − 먼저 명령 프롬프트를 엽니 다.
Step 2 − 다음으로 config.js라는 파일을 저장 한 디렉토리로 이동해야합니다. TestSpecification.js.
Step 3 − 이제 Protrcator config.js 명령을 실행하여 config.js 파일을 실행합니다.
아래 스크린 샷은 위의 예제 실행 단계를 설명합니다.
스크린 샷에서 테스트가 통과되었음을 알 수 있습니다.
이제 각도가 아닌 웹 사이트를 테스트하고 ignoreSynchronization 태그를 true로 설정하지 않으면 코드를 실행 한 후 "Angular를 페이지에서 찾을 수 없습니다"라는 오류가 발생합니다.
다음 스크린 샷에서 볼 수 있습니다.
보고서 생성
지금까지 테스트 케이스를 실행하는 데 필요한 파일과 해당 코드에 대해 논의했습니다. 각도기는 또한 테스트 케이스에 대한 보고서를 생성 할 수 있습니다. 이를 위해 Jasmine을 지원합니다. JunitXMLReporter를 사용하여 테스트 실행 보고서를 자동으로 생성 할 수 있습니다.
그러나 그 전에 다음 명령을 사용하여 Jasmine reporter를 설치해야합니다.
npm install -g jasmine-reporters
보시다시피 Jasmine Reporters를 설치하는 동안 -g 옵션을 사용하는 것은 -g 옵션을 사용하여 Protractor를 전역 적으로 설치했기 때문입니다.
jasmine-reporters를 성공적으로 설치 한 후 이전에 사용한 config.js 파일에 다음 코드를 추가해야합니다.
onPrepare: function(){ //configure junit xml report
var jasmineReporters = require('jasmine-reporters');
jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
consolidateAll: true,
filePrefix: 'guitest-xmloutput',
savePath: 'test/reports'
}));
이제 새로운 config.js 파일은 다음과 같습니다.
// An example configuration file.
exports.config = {
directConnect: true,
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
// Framework to use. Jasmine is recommended.
framework: 'jasmine',
// Spec patterns are relative to the current working directory when
// protractor is called.
specs: ['TestSpecification.js'],
//framework: "jasmine2", //must set it if you use JUnitXmlReporter
onPrepare: function(){ //configure junit xml report
var jasmineReporters = require('jasmine-reporters');
jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
consolidateAll: true,
filePrefix: 'guitest-xmloutput',
savePath: 'reports'
}));
},
};
위의 구성 파일을 동일한 방식으로 실행 한 후 이전에 실행 한 다음 루트 디렉터리 아래에 보고서가 포함 된 XML 파일을 생성합니다. reports폴더. 테스트가 성공하면 보고서는 다음과 같습니다.
그러나 테스트에 실패하면 보고서는 다음과 같이 표시됩니다.
각도기-핵심 APIS
이 장에서는 각도기 기능의 핵심 인 다양한 핵심 API를 이해할 수 있습니다.
각도기 API의 중요성
Protractor는 웹 사이트의 현재 상태를 얻기 위해 다음과 같은 작업을 수행하기 위해 매우 중요한 광범위한 API를 제공합니다.
- 테스트 할 웹 페이지의 DOM 요소를 가져옵니다.
- DOM 요소와 상호 작용.
- 그들에게 작업을 할당합니다.
- 그들에게 정보 공유.
위의 작업을 수행하려면 Protractor API를 이해하는 것이 매우 중요합니다.
다양한 각도기 API
Protractor는 Node.js의 WebDriver 바인딩 인 Selenium-WebDriver를 둘러싼 래퍼라는 것을 알고 있습니다. 각도기에는 다음과 같은 API가 있습니다-
브라우저
탐색, 페이지 전체 정보 등과 같은 브라우저 수준 명령을 처리하는 데 사용되는 WebDriver 인스턴스를 둘러싼 래퍼입니다. 예를 들어 browser.get 메서드는 페이지를로드합니다.
요소
테스트중인 페이지에서 DOM 요소를 검색하고 상호 작용하는 데 사용됩니다. 이를 위해 요소를 찾기위한 하나의 매개 변수가 필요합니다.
로케이터 (기준)
요소 찾기 전략의 모음입니다. 예를 들어, 요소는 CSS 선택기, ID 또는 ng-model로 바인딩 된 다른 속성으로 찾을 수 있습니다.
다음으로 이러한 API와 해당 기능에 대해 자세히 설명합니다.
브라우저 API
위에서 설명한 것처럼 브라우저 수준 명령을 처리하기위한 WebDriver 인스턴스를 둘러싼 래퍼입니다. 다음과 같이 다양한 기능을 수행합니다.
기능 및 설명
ProtractorBrowser API의 기능은 다음과 같습니다.
browser.angularAppRoot
브라우저 API의이 기능은 Angular를 찾을 요소에 대한 CSS 선택기를 설정합니다. 일반적으로이 함수는 'body'에 있지만 ng-app의 경우 페이지의 하위 섹션에 있습니다. 하위 요소 일 수도 있습니다.
browser.waitForAngularEnabled
이 브라우저 API 기능은 true 또는 false로 설정할 수 있습니다. 이름에서 알 수 있듯이이 함수가 false로 설정되면 Protractor는 Angular를 기다리지 않습니다.$http and $브라우저와 상호 작용하기 전에 완료 할 시간 초과 작업. 값을 전달하지 않고 waitForAngularEnabled ()를 호출하여 현재 상태를 변경하지 않고 읽을 수도 있습니다.
browser.getProcessedConfig
이 브라우저 API 기능의 도움으로 현재 실행중인 사양 및 기능을 포함하여 처리 된 구성 개체를 가져올 수 있습니다.
browser.forkNewDriverInstance
이름에서 알 수 있듯이이 함수는 대화 형 테스트에 사용할 다른 브라우저 인스턴스를 포크합니다. 제어 흐름을 활성화 및 비활성화 한 상태에서 실행할 수 있습니다. 두 경우에 대한 예가 아래에 나와 있습니다.
Example 1
달리는 browser.forkNewDriverInstance() 제어 흐름 활성화-
var fork = browser.forkNewDriverInstance();
fork.get(‘page1’);
Example 2
달리는 browser.forkNewDriverInstance() 제어 흐름 비활성화-
var fork = await browser.forkNewDriverInstance().ready;
await forked.get(‘page1’);
browser.restart
이름에서 알 수 있듯이 브라우저 인스턴스를 닫고 새 인스턴스를 만들어 브라우저를 다시 시작합니다. 제어 흐름을 활성화 및 비활성화 한 상태로 실행할 수도 있습니다. 두 경우에 대한 예가 아래에 나와 있습니다.
Example 1 − 달리기 browser.restart() 제어 흐름 활성화-
browser.get(‘page1’);
browser.restart();
browser.get(‘page2’);
Example 2 − 달리기 browser.forkNewDriverInstance() 제어 흐름 비활성화-
await browser.get(‘page1’);
await browser.restart();
await browser.get(‘page2’);
browser.restartSync
browser.restart () 함수와 유사합니다. 유일한 차이점은 새 브라우저 인스턴스로 해결되는 promise를 반환하지 않고 새 브라우저 인스턴스를 직접 반환한다는 것입니다. 제어 흐름이 활성화 된 경우에만 실행할 수 있습니다.
Example − 달리기 browser.restartSync() 제어 흐름 활성화-
browser.get(‘page1’);
browser.restartSync();
browser.get(‘page2’);
browser.useAllAngular2AppRoots
이름에서 알 수 있듯이 Angular2 와만 호환됩니다. 요소를 찾거나 안정성을 기다리는 동안 페이지에서 사용 가능한 모든 각도 앱을 검색합니다.
browser.waitForAngular
이 브라우저 API 함수는 WebDriver에게 Angular가 렌더링을 완료하고 미해결 항목이 없을 때까지 기다리도록 지시합니다. $http or $계속하기 전에 시간 초과 호출.
browser.findElement
이름에서 알 수 있듯이이 브라우저 API 함수는 요소를 검색하기 전에 Angular가 렌더링을 완료 할 때까지 기다립니다.
browser.isElementPresent
이름에서 알 수 있듯이이 브라우저 API 함수는 요소가 페이지에 있는지 여부를 테스트합니다.
browser.addMockModule
Protractor.get 메서드가 호출 될 때마다 Angular 전에로드 할 모듈을 추가합니다.
Example
browser.addMockModule('modName', function() {
angular.module('modName', []).value('foo', 'bar');
});
browser.clearMockModules
browser.addMockModule과 달리 등록 된 모의 모듈 목록을 지 웁니다.
browser.removeMockModule
이름에서 알 수 있듯이 레지스터 모의 모듈을 제거합니다. 예 : browser.removeMockModule ( 'modName');
browser.getRegisteredMockModules
browser.clearMockModule과 반대로 등록 된 모의 모듈 목록을 가져옵니다.
browser.get
browser.get ()을 사용하여 브라우저를 특정 웹 주소로 이동하고 Angular로드 전에 해당 페이지에 대한 모의 모듈을로드 할 수 있습니다.
Example
browser.get(url);
browser.get('http://localhost:3000');
// This will navigate to the localhost:3000 and will load mock module if needed
browser.refresh
이름에서 알 수 있듯이 현재 페이지를 다시로드하고 Angular 이전에 모의 모듈을로드합니다.
browser.navigate
이름에서 알 수 있듯이 탐색 메서드를 탐색 개체에 다시 혼합하여 이전과 같이 호출되도록하는 데 사용됩니다. 예 : driver.navigate (). refresh ().
browser.setLocation
페이지 내 탐색을 사용하여 다른 페이지를 탐색하는 데 사용됩니다.
Example
browser.get('url/ABC');
browser.setLocation('DEF');
expect(browser.getCurrentUrl())
.toBe('url/DEF');
ABC에서 DEF 페이지로 이동합니다.
browser.debugger
이름에서 알 수 있듯이 이것은 각도기 디버그와 함께 사용해야합니다. 이 함수는 기본적으로 테스트를 일시 중지하고 브라우저 콘솔에서 디버깅을 수행 할 수 있도록 도우미 기능을 브라우저에 삽입하는 작업을 제어 흐름에 추가합니다.
browser.pause
WebDriver 테스트를 디버깅하는 데 사용됩니다. 우리는 사용할 수 있습니다browser.pause() 제어 흐름의 해당 지점에서 각도기 디버거로 들어가는 테스트에서.
Example
element(by.id('foo')).click();
browser.pause();
// Execution will stop before the next click action.
element(by.id('bar')).click();
browser.controlFlowEnabled
제어 흐름이 활성화되었는지 여부를 결정하는 데 사용됩니다.
각도기-핵심 APIS (CONTD…)
이 장에서는 Protractor의 핵심 API에 대해 더 알아 보겠습니다.
Elements API
요소는 각도기에 의해 노출되는 전역 함수 중 하나입니다. 이 함수는 로케이터를 가져와 다음을 반환합니다.
- 로케이터를 기반으로 단일 요소를 찾는 ElementFinder.
- 로케이터를 기반으로 요소 배열을 찾는 ElementArrayFinder.
위의 두 가지 모두 아래에서 설명하는 연결 방법을 지원합니다.
ElementArrayFinder의 연결 기능 및 설명
다음은 ElementArrayFinder의 기능입니다-
element.all(locator).clone
이름에서 알 수 있듯이이 함수는 ElementArrayFinder와 같은 요소 배열의 얕은 복사본을 만듭니다.
element.all(locator).all(locator)
이 함수는 기본적으로 비어 있거나 자식 요소를 포함 할 수있는 새 ElementArrayFinder를 반환합니다. 다음과 같이 여러 요소를 배열로 선택하는 데 사용할 수 있습니다.
Example
element.all(locator).all(locator)
elementArr.all(by.css(‘.childselector’));
// it will return another ElementFindArray as child element based on child locator.
element.all(locator).filter(filterFn)
이름에서 알 수 있듯이 ElementArrayFinder 내의 각 요소에 필터 함수를 적용한 후 필터 함수를 통과하는 모든 요소와 함께 새 ElementArrayFinder를 반환합니다. 기본적으로 두 개의 인수가 있습니다. 첫 번째는 ElementFinder이고 두 번째는 인덱스입니다. 페이지 개체에서도 사용할 수 있습니다.
Example
View
<ul class = "items">
<li class = "one">First</li>
<li class = "two">Second</li>
<li class = "three">Third</li>
</ul>
Code
element.all(by.css('.items li')).filter(function(elem, index) {
return elem.getText().then(function(text) {
return text === 'Third';
});
}).first().click();
element.all(locator).get(index)
이것의 도움으로 ElementArrayFinder 내의 요소를 인덱스별로 얻을 수 있습니다. 인덱스는 0에서 시작하고 음수 인덱스는 래핑됩니다.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
let list = element.all(by.css('.items li'));
expect(list.get(0).getText()).toBe('First');
expect(list.get(1).getText()).toBe('Second');
element.all(locator).first()
이름에서 알 수 있듯이 ElementArrayFinder의 첫 번째 요소를 가져옵니다. 기본 요소를 검색하지 않습니다.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
let first = element.all(by.css('.items li')).first();
expect(first.getText()).toBe('First');
element.all(locator).last()
이름에서 알 수 있듯이 ElementArrayFinder의 마지막 요소를 가져옵니다. 기본 요소를 검색하지 않습니다.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
let first = element.all(by.css('.items li')).last();
expect(last.getText()).toBe('Third');
element.all(locator).all(selector)
$$ 호출이 연결될 수있을 때 부모 내에서 요소의 배열을 찾는 데 사용됩니다.
Example
View
<div class = "parent">
<ul>
<li class = "one">First</li>
<li class = "two">Second</li>
<li class = "three">Third</li>
</ul>
</div>
Code
let items = element(by.css('.parent')).$$('li');
element.all(locator).count()
이름에서 알 수 있듯이 ElementArrayFinder가 나타내는 요소의 수를 계산합니다. 기본 요소를 검색하지 않습니다.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
let list = element.all(by.css('.items li'));
expect(list.count()).toBe(3);
element.all(locator).isPresent()
파인더와 요소를 일치시킵니다. true 또는 false를 반환 할 수 있습니다. 파인더와 일치하는 요소가 있으면 True이고 그렇지 않으면 False입니다.
Example
expect($('.item').isPresent()).toBeTruthy();
element.all(locator).locator
이름에서 알 수 있듯이 가장 관련성이 높은 로케이터를 반환합니다.
Example
$('#ID1').locator();
// returns by.css('#ID1')
$('#ID1').$('#ID2').locator();
// returns by.css('#ID2')
$$('#ID1').filter(filterFn).get(0).click().locator();
// returns by.css('#ID1')
element.all(locator).then(thenFunction)
ElementArrayFinder가 나타내는 요소를 검색합니다.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
element.all(by.css('.items li')).then(function(arr) {
expect(arr.length).toEqual(3);
});
element.all(locator).each(eachFunction)
이름에서 알 수 있듯이 ElementArrayFinder가 나타내는 각 ElementFinder에서 입력 함수를 호출합니다.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
element.all(by.css('.items li')).each(function(element, index) {
// It will print First 0, Second 1 and Third 2.
element.getText().then(function (text) {
console.log(index, text);
});
});
element.all(locator).map(mapFunction)
이름에서 알 수 있듯이 ElementArrayFinder 내의 각 요소에 맵 기능을 적용합니다. 두 가지 주장이 있습니다. 첫 번째는 ElementFinder이고 두 번째는 인덱스입니다.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
let items = element.all(by.css('.items li')).map(function(elm, index) {
return {
index: index,
text: elm.getText(),
class: elm.getAttribute('class')
};
});
expect(items).toEqual([
{index: 0, text: 'First', class: 'one'},
{index: 1, text: 'Second', class: 'two'},
{index: 2, text: 'Third', class: 'three'}
]);
element.all(locator).reduce(reduceFn)
이름에서 알 수 있듯이 누산기 및 로케이터를 사용하여 찾은 모든 요소에 대해 축소 기능을 적용합니다. 이 함수는 모든 요소를 단일 값으로 줄입니다.
Example
View
<ul class = "items">
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
Code
let value = element.all(by.css('.items li')).reduce(function(acc, elem) {
return elem.getText().then(function(text) {
return acc + text + ' ';
});
}, '');
expect(value).toEqual('First Second Third ');
element.all(locator).evaluate
이름에서 알 수 있듯이 입력이 현재 기본 요소의 범위에 있는지 여부를 평가합니다.
Example
View
<span class = "foo">{{letiableInScope}}</span>
Code
let value =
element.all(by.css('.foo')).evaluate('letiableInScope');
element.all(locator).allowAnimations
이름에서 알 수 있듯이 현재 기본 요소에서 애니메이션이 허용되는지 여부를 결정합니다.
Example
element(by.css('body')).allowAnimations(false);
ElementFinder의 연결 기능 및 설명
ElementFinder의 연결 기능과 설명-
element(locator).clone
이름에서 알 수 있듯이이 함수는 ElementFinder의 얕은 복사본을 만듭니다.
element(locator).getWebElement()
이 ElementFinder가 나타내는 WebElement를 반환하고 요소가없는 경우 WebDriver 오류가 발생합니다.
Example
View
<div class="parent">
some text
</div>
Code
// All the four following expressions are equivalent.
$('.parent').getWebElement();
element(by.css('.parent')).getWebElement();
browser.driver.findElement(by.css('.parent'));
browser.findElement(by.css('.parent'));
element(locator).all(locator)
부모 내에서 요소 배열을 찾습니다.
Example
View
<div class = "parent">
<ul>
<li class = "one">First</li>
<li class = "two">Second</li>
<li class = "three">Third</li>
</ul>
</div>
Code
let items = element(by.css('.parent')).all(by.tagName('li'));
element(locator).element(locator)
부모 내에서 요소를 찾습니다.
Example
View
<div class = "parent">
<div class = "child">
Child text
<div>{{person.phone}}</div>
</div>
</div>
Code
// Calls Chain 2 element.
let child = element(by.css('.parent')).
element(by.css('.child'));
expect(child.getText()).toBe('Child text\n981-000-568');
// Calls Chain 3 element.
let triple = element(by.css('.parent')).
element(by.css('.child')).
element(by.binding('person.phone'));
expect(triple.getText()).toBe('981-000-568');
element(locator).all(selector)
$$ 호출이 연결될 수있을 때 부모 내에서 요소 배열을 찾습니다.
Example
View
<div class = "parent">
<ul>
<li class = "one">First</li>
<li class = "two">Second</li>
<li class = "three">Third</li>
</ul>
</div>
Code
let items = element(by.css('.parent')).$$('li'));
element(locator).$(locator)
$ 호출이 연결될 때 부모 내에서 요소를 찾습니다.
Example
View
<div class = "parent">
<div class = "child">
Child text
<div>{{person.phone}}</div>
</div>
</div>
Code
// Calls Chain 2 element.
let child = element(by.css('.parent')).
$('.child')); expect(child.getText()).toBe('Child text\n981-000-568'); // Calls Chain 3 element. let triple = element(by.css('.parent')). $('.child')).
element(by.binding('person.phone'));
expect(triple.getText()).toBe('981-000-568');
element(locator).isPresent()
요소가 페이지에 표시되는지 여부를 결정합니다.
Example
View
<span>{{person.name}}</span>
Code
expect(element(by.binding('person.name')).isPresent()).toBe(true);
// will check for the existence of element
expect(element(by.binding('notPresent')).isPresent()).toBe(false);
// will check for the non-existence of element
element(locator).isElementPresent()
element (locator) .isPresent ()와 동일합니다. 유일한 차이점은 현재 요소 찾기가 아닌 하위 위치 지정자에 의해 식별 된 요소가 있는지 여부를 확인한다는 것입니다.
element.all(locator).evaluate
이름에서 알 수 있듯이 현재 기본 요소의 범위에 있는지 여부에 관계없이 입력을 평가합니다.
Example
View
<span id = "foo">{{letiableInScope}}</span>
Code
let value = element(by.id('.foo')).evaluate('letiableInScope');
element(locator).allowAnimations
이름에서 알 수 있듯이 현재 기본 요소에서 애니메이션이 허용되는지 여부를 결정합니다.
Example
element(by.css('body')).allowAnimations(false);
element(locator).equals
이름에서 알 수 있듯이 요소가 동일한 지 비교합니다.
로케이터 (기준) API
기본적으로 바인딩, 모델 등을 통해 Angular 응용 프로그램에서 요소를 찾는 방법을 제공하는 요소 로케이터 전략 모음입니다.
Functions and their descriptions
ProtractorLocators API의 기능은 다음과 같습니다.
by.addLocator(locatorName,fuctionOrScript)
요소 (by.locatorName (args))와 함께 사용할 수있는이 ProtrcatorBy 인스턴스에 로케이터를 추가합니다.
Example
View
<button ng-click = "doAddition()">Go!</button>
Code
// Adding the custom locator.
by.addLocator('buttonTextSimple',
function(buttonText, opt_parentElement, opt_rootSelector) {
var using = opt_parentElement || document,
buttons = using.querySelectorAll('button');
return Array.prototype.filter.call(buttons, function(button) {
return button.textContent === buttonText;
});
});
element(by.buttonTextSimple('Go!')).click();// Using the custom locator.
by.binding
이름에서 알 수 있듯이 텍스트 바인딩으로 요소를 찾습니다. 입력 문자열을 포함하는 변수에 바인딩 된 모든 요소가 반환되도록 부분 일치가 수행됩니다.
Example
View
<span>{{person.name}}</span>
<span ng-bind = "person.email"></span>
Code
var span1 = element(by.binding('person.name'));
expect(span1.getText()).toBe('Foo');
var span2 = element(by.binding('person.email'));
expect(span2.getText()).toBe('[email protected]');
by.exactbinding
이름에서 알 수 있듯이 정확한 바인딩으로 요소를 찾습니다.
Example
View
<spangt;{{ person.name }}</spangt;
<span ng-bind = "person-email"gt;</spangt;
<spangt;{{person_phone|uppercase}}</span>
Code
expect(element(by.exactBinding('person.name')).isPresent()).toBe(true);
expect(element(by.exactBinding('person-email')).isPresent()).toBe(true);
expect(element(by.exactBinding('person')).isPresent()).toBe(false);
expect(element(by.exactBinding('person_phone')).isPresent()).toBe(true);
expect(element(by.exactBinding('person_phone|uppercase')).isPresent()).toBe(true);
expect(element(by.exactBinding('phone')).isPresent()).toBe(false);
by.model(modelName)
이름에서 알 수 있듯이 ng-model 표현식으로 요소를 찾습니다.
Example
View
<input type = "text" ng-model = "person.name">
Code
var input = element(by.model('person.name'));
input.sendKeys('123');
expect(input.getAttribute('value')).toBe('Foo123');
by.buttonText
이름에서 알 수 있듯이 텍스트로 버튼을 찾습니다.
Example
View
<button>Save</button>
Code
element(by.buttonText('Save'));
by.partialButtonText
이름에서 알 수 있듯이 부분 텍스트로 버튼을 찾습니다.
Example
View
<button>Save my file</button>
Code
element(by.partialButtonText('Save'));
by.repeater
이름에서 알 수 있듯이 ng-repeat 내에서 요소를 찾습니다.
Example
View
<div ng-repeat = "cat in pets">
<span>{{cat.name}}</span>
<span>{{cat.age}}</span>
<</div>
<div class = "book-img" ng-repeat-start="book in library">
<span>{{$index}}</span>
</div>
<div class = "book-info" ng-repeat-end>
<h4>{{book.name}}</h4>
<p>{{book.blurb}}</p>
</div>
Code
var secondCat = element(by.repeater('cat in
pets').row(1)); // It will return the DIV for the second cat.
var firstCatName = element(by.repeater('cat in pets').
row(0).column('cat.name')); // It will return the SPAN for the first cat's name.
by.exactRepeater
이름에서 알 수 있듯이 정확한 리피터로 요소를 찾습니다.
Example
View
<li ng-repeat = "person in peopleWithRedHair"></li>
<li ng-repeat = "car in cars | orderBy:year"></li>
Code
expect(element(by.exactRepeater('person in
peopleWithRedHair')).isPresent())
.toBe(true);
expect(element(by.exactRepeater('person in
people')).isPresent()).toBe(false);
expect(element(by.exactRepeater('car in cars')).isPresent()).toBe(true);
by.cssContainingText
이름에서 알 수 있듯이 CSS로 정확한 문자열을 포함하는 요소를 찾습니다.
Example
View
<ul>
<li class = "pet">Dog</li>
<li class = "pet">Cat</li>
</ul>
Code
var dog = element(by.cssContainingText('.pet', 'Dog'));
// It will return the li for the dog, but not for the cat.
by.options(optionsDescriptor)
이름에서 알 수 있듯이 ng-options 표현식으로 요소를 찾습니다.
Example
View
<select ng-model = "color" ng-options = "c for c in colors">
<option value = "0" selected = "selected">red</option>
<option value = "1">green</option>
</select>
Code
var allOptions = element.all(by.options('c for c in colors'));
expect(allOptions.count()).toEqual(2);
var firstOption = allOptions.first();
expect(firstOption.getText()).toEqual('red');
by.deepCSS(selector)
이름에서 알 수 있듯이 Shadow DOM 내에서 CSS 선택기로 요소를 찾습니다.
Example
View
<div>
<span id = "outerspan">
<"shadow tree">
<span id = "span1"></span>
<"shadow tree">
<span id = "span2"></span>
</>
</>
</div>
Code
var spans = element.all(by.deepCss('span'));
expect(spans.count()).toEqual(3);
각도기-개체
이 장에서는 각도기의 개체에 대해 자세히 설명합니다.
페이지 개체 란 무엇입니까?
페이지 개체는 테스트 유지 관리를 강화하고 코드 중복을 줄이기 위해 e2e 테스트를 작성하는 데 널리 사용되는 디자인 패턴입니다. AUT (테스트중인 애플리케이션) 페이지에 대한 인터페이스 역할을하는 객체 지향 클래스로 정의 될 수 있습니다. 그러나 페이지 개체에 대해 자세히 알아보기 전에 자동화 된 UI 테스트의 문제와이를 처리하는 방법을 이해해야합니다.
자동화 된 UI 테스트의 과제
다음은 UI 테스트 자동화와 관련된 몇 가지 일반적인 문제입니다.
UI 변경
UI 테스트 작업 중 가장 일반적인 문제는 UI에서 발생하는 변경입니다. 예를 들어, 대부분의 경우 버튼이나 텍스트 상자 등이 일반적으로 변경되어 UI 테스트에 문제가 발생합니다.
DSL (Domain Specific Language) 지원 부족
UI 테스트의 또 다른 문제는 DSL 지원이 없다는 것입니다. 이 문제로 인해 테스트 대상을 이해하기가 매우 어려워집니다.
많은 반복 / 코드 중복
UI 테스트의 다음 일반적인 문제는 반복 또는 코드 중복이 많다는 것입니다. 다음 코드 줄의 도움으로 이해할 수 있습니다-
element(by.model(‘event.name’)).sendKeys(‘An Event’);
element(by.model(‘event.name’)).sendKeys(‘Module 3’);
element(by.model(‘event.name’));
힘든 유지 관리
위의 과제로 인해 유지 관리가 골치 아파집니다. 모든 인스턴스를 찾아서 새 이름, 선택기 및 기타 코드로 바꿔야하기 때문입니다. 또한 리팩토링에 맞춰 테스트를 유지하기 위해 많은 시간을 할애해야합니다.
깨진 테스트
UI 테스트의 또 다른 과제는 테스트에서 많은 실패가 발생한다는 것입니다.
문제를 처리하는 방법
우리는 UI 테스트의 몇 가지 일반적인 문제를 보았습니다. 이러한 문제를 처리하는 방법 중 일부는 다음과 같습니다.
수동으로 참조 업데이트
위의 문제를 처리하는 첫 번째 옵션은 참조를 수동으로 업데이트하는 것입니다. 이 옵션의 문제점은 테스트뿐만 아니라 코드에서 수동으로 변경해야한다는 것입니다. 이것은 하나 또는 두 개의 테스트 파일이있을 때 수행 할 수 있지만 프로젝트에 수백 개의 테스트 파일이있는 경우 어떻게됩니까?
페이지 개체 사용
위의 문제를 처리하는 또 다른 옵션은 페이지 개체를 사용하는 것입니다. 페이지 객체는 기본적으로 Angular 템플릿의 속성을 캡슐화하는 일반 JavaScript입니다. 예를 들어, 다음 사양 파일은 차이점을 이해하기 위해 페이지 객체없이 작성됩니다.
Without Page Objects
describe('angularjs homepage', function() {
it('should greet the named user', function() {
browser.get('http://www.angularjs.org');
element(by.model('yourName')).sendKeys('Julie');
var greeting = element(by.binding('yourName'));
expect(greeting.getText()).toEqual('Hello Julie!');
});
});
With Page Objects
페이지 개체로 코드를 작성하려면 먼저 페이지 개체를 만들어야합니다. 따라서 위 예제의 페이지 객체는 다음과 같이 보일 수 있습니다.
var AngularHomepage = function() {
var nameInput = element(by.model('yourName'));
var greeting = element(by.binding('yourName'));
this.get = function() {
browser.get('http://www.angularjs.org');
};
this.setName = function(name) {
nameInput.sendKeys(name);
};
this.getGreetingText = function() {
return greeting.getText();
};
};
module.exports = new AngularHomepage();
페이지 개체를 사용하여 테스트 구성
위의 예에서 UI 테스트 문제를 처리하기 위해 페이지 개체를 사용하는 것을 확인했습니다. 다음으로 테스트를 구성하는 데 사용할 수있는 방법에 대해 논의 할 것입니다. 이를 위해 테스트 스크립트의 기능을 수정하지 않고 테스트 스크립트를 수정해야합니다.
예
이 개념을 이해하기 위해 페이지 개체와 함께 위의 구성 파일을 사용합니다. 다음과 같이 테스트 스크립트를 수정해야합니다.
var angularHomepage = require('./AngularHomepage');
describe('angularjs homepage', function() {
it('should greet the named user', function() {
angularHomepage.get();
angularHomepage.setName('Julie');
expect(angularHomepage.getGreetingText()).toEqual
('Hello Julie!');
});
});
여기서 페이지 개체의 경로는 사양에 따라 달라집니다.
마찬가지로 테스트 스위트를 다양한 테스트 스위트로 분리 할 수도 있습니다. 그런 다음 구성 파일을 다음과 같이 변경할 수 있습니다.
exports.config = {
// The address of a running selenium server.
seleniumAddress: 'http://localhost:4444/wd/hub',
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
// Spec patterns are relative to the location of the spec file. They may
// include glob patterns.
suites: {
homepage: 'tests/e2e/homepage/**/*Spec.js',
search: ['tests/e2e/contact_search/**/*Spec.js',
'tests/e2e/venue_search/**/*Spec.js']
},
// Options to be passed to Jasmine-node.
jasmineNodeOpts: {
showColors: true, // Use colors in the command line report.
}
};
이제 하나 또는 다른 테스트 모음 실행간에 쉽게 전환 할 수 있습니다. 다음 명령은 테스트의 홈페이지 섹션 만 실행합니다.
protractor protractor.conf.js --suite homepage
마찬가지로 다음과 같은 명령을 사용하여 특정 테스트 모음을 실행할 수 있습니다.
protractor protractor.conf.js --suite homepage,search
각도기-디버깅
이전 장에서 Protractor의 모든 개념을 살펴 보았으므로 이제이 장에서 디버깅 개념을 자세히 이해하겠습니다.
소개
종단 간 (e2e) 테스트는 해당 애플리케이션의 전체 에코 시스템에 의존하기 때문에 디버그하기가 매우 어렵습니다. 우리는 그들이 다양한 행동에 의존한다는 것을 보았습니다. 특히 로그인과 같은 이전 행동에 의존하고 때로는 권한에 의존한다고 말할 수 있습니다. e2e 테스트를 디버깅하는 데있어 또 다른 어려움은 WebDriver가 다른 운영 체제와 브라우저에서 다르게 작동하기 때문에 WebDriver에 대한 종속성입니다. 마지막으로 e2e 테스트를 디버깅하면 긴 오류 메시지가 생성되어 브라우저 관련 문제와 테스트 프로세스 오류를 구분하기가 어렵습니다.
실패 유형
테스트 스위트의 실패에 대한 다양한 이유가있을 수 있으며 다음은 잘 알려진 실패 유형입니다.
WebDriver 실패
명령을 완료 할 수없는 경우 WebDriver에서 오류가 발생합니다. 예를 들어 브라우저가 정의 된 주소를 가져올 수 없거나 요소가 예상대로 없습니다.
WebDriver 예기치 않은 오류
웹 드라이버 관리자 업데이트에 실패하면 예기치 않은 브라우저 및 OS 관련 오류가 발생합니다.
Angular의 각도기 실패
Protractor for Angular의 실패는 Protractor가 예상대로 라이브러리에서 Angular를 찾지 못했을 때 발생합니다.
각도기 Angular2 실패
이러한 종류의 실패에서 구성에서 useAllAngular2AppRoots 매개 변수를 찾을 수 없으면 Protractor가 실패합니다. 이것이 없으면 테스트 프로세스가 프로세스에서 둘 이상의 요소를 예상하면서 하나의 단일 루트 요소를 살펴보기 때문에 발생합니다.
시간 초과에 대한 각도기 오류
이러한 종류의 실패는 테스트 사양이 루프 또는 긴 풀에 도달하여 데이터를 제 시간에 반환하지 못할 때 발생합니다.
기대 실패
정상적인 예상 실패가 어떻게 생겼는지 보여주는 가장 일반적인 테스트 실패 중 하나입니다.
Protractor에서 디버깅이 중요한 이유는 무엇입니까?
테스트 케이스를 작성했는데 실패한 경우 오류가 발생한 정확한 위치를 찾기가 매우 어렵 기 때문에 해당 테스트 케이스를 디버그하는 방법을 아는 것이 매우 중요하다고 가정하십시오. 각도기로 작업하는 동안 명령 줄에서 빨간색 글꼴로 된 긴 오류가 발생합니다.
테스트 일시 중지 및 디버깅
각도기에서 디버깅하는 방법은 여기에 설명되어 있습니다. & miuns;
일시 중지 방법
Pause 메서드를 사용하여 Protractor에서 테스트 케이스를 디버깅하는 것이 가장 쉬운 방법 중 하나입니다. 테스트 코드 & miuns;를 일시 중지하려는 위치에 다음 명령을 입력 할 수 있습니다.
browser.pause();
실행중인 코드가 위의 명령을 입력하면 해당 지점에서 실행중인 프로그램이 일시 중지됩니다. 그 후 우리의 선호도에 따라 다음 명령을 내릴 수 있습니다.
전진을위한 C 형
명령이 소진 될 때마다 앞으로 진행하려면 C를 입력해야합니다. C를 입력하지 않으면 테스트가 전체 코드를 실행하지 않으며 Jasmine 시간 초과 오류로 인해 실패합니다.
대화식 모드로 들어가려면 repl을 입력하십시오.
대화 형 모드의 이점은 WebDriver 명령을 브라우저로 보낼 수 있다는 것입니다. 대화 형 모드로 들어가려면 다음을 입력하십시오.repl.
테스트를 종료하고 계속하려면 Ctrl-C를 입력하십시오.
일시 중지 상태에서 테스트를 종료하고 중지 된 위치에서 테스트를 계속하려면 Ctrl-C를 입력해야합니다.
예
이 예에서는 아래 사양 파일이 example_debug.js, 각도기는 로케이터로 요소를 식별하려고합니다. by.binding( 'mmmm')하지만 URL (https://angularjs.org/ 페이지에 지정된 로케이터가있는 요소가 없습니다.
describe('Suite for protractor debugger',function(){
it('Failing spec',function(){
browser.get("http://angularjs.org");
element(by.model('yourName')).sendKeys('Vijay');
//Element doesn't exist
var welcomeText =
element(by.binding('mmmm')).getText();
expect('Hello '+welcomeText+'!').toEqual('Hello Ram!')
});
});
이제 위의 테스트를 실행하려면 위의 사양 파일에서 테스트를 일시 중지하려는 browser.pause () 코드를 추가해야합니다. 다음과 같이 보일 것입니다-
describe('Suite for protractor debugger',function(){
it('Failing spec',function(){
browser.get("http://angularjs.org");
browser.pause();
element(by.model('yourName')).sendKeys('Vijay');
//Element doesn't exist
var welcomeText =
element(by.binding('mmmm')).getText();
expect('Hello '+welcomeText+'!').toEqual('Hello Ram!')
});
});
그러나 실행하기 전에 구성 파일도 약간 변경해야합니다. 이전에 사용 된 구성 파일에서 다음과 같은 변경을 수행하고 있습니다.example_configuration.js 이전 장에서-
// An example configuration file.
exports.config = {
directConnect: true,
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
// Framework to use. Jasmine is recommended.
framework: 'jasmine',
// Spec patterns are relative to the current working directory when
// protractor is called.
specs: ['example_debug.js'],
allScriptsTimeout: 999999,
jasmineNodeOpts: {
defaultTimeoutInterval: 999999
},
onPrepare: function () {
browser.manage().window().maximize();
browser.manage().timeouts().implicitlyWait(5000);
}
};
이제 다음 명령을 실행하십시오.
protractor example_configuration.js
디버거는 위의 명령 후에 시작됩니다.
디버거 방법
Pause 메서드를 사용하여 Protractor에서 테스트 케이스를 디버깅하는 것은 약간 고급 방법입니다. 테스트 코드를 깰 위치에 다음 명령을 입력 할 수 있습니다.
browser.debugger();
노드 디버거를 사용하여 테스트 코드를 디버깅합니다. 위의 명령을 실행하려면 테스트 프로젝트 위치에서 열린 별도의 명령 프롬프트에 다음 명령을 입력해야합니다.
protractor debug protractor.conf.js
이 방법에서는 테스트 코드를 계속하기 위해 터미널에 C를 입력해야합니다. 그러나 일시 정지 방식과는 반대로이 방식에서는 한 번만 입력해야합니다.
예
이 예에서는 b라는 동일한 사양 파일을 사용합니다.example_debug.js, 위에 사용. 유일한 차이점은browser.pause(), 우리는 browser.debugger()테스트 코드를 깨고 싶은 곳입니다. 다음과 같이 보일 것입니다-
describe('Suite for protractor debugger',function(){
it('Failing spec',function(){
browser.get("http://angularjs.org");
browser.debugger();
element(by.model('yourName')).sendKeys('Vijay');
//Element doesn't exist
var welcomeText = element(by.binding('mmmm')).getText();
expect('Hello '+welcomeText+'!').toEqual('Hello Ram!')
});
});
동일한 구성 파일을 사용하고 있습니다. example_configuration.js, 위의 예에서 사용되었습니다.
이제 다음 디버그 명령 줄 옵션을 사용하여 각도기 테스트를 실행합니다.
protractor debug example_configuration.js
디버거는 위의 명령 후에 시작됩니다.
각도기-각도기 스타일 가이드
이 장에서는 각도기 스타일 가이드에 대해 자세히 알아 보겠습니다.
소개
스타일 가이드는 두 명의 소프트웨어 엔지니어가 만들었습니다. Carmen Popoviciu, ING의 프런트 엔드 엔지니어 및 Andres Dominguez, Google의 소프트웨어 엔지니어입니다. 따라서이 스타일 가이드는 Carmen Popoviciu 및 Google의 각도기 스타일 가이드라고도합니다.
이 스타일 가이드는 다음 5 가지 핵심 포인트로 나눌 수 있습니다.
- 일반 규칙
- 프로젝트 구조
- 로케이터 전략
- 페이지 개체
- 테스트 스위트
일반 규칙
다음은 테스트를 위해 각도기를 사용하는 동안주의해야하는 몇 가지 일반적인 규칙입니다.
이미 단위 테스트를 마친 것을 종단 간 테스트하지 마십시오.
이것은 Carmen과 Andres가 제시 한 최초의 일반적인 규칙입니다. 그들은 이미 단위 테스트를 거친 코드에 대해 e2e 테스트를 수행해서는 안된다고 제안했습니다. 그 뒤에있는 주된 이유는 단위 테스트가 e2e 테스트보다 훨씬 빠르기 때문입니다. 또 다른 이유는 시간을 절약하기 위해 중복 테스트를 피해야한다는 것입니다 (단위 및 e2e 테스트를 모두 수행하지 마십시오).
하나의 구성 파일 만 사용
권장되는 또 다른 중요한 점은 하나의 구성 파일 만 사용해야한다는 것입니다. 테스트중인 각 환경에 대한 구성 파일을 생성하지 마십시오. 당신이 사용할 수있는grunt-protractor-coverage 다른 환경을 설정하기 위해.
테스트에 논리를 사용하지 마십시오.
테스트 케이스에서 IF 문이나 FOR 루프를 사용하지 않아야합니다. 그렇게하면 테스트가 아무 것도 테스트하지 않고 통과하거나 매우 느리게 실행될 수 있기 때문입니다.
파일 수준에서 독립적 인 테스트 만들기
각도기는 공유가 활성화 된 경우 테스트를 병렬로 실행할 수 있습니다. 이러한 파일은 사용 가능 해지면 다른 브라우저에서 실행됩니다. Carmen과 Andres는 분도기에 의해 실행되는 순서가 불확실하고 테스트를 독립적으로 실행하기가 매우 쉽기 때문에 적어도 파일 수준에서 테스트를 독립적으로 만들 것을 권장했습니다.
프로젝트 구조
Protractor의 스타일 가이드와 관련된 또 다른 중요한 요점은 프로젝트의 구조입니다. 다음은 프로젝트 구조에 대한 권장 사항입니다-
합리적인 구조로 e2e 테스트 모색
Carmen과 Andres는 프로젝트의 구조에 맞는 구조로 e2e 테스트를 그룹화해야한다고 권장했습니다. 이 권장 사항의 배경은 파일 찾기가 쉬워지고 폴더 구조가 더 읽기 쉬워지기 때문입니다. 이 단계는 또한 단위 테스트에서 e2e 테스트를 분리합니다. 그들은 다음과 같은 종류의 구조를 피할 것을 권장했습니다.
|-- project-folder
|-- app
|-- css
|-- img
|-- partials
home.html
profile.html
contacts.html
|-- js
|-- controllers
|-- directives
|-- services
app.js
...
index.html
|-- test
|-- unit
|-- e2e
home-page.js
home-spec.js
profile-page.js
profile-spec.js
contacts-page.js
contacts-spec.js
반면에 그들은 다음과 같은 종류의 구조를 권장했습니다.
|-- project-folder
|-- app
|-- css
|-- img
|-- partials
home.html
profile.html
contacts.html
|-- js
|-- controllers
|-- directives
|-- services
app.js
...
index.html
|-- test
|-- unit
|-- e2e
|-- page-objects
home-page.js
profile-page.js
contacts-page.js
home-spec.js
profile-spec.js
contacts-spec.js
로케이터 전략
다음은 테스트를 위해 각도기를 사용하는 동안주의해야 할 몇 가지 로케이터 전략입니다.
XPATH를 사용하지 마십시오.
이것은 각도기 스타일 가이드에서 권장되는 첫 번째 로케이터 전략입니다. 그 이유는 마크 업이 매우 쉽게 변경되기 때문에 XPath에 많은 유지 관리가 필요하기 때문입니다. 또한 XPath 표현식은 가장 느리고 디버깅하기가 매우 어렵습니다.
항상 by.model 및 by.binding과 같은 각도기 별 로케이터를 선호합니다.
by.model 및 by.binding과 같은 각도기 별 로케이터는 짧고 구체적이며 읽기 쉽습니다. 이들의 도움으로 로케이터를 작성하는 것도 매우 쉽습니다.
예
View
<ul class = "red">
<li>{{color.name}}</li>
<li>{{color.shade}}</li>
<li>{{color.code}}</li>
</ul>
<div class = "details">
<div class = "personal">
<input ng-model = "person.name">
</div>
</div>
위 코드의 경우 다음을 피하는 것이 좋습니다.
var nameElement = element.all(by.css('.red li')).get(0);
var personName = element(by.css('.details .personal input'));
반면에 다음을 사용하는 것이 좋습니다.
var nameElement = element.all(by.css('.red li')).get(0);
var personName = element(by.css('.details .personal input'));
var nameElement = element(by.binding('color.name'));
var personName = element(by.model('person.name'));
각도기 로케이터를 사용할 수없는 경우 by.id 및 by.css를 선호하는 것이 좋습니다.
자주 변경되는 텍스트에 대해서는 항상 텍스트 로케이터를 피하십시오.
버튼, 링크 및 레이블의 텍스트는 시간이 지남에 따라 자주 변경되므로 by.linkText, by.buttonText 및 by.cssContaningText와 같은 텍스트 기반 로케이터를 피해야합니다.
페이지 개체
앞서 논의한 바와 같이 페이지 객체는 애플리케이션 페이지의 요소에 대한 정보를 캡슐화하므로 더 깨끗한 테스트 케이스를 작성하는 데 도움이됩니다. 페이지 객체의 매우 유용한 장점은 여러 테스트에서 재사용 할 수 있으며 애플리케이션의 템플릿이 변경된 경우 페이지 객체 만 업데이트하면된다는 것입니다. 다음은 테스트를 위해 각도기를 사용하는 동안주의해야하는 페이지 개체에 대한 몇 가지 권장 사항입니다.
테스트중인 페이지와 상호 작용하려면 페이지 개체를 사용하십시오.
테스트중인 페이지의 요소에 대한 정보를 캡슐화 할 수 있고 재사용 할 수도 있으므로 테스트중인 페이지와 상호 작용하는 페이지 개체를 사용하는 것이 좋습니다.
항상 파일 당 한 페이지 개체 선언
코드를 깨끗하게 유지하고 사물을 찾기가 쉬워 지므로 각 페이지 객체를 자체 파일에 정의해야합니다.
페이지 끝에서 개체 파일은 항상 단일 모듈을 사용합니다.
각 페이지 객체는 하나의 클래스 만 내보내도록 단일 클래스를 선언하는 것이 좋습니다. 예를 들어, 다음과 같은 개체 파일 사용은 피해야합니다.
var UserProfilePage = function() {};
var UserSettingsPage = function() {};
module.exports = UserPropertiesPage;
module.exports = UserSettingsPage;
그러나 다른 한편으로 다음을 사용하는 것이 좋습니다.
/** @constructor */
var UserPropertiesPage = function() {};
module.exports = UserPropertiesPage;
모든 필수 모듈을 맨 위에 선언하십시오.
모듈 종속성을 명확하고 쉽게 찾을 수 있도록 페이지 개체의 맨 위에 필요한 모든 모듈을 선언해야합니다.
테스트 스위트의 시작 부분에서 모든 페이지 객체를 인스턴스화합니다.
테스트 스위트의 시작 부분에서 모든 페이지 개체를 인스턴스화하는 것이 좋습니다. 이렇게하면 테스트 코드에서 종속성이 분리되고 제품군의 모든 사양에서 종속성을 사용할 수 있기 때문입니다.
페이지 개체에서 expect ()을 사용하지 마십시오.
우리는 페이지 객체에서 expect ()을 사용해서는 안됩니다. 즉, 모든 어설 션이 테스트 케이스에서 수행되어야하므로 페이지 객체에서 어설 션을 만들어서는 안됩니다.
또 다른 이유는 테스트 독자가 테스트 케이스 만 읽어서 애플리케이션의 동작을 이해할 수 있어야한다는 것입니다.