尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Protractor 快速入门:安装、首个 E2E 测试与 Spec/Config 文件实战指南

发布时间:2026/9/25 12:08:18

资讯中心
01
ARTICLE

Protractor 快速入门:安装、首个 E2E 测试与 Spec/Config 文件实战指南

Protractor 快速入门:安装、首个 E2E 测试与 Spec/Config 文件实战指南
测试【免费下载链接】protractorE2E test framework for Angular apps项目地址https://gitcode.com/gh_mirrors/pr/protractor点击查看免费下载Protractor 是面向 Angular含 AngularJS应用的端到端测试框架基于 Node.js 运行支持 Jasmine 与 Mocha。本篇快速入门指南围绕 Protractor 的两个必需文件模型展开——spec 测试文件与配置文件config从安装环境、编写第一条断言、操作页面元素、配置多浏览器到理解控制流Control Flow与 Selenium 通信的底层机制带领你完成从零到可运行的首个 E2E 测试。读完本文你将掌握protractor与webdriver-manager两个命令行工具的使用、browser/element/by三大全局对象以及如何用 Page Objects 组织可维护的测试代码。本文内容以 docs/getting-started.md 为骨架完整展开其指向的官方教程docs/tutorial.md、Spec 与 Config 文件详解docs/api-overview.md、WebDriver 控制流docs/control-flow.md、架构原理docs/infrastructure.md与 Page Objectsdocs/page-objects.md并结合作品仓库中的源码与真实示例进行佐证。一、快速开始先读教程再上手Protractor 官方给出的最快上手路径是跟着教程Tutorial走一遍。docs/tutorial.md 提供了一步一步的指南如何安装 Protractor、创建测试文件、配置配置文件并运行测试。教程中使用了一个公开的 AngularJS 示例应用 Super Calculator一个计算器页面非常适合完整演示定位元素 → 输入 → 点击 → 断言结果的典型 E2E 流程。在动手写测试之前有两点需要提前建立认知Protractor 是 WebDriverJS 的封装。WebDriverJS 是 Selenium WebDriver API 的 JavaScript 绑定因此 Protractor 的绝大多数能力都来自 WebDriverJS。WebDriverJS API 基于 Promise。所有命令都是异步的它们被调度进一个控制流Control Flow队列并返回 Promise 而非原始值。这一点直接影响你编写断言的方式详见后文控制流与 Promise一节。此外官方推荐在熟悉 Protractor 之后立刻开始使用Page Objects模式组织测试见 docs/page-objects.md这能显著提升测试的可维护性。二、前置条件Node.js、npm 与 JDKProtractor 是一个 Node.js 程序因此运行它需要Node.js从 npm 安装 Protractor 包而 npm 随 Node.js 一同分发。先用node --version检查你本机的 Node.js 版本再对照 Protractor README 中的兼容性说明确认版本匹配。Jasmine默认情况下Protractor 使用 Jasmine 作为测试框架的接口。下文教程默认你已具备基本的 Jasmine 使用经验并使用 Jasmine 2.x 语法describe/it/expect。Java Development Kit (JDK)如果采用本地独立 Selenium Server方案本教程的方案需要用 JDK 运行 Selenium Server。用java -version在命令行验证 JDK 是否已安装。除了本地 Selenium ServerProtractor 还支持直连浏览器驱动的directConnect、Sauce Labs、BrowserStack 等远程服务连接方式。本教程聚焦最通用的本地 Server 方案完整的连接选项见下文配置文件详解。三、环境搭建npm 全局安装与 webdriver-manager使用 npm 全局安装 Protractornpm install -g protractor安装完成后你会获得两个命令行工具protractor测试启动器。运行protractor --version确认它工作正常。webdriver-managerSelenium Server 的辅助管理工具用于下载并启动一个可用的 Selenium Server 实例。用webdriver-manager下载必要的二进制文件webdriver-manager update然后启动服务器webdriver-manager start这会启动一个 Selenium Server并输出大量信息日志。你的 Protractor 测试会向这个服务器发送请求由它来控制本地的浏览器。整个教程期间请保持该服务器运行。服务器状态可在http://localhost:4444/wd/hub查看。这一测试脚本 → Selenium Server → 浏览器的三进程协作模型是 Protractor 工作的基础其通信细节参见架构原理一节。四、Step 0编写你的第一个 Protractor 测试打开一个新的命令行终端创建一个干净的测试文件夹。Protractor 运行需要两个文件一个spec 文件测试用例和一个配置文件运行配置。4.1 编写 spec 文件先写一个最简单的测试导航到一个示例 AngularJS 应用并检查其标题。把以下内容复制为spec.js// spec.js describe(Protractor Demo App, function() { it(should have a title, function() { browser.get(http://juliemr.github.io/protractor-demo/); expect(browser.getTitle()).toEqual(Super Calculator); }); });这里出现了三个关键元素describe与it来自 Jasmine 框架的测试组织语法Protractor 原生支持。browserProtractor 创建的全局对象用于浏览器级命令如用browser.get进行导航。仓库中该对象的实现位于 lib/browser.ts它是 WebDriver 实例的封装。browser.getTitle()读取页面标题返回一个 PromiseProtractor 对expect做了适配使其能理解 Promise详见控制流与 Promise。4.2 编写配置文件把以下内容复制为conf.js// conf.js exports.config { framework: jasmine, seleniumAddress: http://localhost:4444/wd/hub, specs: [spec.js] }这个配置告诉 Protractor 三件事specs测试文件的位置。seleniumAddress要连接的 Selenium Server 地址。framework使用的测试框架为 Jasmine。其余全部使用默认值——Chrome 是默认浏览器。这份极简配置的完整形态可参考仓库中的真实示例 example/conf.js后者还演示了directConnect、capabilities与jasmineNodeOpts的用法。4.3 运行测试protractor conf.js你会看到一个 Chrome 浏览器窗口打开并导航到 Calculator 页面然后自动关闭整个过程非常快。测试输出应为1 tests, 1 assertion, 0 failures。恭喜你已成功运行了第一个 Protractor 测试五、配置文件详解Spec Config 两个文件模型Protractor 运行时依赖且仅依赖两个文件——测试文件spec与配置文件这一点在 docs/api-overview.md 中有系统说明。5.1 Spec 文件与三大全局变量Protractor 的测试使用你所选测试框架的语法如 Jasmine编写并结合 Protractor 自身的 API完整列表见 docs/api.md。一个完整的示例 spec仓库中的 example/example_spec.js如下describe(angularjs homepage, () { it(should greet the named user, async () { await browser.get(http://www.angularjs.org); await element(by.model(yourName)).sendKeys(Julie); const greeting element(by.binding(yourName)); expect(await greeting.getText()).toEqual(Hello Julie!); }); });Protractor 会向你的 spec 文件导出以下全局变量全局变量作用关键方法browserWebDriver 实例的封装用于导航和页面级信息browser.get(url)加载页面browser.getTitle()获取标题element查找并交互页面 DOM 元素的辅助函数接收一个 Locator 作为唯一参数element(locator)返回 ElementFinderby元素定位策略Locator工厂的集合by.css()、by.id()、by.model()、by.binding()protractor包裹 WebDriver 命名空间的 Protractor 命名空间包含静态变量与类protractor.Key枚举特殊键盘按键码需要注意browser.get会期待页面中存在 Angular 库。如果它尝试加载的页面不包含 Angular会抛出错误如需与非 Angular 页面交互可通过browser.driver直接访问被包裹的 WebDriver 实例。关于element的更多示例可查看 Protractor 的 ElementFinder 测试套件 spec/basic/elements_spec.js。5.2 Config 文件核心配置选项配置文件负责告诉 Protractor 如何设置 Selenium Server、运行哪些测试、如何配置浏览器以及使用哪个测试框架。仓库中的 example/conf.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_spec.js, angular_material/input_spec.js, angular_material/mat_paginator_spec.js ], // Options to be passed to Jasmine. jasmineNodeOpts: { defaultTimeoutInterval: 30000 } };默认设置为独立 Selenium Server、Chrome 浏览器、Jasmine 测试框架。完整配置项的解释见 lib/config.ts各类配置选项的进一步信息对应以下文档设置 Selenium Serverdocs/server-setup.md设置浏览器docs/browser-setup.md选择测试框架docs/frameworks.md使用 Page Objects 组织测试docs/page-objects.md5.3 浏览器连接方式与 capabilities从源码 lib/config.ts 可以看到Protractor 提供了五种连接浏览器驱动的方案配置时只需指定其中之一seleniumServerJar在本地启动一个独立 Selenium Serverjar 文件相对 webdriver-manager 位置的路径。seleniumAddress连接一个已经运行的 Selenium Server如http://localhost:4444/wd/hub。sauceUser/sauceKey通过 Sauce Labs 使用远程 Selenium Server。browserstackUser/browserstackKey通过 BrowserStack 使用远程 Selenium Server。directConnect直接连接浏览器驱动仅对 Firefox 和 Chrome 可用无需单独启动 Selenium Server。教程采用的正是方案 2seleniumAddress而 example/conf.js 演示了方案 5directConnect: true。此外若通过本地独立 Server 运行还可配置seleniumServerStartTimeout等待本地独立 Selenium Server 启动的超时时间默认 30000ms见 lib/config.ts。chromeDriver/geckoDriver指定 chromedriver / geckodriver 二进制位置未设置时使用 webdriver-manager 下载的默认值见 lib/config.ts。六、从入门到实战四个渐进步骤教程docs/tutorial.md把完整的上手过程拆成四个渐进步骤从只读断言逐步推进到多场景组织与元素列表操作。6.1 Step 1与页面元素交互把spec.js修改为以下内容测试输入两个数字并点击按钮// spec.js describe(Protractor Demo App, function() { it(should add one and two, function() { browser.get(http://juliemr.github.io/protractor-demo/); element(by.model(first)).sendKeys(1); element(by.model(second)).sendKeys(2); element(by.id(gobutton)).click(); expect(element(by.binding(latest)).getText()). toEqual(5); // This is wrong! }); });这里使用了另外两个全局对象element用于在网页中查找 HTML 元素返回ElementFinder对象。可调用sendKeys向input输入文本、click点击按钮、getText获取元素内容。byelement接收一个参数——描述如何查找元素的Locator而by对象负责创建 Locator。本测试用了三种 Locatorby.model(first)查找带ng-modelfirst的元素即页面源码中的input typetext ng-modelfirstby.id(gobutton)按 id 查找元素button idgobuttonby.binding(latest)查找绑定到变量latest的元素即包含{{latest}}的 span。运行protractor conf.js你会看到页面输入两个数字并等待结果显示。因为结果是 3 而不是 5测试会失败——这正是 E2E 测试的价值修改断言并重新运行直到通过。Locator 与 ElementFinder 的完整讲解见 docs/locators.md。6.2 Step 2组织多个测试场景把两个测试合并整理并抽出公共逻辑// spec.js describe(Protractor Demo App, function() { var firstNumber element(by.model(first)); var secondNumber element(by.model(second)); var goButton element(by.id(gobutton)); var latestResult element(by.binding(latest)); beforeEach(function() { browser.get(http://juliemr.github.io/protractor-demo/); }); it(should have a title, function() { expect(browser.getTitle()).toEqual(Super Calculator); }); it(should add one and two, function() { firstNumber.sendKeys(1); secondNumber.sendKeys(2); goButton.click(); expect(latestResult.getText()).toEqual(3); }); it(should add four and six, function() { // Fill this in. expect(latestResult.getText()).toEqual(10); }); it(should read the value from an input, function() { firstNumber.sendKeys(1); expect(firstNumber.getAttribute(value)).toEqual(1); }); });本步的关键重构动作把导航抽入beforeEach函数它在每个it块之前运行把两个输入框的 ElementFinder 存入可复用的变量最后一个断言用firstNumber.getAttribute(value)读取输入框当前值并与刚才设置的值比较。你可以补全第三个测试用上面两个变量做4 6的输入再运行确保全部通过。6.3 Step 3修改配置——切换与并行运行浏览器配置文件可以改变使用的浏览器以及连接 Selenium Server 的方式。把浏览器从默认的 Chrome 切换为 Firefox// conf.js exports.config { framework: jasmine, seleniumAddress: http://localhost:4444/wd/hub, specs: [spec.js], capabilities: { browserName: firefox } }capabilities对象描述要测试的浏览器全部选项见 lib/config.ts。Protractor 还支持同时在多个浏览器上运行测试// conf.js exports.config { framework: jasmine, seleniumAddress: http://localhost:4444/wd/hub, specs: [spec.js], multiCapabilities: [{ browserName: firefox }, { browserName: chrome }] }再次运行你会看到测试同时在 Chrome 和 Firefox 上执行命令行会分别报告两者的结果。6.4 Step 4处理元素列表ElementArrayFinder有时你需要处理多个元素。element.all返回ElementArrayFinder。在 Calculator 应用中每次运算都会记录到历史中页面用带ng-repeat的表格实现可以这样验证// spec.js describe(Protractor Demo App, function() { var firstNumber element(by.model(first)); var secondNumber element(by.model(second)); var goButton element(by.id(gobutton)); var latestResult element(by.binding(latest)); var history element.all(by.repeater(result in memory)); function add(a, b) { firstNumber.sendKeys(a); secondNumber.sendKeys(b); goButton.click(); } beforeEach(function() { browser.get(http://juliemr.github.io/protractor-demo/); }); it(should have a history, function() { add(1, 2); add(3, 4); expect(history.count()).toEqual(2); add(5, 6); expect(history.count()).toEqual(0); // This is wrong! }); });这里完成了两件事一是抽出add辅助函数二是用element.allby.repeater得到 ElementArrayFinder用count方法断言历史长度。修正第二个断言应为 3让测试通过。ElementArrayFinder除count外还有很多方法。例如用last获取最后一个匹配元素it(should have a history, function() { add(1, 2); add(3, 4); expect(history.last().getText()).toContain(1 2); expect(history.first().getText()).toContain(foo); // This is wrong! });由于 Calculator 把最旧的结果放在底部最旧的加法1 2正是历史的最后一项。这里用 Jasmine 的toContain匹配器断言元素文本包含 1 2完整文本还含时间戳和结果。请修正测试使其正确期望第一条历史记录包含 3 4。ElementArrayFinder还提供each、map、filter、reduce等方法与 JavaScript 数组方法类似。完整的 API 见官方 API 参考。七、控制流与 PromiseWebDriverJS 的异步模型WebDriverJS因而 Protractor的 API完全异步所有函数都返回 Promise。这一点在 docs/control-flow.md 中有详细说明。7.1 Promise 队列Control FlowWebDriverJS 维护一个待处理 Promise 的队列称为控制流Control Flow用来保持执行有序。考虑如下测试it(should find an element by text input model, function() { browser.get(app/index.html#/form); var username element(by.model(username)); username.clear(); username.sendKeys(Jane Doe); var name element(by.binding(username)); expect(name.getText()).toEqual(Jane Doe); // Point A });在// Point A这一时刻没有任何任务实际执行过browser.get位于控制流队列最前name.getText()位于队列最末而name.getText()此刻的值是一个未解析的 Promise 对象。所有命令按书写顺序入队随后依次执行。7.2 Protractor 的适配Jasmine 适配Protractor 让每个 spec自动等待控制流清空后才退出因此你不必手动等待异步命令完成。expect 适配Jasmine 的expect被改造为能理解 Promise。下面这行代码能正常工作是因为它实际往控制流里添加了一个期望任务该任务会在其他任务之后运行expect(name.getText()).toEqual(Jane Doe);7.3 禁用控制流SELENIUM_PROMISE_MANAGER控制流正在被逐步移除。要禁用控制流可使用配置选项SELENIUM_PROMISE_MANAGER: false对应源码定义见 lib/config.ts。从源码注释可以看到在未来的 webdriver 版本中环境变量SELENIUM_PROMISE_MANAGER1才会恢复启用控制流之后控制流将被彻底移除且配置文件中的该选项优先级高于同名环境变量。禁用控制流后你需要用 Promise 链或 ES7 的async/await来同步命令。仓库的 spec/ts/ 目录提供了禁用控制流下的 TypeScript 测试示例如 spec/ts/basic/element_spec.ts、spec/ts/noCFBasicConf.ts。因为async/await使用原生 Promise会使控制流变得不可靠所以如果你在编写需要兼容控制流开/关两种场景的库或插件应使用 Promise 链来做同步。7.4 Mocha 用户须知如果使用 Mocha 作为测试框架控制流同样会在每个测试完成前自动清空。但Mocha 的expect并没有被适配成能理解 Promise——因此你需要使用如 Chai as Promised 之类的断言框架。参见 docs/frameworks.md。八、架构原理Protractor / Selenium / 浏览器如何协作深入理解协作模型docs/infrastructure.md有助于你排查测试失败与性能问题。8.1 三进程模型一个使用 Selenium WebDriver 的测试涉及三个进程测试脚本、服务器、浏览器其通信关系如下Selenium Server负责解释来自测试的命令并将其转发给一个或多个浏览器服务器与浏览器之间使用WebDriver Wire Protocol基于 JSON 的协议通信命令由Browser Driver解释执行在 Protractor 中测试脚本运行在 Node.js 环境下。8.2 组件关系Protractor 与 Selenium 的组合关系需要记住三点Protractor 是 WebDriverJS 的封装WebDriver 命令是异步的它们被调度到控制流上并返回 Promise 而非原始值测试脚本发送命令给 Selenium Server服务器再与浏览器驱动通信。8.3 自动等待额外的稳定性命令Protractor 在对浏览器执行任何动作之前都会先运行一条额外命令以确保被测应用已经稳定。例如element(by.css(button.myclass)).click();这条代码实际会向 Browser Driver 发送三条命令/session/:sessionId/execute_asyncProtractor 让浏览器先执行一段自定义 JavaScript请求 Angular 在完成所有 timeout 与异步请求、应用就绪时做出响应然后测试才继续/session/:sessionId/element发送查找元素的命令/session/:sessionId/element/:id/click最后发送点击动作的命令。这正是 Protractor 相对于裸 WebDriver 的核心价值为 Angular 应用自动同步等待。对相关超时与同步策略的深入讨论见 docs/timeouts.md。九、用 Page Objects 组织测试当你熟悉 Protractor 后官方强烈建议开始使用Page Objects模式docs/page-objects.md。它通过把页面元素信息封装起来帮助写出更整洁的测试Page Object 可在多个测试间复用当应用模板变化时只需更新 Page Object 一处。9.1 不使用 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!); }); });9.2 使用 Page Objects第一步创建 Page Object。针对 angularjs.org 主页Basics示例Page Object 可以这样写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();如果使用async/await则需注意不使用await的函数不应加async前缀var AngularHomepage function() { var nameInput element(by.model(yourName)); var greeting element(by.binding(yourName)); this.get async function() { await browser.get(http://www.angularjs.org); }; this.setName async function(name) { await nameInput.sendKeys(name); }; this.getGreetingText function() { return greeting.getText(); }; // Not async, returns the element this.getGreeting function() { return greeting; }; }; module.exports new AngularHomepage();第二步修改测试脚本使用 Page Object。注意测试脚本的功能本身不发生变化不增不减require的路径相对于你的 spec 文件位置请相应调整。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!); }); });使用async/await的版本var angularHomepage require(./AngularHomepage); describe(angularjs homepage, function() { it(should greet the named user, async function() { await angularHomepage.get(); await angularHomepage.setName(Julie); expect(await angularHomepage.getGreetingText()).toEqual(Hello Julie!); }); });仓库 exampleTypescript/ 目录中提供了 TypeScript 版 Page Object 的完整示例exampleTypescript/angularPage.ts、exampleTypescript/specPageObjects.ts。9.3 配置测试套件SuitesPage Objects 文档还介绍了按套件分离测试的能力。在配置文件中设置suites选项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. } };从命令行即可轻松切换运行某个套件。只运行 homepage 部分protractor protractor.conf.js --suite homepage也可以同时运行多个套件protractor protractor.conf.js --suite homepage,search相关源码实现位于 lib/config.ts不传命令行参数时运行全部套件--suitesmoke或--suitesmoke,full时仅运行匹配指定套件的模式也可以在配置文件中通过suite字段设置默认套件。十、下一步完整文档导航本指南已带你完成从安装到运行、从单条断言到多浏览器并行的完整入门闭环。想继续深入学习官方文档的完整目录见 docs/toc.md推荐按以下顺序进阶环境与安装docs/protractor-setup.mdProtractor 安装、docs/server-setup.mdSelenium Server 配置、docs/browser-setup.md浏览器配置、docs/frameworks.md选择测试框架测试编写docs/locators.mdLocator 详解、docs/system-setup.md被测系统搭建、docs/debugging.md调试进阶参考lib/config.ts全部配置项、docs/api.mdProtractor API、docs/async-await.mdasync/await 用法、docs/typescript.mdTypeScript 支持、docs/timeouts.md超时与同步。赞分享测试【免费下载链接】protractorE2E test framework for Angular apps项目地址https://gitcode.com/gh_mirrors/pr/protractor点击查看免费下载相关推荐3大核心优势打造DayZ单机生存终极解决方案3大核心优势打造DayZ单机生存终极解决方案 想象一下在《DayZ》的末日世界中你可以不受网络限制、自由探索生存的每一个细节——这就是DayZCommuni测试Angular Material 快速入门从 ng add 安装到首个组件实战Angular Material 快速入门从 ng add 安装到首个组件实战 本篇技术指南以官方文档 guides/getting started.md h前端UI组件设计系统Protractor 入门教程从零搭建 Angular E2E 测试环境Protractor 入门教程从零搭建 Angular E2E 测试环境 本教程面向首次接触 Protractor 的开发者以官方入门文档 docs/tut测试上一篇pi-computer-use使用场景大盘点哪些重复工作最适合交给AI Agent下一篇hikptool信息收集功能详解带内诊断数据采集最佳实践创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。