本教程包括:
- 设置一个渐进式网络应用程序样本
- 为示例应用程序创建测试
- 构建持续集成管道
网络和浏览器技术不断进步,缩小了网络和本地应用程序性能之间的差距。曾经专属本地应用程序的功能可以在Web应用程序中实现。这部分是由于渐进式网络应用程序(PWA)的出现。网络应用现在可以被安装,接收推送通知,甚至可以离线工作。在这篇文章中,我们将建立一个简单的PWA,为其编写测试,并通过建立一个持续集成(CI)管道来实现测试过程的自动化。
前提条件
要学习这篇文章,需要一些条件。
设置演示应用程序
首先,通过运行此命令创建一个应用程序文件夹。
mkdir my-pwa
接下来,在应用程序的根目录下,创建一个名为index.html 的文件。这个文件将成为应用程序的主页。将这段代码粘贴到该文件中。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="manifest" href="manifest.json" />
<link rel="stylesheet" type="text/css" href="styles.css" media="all" />
<title>My PWA Application</title>
</head>
<body>
<h2>
Welcome to my Progressive Web Application.
</h2>
<script src="app.js"></script>
</body>
</html>
这个代码块显示了一个典型的HTML页面,标题是 "我的PWA应用程序",还有一条欢迎信息。这个文件还引用了一个manifest.json 文件(用于配置我们的PWA的安装),一个styles.css 文件,用于一些基本的风格设计,还有一个app.js 文件,将加载我们的服务工作者。所有这些文件都将在本教程的过程中创建。
为了获得预览,在应用程序的根部运行这个命令。
http-server
这将调用http-server 模块来启动一个临时服务器,为应用程序提供服务。在你运行该命令后,地址将显示在控制台。然后你就可以进入应用程序的URL了。

注意:我是在谷歌浏览器的隐身模式下运行的,打开了开发工具,激活了移动视图。在开发过程中,我更喜欢在Incognito模式下运行PWA,因为它能确保我的服务工作者得到更新。
接下来,通过在应用程序的根文件夹中创建一个styles.css 文件来添加样式。把这个粘贴到文件中。
/* ./styles.css */
h2 {
color: blue;
padding: 5px;
}
这个文件只是给h2 头部一些填充,并将其染成蓝色。
添加一个服务工作者
服务工作者创建了一个引擎室,为PWA功能提供动力。我们将通过在应用程序的根文件夹中创建一个名为serviceworker.js 的新文件来为这个项目添加一个服务工作者。将这段代码粘贴到其中。
// ./serviceworker.js
var cacheName = "sw-v1";
var filesToCache = ["./", "./index.html", "./styles.css"];
self.addEventListener("install", function (e) {
console.log("[ServiceWorker] Install v1");
e.waitUntil(
caches.open(cacheName).then(function (cache) {
console.log("[ServiceWorker] Caching app shell");
return cache.addAll(filesToCache);
})
);
});
self.addEventListener("activate", (event) => {
event.waitUntil(self.clients.claim());
});
self.addEventListener("fetch", function (event) {
event.respondWith(
caches.match(event.request).then(function (response) {
if (response) {
return response;
}
return fetch(event.request);
})
);
});
如果你以前从事过PWA项目,这段代码会显得很熟悉。它首先为缓存设置了一个名称,在文件更新时设置你的服务工作者的版本。当浏览器安装更新的服务工作者文件时,你可以很容易地识别出当前正在运行的版本。我使用了sw-v1 这个名字来标识它是我的第一个版本。这是你缓存你的应用程序根文件的地方 (index.html 和styles.css)。
接下来,创建一个要缓存的文件数组。这些文件将被缓存在浏览器的内存中,供用户在离线时访问。
接下来,install 事件使用缓存名称来创建一个缓存,将文件存储在其中。
下一个事件,activate ,是在安装了一个新版本的服务工作者后,检测到它的新版本时触发的。这个事件指定旧的服务工作者停止为缓存的文件提供服务。
最后一个事件,fetch ,拦截应用程序的请求,并检查请求资源的新缓存版本。如果有新的版本,缓存的资源将被提供。如果没有找到新的版本,就会对该资源提出新的请求。
然后你需要将你刚刚创建的服务工作者加载到你的应用程序中。在应用程序的根文件夹中创建一个app.js 文件,并粘贴此代码。
// ./app.js
if ("serviceWorker" in navigator) {
window.addEventListener("load", function () {
navigator.serviceWorker.register("./serviceworker.js").then(
function (registration) {
console.log("Hurray! Service workers with scope: ", registration.scope);
},
function (err) {
console.log("Oops! ServiceWorker registration failed: ", err);
}
);
});
}
现在是时候让你的服务工作者进行测试运行了。确保你的应用程序仍在运行,然后在它所在的浏览器标签上做一个硬重载。Ctrl + Shift + R.检查浏览器控制台中你写的日志信息,以确认服务工的安装。

很好!
您的服务工作者已经安装,文件已被缓存,可供离线访问。要确认缓存,请转到Chrome开发工具中的应用标签,并展开缓存存储部分。您将看到我们的服务工作者刚刚创建的命名缓存。

要确认您的服务工作者已经提供了离线功能,请使用Ctrl + C 关闭http-server 服务。然后在你的浏览器中刷新应用程序。以前,离线页面会在这时显示,因为应用程序不再运行。不过,有了服务工作者这个法宝,您的应用程序主页仍然可以使用,不会出现中断。
添加清单文件
要完成PWA的创建,您需要创建一个清单文件。这个文件可以激活你的应用程序的 "添加到主屏幕"功能。这定义了你的应用程序是如何安装在它被使用的设备上的。
在项目的根部创建一个manifest.json 文件。把这个粘贴到里面。
{
"name": "My PWA",
"short_name": "My PWA",
"background_color": "#ffffff",
"display": "standalone",
"orientation": "portrait",
"scope": "/index.html",
"start_url": "/index.html",
"icons": [
{
"src": "icons/icon-128x128.png",
"sizes": "128x128",
"type": "image/png"
},
{
"src": "icons/icon-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "icons/icon-152x152.png",
"sizes": "152x152",
"type": "image/png"
},
{
"src": "icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
这个代码块定义了应用程序的name ,首选的orientation ,以及用于闪屏的background_color 。添加short_name 是一种最佳做法。这个可选字段指定了将在应用程序启动器或新标签页中显示的名称。否则,将使用name ,如果长度超过12个字符,将被截断。
注意:你可以在这里生成一个清单文件。你也可以使用该网站来为你的应用程序生成图标。
这是一个非常简单、精简的应用程序,所以我忽略了诸如theme_color 、splash_pages 、一些标准图标尺寸和iOS图标支持等功能。
应用程序的主页被设置为/index.html ,不同设备的安装图标尺寸被定义在icons 属性中。我还把包含我所有图标的icons 目录移到了项目的根目录。这就是你的应用程序作为PWA运作所需要的一切。
为了确认这一点,运行一个Lighthouse测试。进入Chrome开发工具中的Lighthouse标签来运行测试。

点击 "生成报告",然后点击**"分析页面负载**",以获得PWA的审计报告。

点击最右边的PWA图标,进入PWA兼容性测试的结果。
注意:失败的检查,Does not redirect HTTP traffic to HTTPS ,将在你部署网站并启用HTTPS时通过。
添加测试
要开始向你的应用程序添加测试,为你将要安装的npm包创建一个package.json 文件。要在项目根部创建一个基本文件并跳过QA过程,请运行此命令。
npm init -y
要在应用程序中设置测试,请安装这些包。
使用这个命令一次性安装这些包。
npm install --save-dev @testing-library/dom @testing-library/jest-dom jsdom jest
当这些安装完毕后,在根目录下创建一个名为index.test.js 的测试文件。将这段代码粘贴到其中。
// ./index.test.js
const { getByText } = require("@testing-library/dom");
require("@testing-library/jest-dom/extend-expect");
const { JSDOM } = require("jsdom");
const fs = require("fs");
const path = require("path");
const html = fs.readFileSync(path.resolve(__dirname, "./index.html"), "utf8");
let dom;
let container;
describe("Test for elements on Home page", () => {
beforeEach(() => {
dom = new JSDOM(html, { runScripts: "dangerously" });
container = dom.window.document.body;
});
it("Page renders a heading element", () => {
expect(container.querySelector("h2")).not.toBeNull();
expect(getByText(container, "Welcome to my Progressive Web Application.")
).toBeInTheDocument();
});
});
这个代码块从获取所有必要的依赖性和加载HTML文件开始。describe 块中的beforeEach 方法用JSDOM 创建 DOM 。
在it 块中运行一个测试,检查标题元素文本的出现。Welcome to my progressive web application.
现在,在package.json 文件中设置你的test 脚本。用这个编辑现有的test 键值对。
...
"scripts": {
"test": "jest"
},
...
现在用这个命令运行测试文件。
npm run test
你的测试将全部通过。现在你已经准备好开始构建你的CI管道了。

为PWA持续集成建立管道
为你的应用程序创建CI流水线的步骤。
- 在应用程序中添加一个管道配置脚本。
- 推送项目到远程仓库:你可以使用GitHub。
- 在CircleCI上添加该仓库作为一个项目。
- 使用你的项目中的配置文件运行管道。
在你项目的根部,创建一个名为.circleci 的文件夹。添加一个名为config.yml 的文件。在config.yml 文件中,输入这段代码。
version: 2.1
jobs:
build:
working_directory: ~/repo
docker:
- image: cimg/node:17.4.0
steps:
- checkout
- run:
name: Update NPM
command: "sudo npm install -g npm"
- restore_cache:
key: dependency-cache-{{ checksum "package-lock.json" }}
- run:
name: Install Dependencies
command: npm install
- save_cache:
key: dependency-cache-{{ checksum "package-lock.json" }}
paths:
- ./node_modules
- run:
name: Run tests
command: npm run test
这个代码块从资源库中检查出应用程序,并为你的Node.js环境更新npm 版本。然后,它安装了依赖性,并缓存了node_modules 文件夹。最后一步是运行测试。
推送你的项目变化到GitHub仓库。确保在node_modules 文件夹中添加一个.gitignore 文件。
现在,把你的应用程序的仓库设置为CircleCI项目。在CircleCI仪表板上,找到你的项目并点击Set Up Project。

你会被提示写一个新的配置文件或使用现有的配置文件。选择现有的一个,并输入你的代码在GitHub上存储的分支的名称。点击Set Up Project。

这将触发CI管线来运行构建过程。这个过程可以在您的CircleCI账户的管道页面上查看。现在你应该已经成功构建了。

恭喜您!所有的步骤都运行得很好,您的测试也很成功。所有的步骤都运行得很完美,你的测试也成功通过。现在你已经为你的持续集成实践设置好了一切。你所需要做的就是把你的代码修改推送到你的仓库,CI管道将自动构建和测试你的应用程序。
总结
在这篇文章中,你成功地建立了一个PWA,并为测试自动化设置了一个CI管道。