发布于 2026-01-06 2 阅读
0

使用 Vue 3 + Vite 和 Pinia 创建、测试和部署单页应用程序

使用 Vue 3 + Vite 和 Pinia 创建、测试和部署单页应用程序

介绍

Vue.js创建于 2014 年,无疑是目前领先的前端框架之一。随着社区的不断壮大和生态系统的扩展,它的地位似乎将在未来很长一段时间内保持稳固。几年前,我曾在几个项目中使用过 Vue 2,那是一段非常愉快的经历。

我认为现在是时候将我的工具集升级到最新版本,并添加像VitePinia这样的新工具了。

本指南将详细介绍如何使用 Vue 3 创建一个功能齐全的单页书店应用示例,并使用 Vite 运行它。此外,它还包含如何使用 Pinia(Vuex 的继任者)添加状态管理以及如何使用Vue Router进行路由的详细说明。

我们将涵盖的核心概念包括:

  • 使用Vite创建一个Vue 3单页应用程序
  • 使用Vue Router管理路由
  • 使用Pinia管理应用程序状态
  • 使用Vite运行、构建和部署应用程序
  • 编写和运行Vue 组件测试
  • 使用Nightwatch.js编写和运行自动化端到端测试

这看起来内容很多,但我认为完全可以在20分钟内全部看完。上面列出的一些主题可以扩展成完整的教程,但现在我只涵盖让一切正常运行所需的基本内容。

最后需要说明的是,本教程不涉及后端部分。虽然数据是通过浏览器 Fetch API(XHR 的后继者)加载的,因此没有严格意义上的服务器端组件,所以添加后端组件也很容易。

实际上,我们将要构建的应用程序可以部署为静态网站。如果您迫不及待地想要立即开始编码,可以使用以下命令启动并运行项目:

git clone https://github.com/beatfactor/middlemarch
npm install
npm run dev
Enter fullscreen mode Exit fullscreen mode

或者在 GitHub 上 fork 该项目:https://github.com/beatfactor/middlemarch

维特

create-vite步骤 1 – 使用脚手架工具设置应用程序

我们将使用官方的 create-vite 脚手架工具来搭建项目结构,所以请确保您已安装 Node 12+ 和 NPM 6+。他们也支持 Yarn 和 PNPM 作为包管理器,但我们只介绍 NPM。

create-vite 工具还会为您创建项目文件夹,所以请确保先进入父文件夹:cd ~/workspace

使用以下命令安装Vite并初始化项目:

npm init vite@latest
Enter fullscreen mode Exit fullscreen mode

然后系统会提示您输入项目名称并选择要使用的库。从列表中选择vue

~/workspace % npm init vite@latest
npx: installed 6 in 1.051s
✔ Project name: … vue-bookstore
? Select a framework: › - Use arrow-keys. Return to submit.
    vanilla
❯   vue
    react
    preact
    lit
    svelte 
Enter fullscreen mode Exit fullscreen mode

然后选择vue作为变体,因为我们不会使用 TypeScript:

? Select a variant: › - Use arrow-keys. Return to submit.
❯   vue
    vue-ts
Enter fullscreen mode Exit fullscreen mode

您应该看到以下输出:

npx: installed 6 in 1.051s
✔ Project name: … vue-bookstore
✔ Select a framework: › vue
✔ Select a variant: › vue

Scaffolding project in /Users/andrei/workspace/vue-bookstore...

Done. Now run:

  cd vue-bookstore
  npm install
  npm run dev 
Enter fullscreen mode Exit fullscreen mode

按照上述步骤操作后,Vite 会输出以下信息,表明应用程序正在运行:


  vite v2.7.7 dev server running at:

  > Local: http://localhost:3000/
  > Network: use `--host` to expose

  ready in 611ms.

Enter fullscreen mode Exit fullscreen mode

让我们访问 localhost:3000 这个网址。欢迎页面如下所示:

Vue HelloWorld 页面

步骤 2 – 使用 Vue Router 添加路由,并使用 Pinia 添加状态管理

让我们来看一下该工具创建的项目目录结构create-vite

vue-bookstore/
 ├── public/
 |    ├── favicon.ico
 ├── src/
 |    ├── assets/
 |    |    └── logo.png
 |    ├── components/
 |    |    └── HelloWorld.vue
 |    ├── App.vue
 |    └── main.js
 ├─── package.json
 ├─── README.md
 └─── vite.config.js
Enter fullscreen mode Exit fullscreen mode

在本指南的这一部分,我们将为项目添加两个新的依赖项:vue-routerpinia。让我们从 NPM 安装它们。

Vue路由器

Vue Router 是 Vue.js 的官方路由工具。我们需要安装与 Vue 3 兼容的版本 4:

npm install vue-router@4 --save
Enter fullscreen mode Exit fullscreen mode

皮尼亚

Pinia是 Vue 生态系统中最新涌现的项目之一,也是 Vue.js 应用的官方状态管理工具。它的 API 与 Vuex(其前身)非常相似,并且旨在实现更快、更轻量级的性能。

您可以使用以下命令从 NPM 安装 pinia:

npm install pinia --save
Enter fullscreen mode Exit fullscreen mode

Vue路由器

设置路由

如果您不熟悉单页应用程序中的路由或状态管理,请不要担心;这两个概念都非常容易理解,一旦您了解其工作原理,它们就会不言自明。

另外,请记住,我们只是在做一个教程,目标是在 20 分钟内完成所有设置并运行,这并不意味着您需要学习 Vue.js 的所有知识。甚至不需要您理解我们将要做的所有内容。

什么是单页应用程序?

既然我们在这里构建的是一个单页应用程序,那么考虑一下这意味着什么以及为什么它是单页的可能会很有用(虽然并非必要)。

单页应用程序(SPA)是一种不会在用户导航到其子页面时重新加载页面的Web应用程序。但是,浏览器地址栏的URL会被修改,就像页面重新加载了一样,这是通过HTML5 History API实现的。

在 Vite 中使用 Vue 组件

使用该工具创建的脚手架create-vite添加了一个非常基础的 Vue 组件,位于src/components/HelloWorld.vue。然后,它在位于 的主应用程序组件中使用src/App.vue

还有两个重要的文件:

  • index.html
  • src/main.js

index.html 文件是浏览器导航到我们应用程序页面时看到的内容,而 main.js 是 Vue.js 应用程序的入口点。

这些文件看起来是这样的:

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite App</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

src/main.js

import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')
Enter fullscreen mode Exit fullscreen mode

添加路线

现在是时候创建应用程序的主路由了。在 Vue 中,每个路由都必须对应一个组件。对于这个应用程序,我们将每个子页面对应一个组件,如下所示:

  • 首页- 我们的书店首页
  • 购物车- 购物购物车和结账页面
  • 登录- 用户登录页面

由于这只是一个示例,因此省略了用户注册页面或产品详情页面等其他页面。此外,登录页面也仅包含模拟登录界面。

对于基本的 HTML 和 CSS,我也使用Bootstrap 5来创建 UI 下拉菜单和表单等功能,当然,您可以使用任何您想要的 UI 库。

我们暂时将页面组件创建为空,以便设置路由。新的 src 目录结构如下所示(移除样板代码后):

src/
  ├── components/
  |    └── TopNavbar.js
  ├── lib/
  |    ├── router.js   
  |    └── store.js
  ├── pages/
  |    ├── cart/
  |    |    ├── cart.css
  |    |    ├── cart.html
  |    |    └── Cart.vue
  |    ├── home/
  |    |    ├── home.css
  |    |    ├── home.html
  |    |    └── Home.vue
  |    ├── sign-in/
  |    |    ├── sign-in.css
  |    |    ├── sign-in.html
  |    |    └── SignIn.vue
  |    └── routes.js
  ├── App.vue
  └── main.js
Enter fullscreen mode Exit fullscreen mode

我们添加了三个页面,每个页面都将保持非常简洁。我们只会添加TobNavbar一些组件,使导航无需页面重新加载即可正常工作。

src/pages/cart/Cart.vue为、src/pages/home/Home.vue添加以下内容src/pages/sign-in/SignIn.vue

<script setup>
import TopNavbar from '../../components/TopNavbar.vue';
</script>

<template>
  <TopNavbar />
</template>
<style></style>

<script>
export default {
  components: {
    TopNavbar
  },

  computed: {},

  mounted() {
  },

  data() {
    return {
    };
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

TopNavbar组件src/components仅包含导航链接。请注意 router-link 组件,它是以下组件的一部分vue-router

<template>
  <router-link to="/">Home</router-link>
  <router-link to="/cart/">Cart</router-link>
  <router-link to="/sign-in/">Sign In</router-link>
</template>
Enter fullscreen mode Exit fullscreen mode

pages/routes.js文件包含应用程序的所有路由声明。其内容如下:

import {createRouter} from 'vue-router'
import Homepage from './home/Home.vue';
import SignIn from './sign-in/SignIn.vue';
import Cart from './cart/Cart.vue';

const routes = [
  {
    path: '/',
    component: Homepage
  },

  {
    path: '/sign-in/',
    component: SignIn
  },

  {
    path: '/cart/',
    component: Cart
  },
]

export default function (history) {
  return createRouter({
    history,
    routes
  })
}
Enter fullscreen mode Exit fullscreen mode

在看到vue-router实际效果之前,我们还需要做两件事:

1)创建路由器并将其添加到主 Vue 应用程序实例中,具体位置src/main.js

import { createApp } from 'vue'
import { createWebHistory } from 'vue-router'

import createRouter from './pages/routes.js'
import App from './App.vue'

const router = createRouter(createWebHistory())
const app = createApp(App)
app.use(router).mount('#app')
Enter fullscreen mode Exit fullscreen mode

2)添加<router-view>组件src/App.vue

<template>
  <router-view></router-view>
</template>
Enter fullscreen mode Exit fullscreen mode

现在如果需要,重新运行npm run dev,然后导航到http://localhost:3000,您将拥有一个启用路由的 Vue 3 应用。

皮尼亚

使用 Pinia 设置状态管理

接下来,我们需要为我们的应用设置 Pinia 商店。该商店用于维护应用状态。

Pinia 是 Vue.js 核心团队的一个新项目,目前是管理应用程序状态的推荐方法。如果您已经熟悉 Vuex,那么上手 Pinia 将非常容易。事实上,Pinia 的 API 比 Vuex 更简洁易懂。

在 Pinia 中,Vue 3 应用只有一个根 store,然后可以有任意数量的子 store。对于我们的书店应用,我们将只使用两个 store:

  • 图书目录:可售图书列表
  • 购物商店:用户想要订购的书籍

创造一个皮尼亚

“pinia”是我们必须首先创建并将其传递给Vue实例的根存储。

我们会进行修改src/main.js,使其看起来像这样:

import { createApp } from 'vue'
import { createWebHistory } from 'vue-router'
import { createPinia } from 'pinia'

import createRouter from './pages/routes.js'
import App from './App.vue'

const store = createPinia()
const router = createRouter(createWebHistory())
const app = createApp(App)

app.use(router).use(store).mount('#app')
Enter fullscreen mode Exit fullscreen mode

下一步是创建单独的目录和购物车商店,并在组件中使用它们。

添加目录商店

创建 Pinia 商店主要包含两件事:

  1. 定义商店
  2. 在一个或多个组件中使用存储

定义商店

与 Vuex 类似,Pinia store 包含状态和两种类型的方法:gettersactions

关于一家商店,需要考虑以下几点:

  • Getters是用于从状态中检索数据的同步函数
  • Actions这些函数也可以是异步的,用于更新状态。
  • 该函数state被定义为返回初始状态的函数

现在是时候在内部创建目录商店src/stores/catalog.js了:

import { defineStore } from 'pinia'

export const useCatalog = defineStore('catalog-store', {
  state: () => {
    return {
      newArrivals: [],
      fetching: false
    }
  },

  getters: {
    results(state) {
      return state.newArrivals;
    },

    isFetching(state) {
      return state.fetching;
    }
  },

  actions: {
    async fetchNewArrivals() {
      this.fetching = true;
      const response = await fetch('/data/new-arrivals.json');
      try {
        const result = await response.json();
        this.newArrivals = result.books;
      } catch (err) {
        this.newArrivals = [];
        console.error('Error loading new arrivals:', err);
        return err;
      }

      this.fetching = false;
    }
  }
})
Enter fullscreen mode Exit fullscreen mode

查看上面的源代码,你会注意到我们有两个 getter 方法(`get( results) isFetching` 和 `get()`)和一个 action 方法(`action() fetchNewArrivals`)。我们没有真正的后端,只有一个位于 `/etc/books/lib/books/lib` 的 JSON 文件,其中/data/new-arrivals.json包含一些书籍,我们将用作我们的目录。

您还会注意到,我们的 getter 方法并没有对数据进行任何特殊处理,因此它们有点多余,但我认为展示如何定义它们仍然是有益的。

在模板中使用商店

将上述定义链接到模板也非常简单。

让我们创建一个名为 `<component>` 的新组件,我们将在页面组件NewArrivals中使用它src/components/NewArrivals.vueHome.vue

<script setup>
import {useCatalog} from '../../store/catalog.js'
</script>

<template>

</template>

<style scoped></style>
<script>
import { mapState, mapActions } from 'pinia'

export default {
  computed: {
    ...mapState(useCatalog, {newArrivals: 'results'})
  },

  methods: {
    ...mapActions(useCatalog, ['fetchNewArrivals']),

    addToCart() {
      // we'll populate this later
    }
  },

  created() {
    // when the template is created, we call this action
    this.fetchNewArrivals();
  }
};
</script>
Enter fullscreen mode Exit fullscreen mode

Home.vue组件变为:

<script setup>
import TopNavbar from '../../components/TopNavbar.vue';
import NewArrivals from '../../components/NewArrivals.vue';
</script>

<template>
  <TopNavbar />
  <NewArrivals />
</template>

<style></style>

<script>
export default {
  components: {
    TopNavbar,
    NewArrivals
  },
  computed: {},
  mounted() {},
  data() {
    return {};
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

下图展示了应用程序中商店和组件如何协同工作:

Pinia 工作流程图

我还编写了一个商店和一个购物车组件,但我不会将其包含在教程中,因为它们的机制类似,而且您可以在存储库中查看源代码,其中包含了所有内容,甚至包括一些样式。

步骤 3 – 测试 Vue.js 组件

组件测试是一种UI测试,它将组件独立渲染,不与其他应用程序组件交互,目的是验证其功能。它通常是一种在端到端测试之前进行的测试策略,我们将在下一节详细介绍端到端测试。

我们需要安装Vue TestUtils项目,它是 Vue.js 的官方单元测试库,我们需要的是面向 Vue 3 的版本。您可以使用以下命令从 NPM 安装它:

npm install @vue/test-utils@next --save-dev
Enter fullscreen mode Exit fullscreen mode

Nightwatch.js 预览

安装 Nightwatch.js 和 ChromeDriver

我们将使用 Nightwatch.js 进行组件测试和端到端测试。Nightwatch 已经是 Vue.js 团队推荐的测试框架之一,并且与 Vue 几乎同时发布。

它最近通过vite-plugin-nightwatch 插件获得了对 Vue 组件测试的支持(目前仍处于 beta 测试阶段)。接下来,我们将使用以下命令安装 Nightwatch v2:

npm install nightwatch--save-dev
Enter fullscreen mode Exit fullscreen mode

我们还需要vite-plugin-nightwatch前面提到的那些:

npm install vite-plugin-nightwatch --save-dev
Enter fullscreen mode Exit fullscreen mode

Nightwatch 使用W3C WebDriver API进行浏览器自动化任务,我们还需要安装chromedriverNPM 包,因为我们将使用 Chrome 来运行测试。

npm install chromedriver --save-dev
Enter fullscreen mode Exit fullscreen mode

测试 <新品上市> 组件

至此,我们终于可以开始为 NewArrivals 组件编写实际的测试了。

前面提到的内容vite-plugin-nightwatch包括一个测试渲染页面,而 Nightwatch 已经包含了运行我们组件初始测试所需的一切。

创建一个文件夹test,并在其中创建两个子文件夹:

  • component这将进行组件测试
  • e2e这将进行端到端测试

我们还需要一个nightwatch.conf.js配置文件,但我们可以直接运行 Nightwatch,它会自动为我们创建配置文件。只需确保chromedriver也安装了 Nightwatch(当然还有 Chrome 浏览器)。

请确保当前工作目录是项目根目录,然后运行​​Nightwatch 自带的示例测试duckDuckGo。我们选择这个测试是因为它速度最快:

$ npx nightwatch examples/tests/duckDuckGo.js
Enter fullscreen mode Exit fullscreen mode

项目结构现在应该如下所示:

vue-bookstore/
 ├── public/
 |    ├── data/
 |    └── favicon.ico
 ├── src/
 ├── ...
 |    └── main.js
 ├── test/
 |    ├── component/
 |    └── e2e/
 ├─── nightwatch.conf.js
 ├─── package.json
 ├─── README.md
 └─── vite.config.js
Enter fullscreen mode Exit fullscreen mode

接下来,我们将创建一个名为 ` newArrivalsTest.jsinside` 的新文件test/component。在其中,我们将添加一个基本测试,该测试会挂载组件并检查返回的元素是否可以在页面中找到(即组件是否已挂载)。

describe('New Arrivals Component Test', function() {

  it('checks if the component has been mounted', async (browser) => {
    const component = await browser.mountVueComponent('/src/components/new-arrivals/NewArrivals.vue', {
      plugins: {
        router: '/src/lib/router.js'
      }
    })
    expect(component).to.be.present; 
  });
});
Enter fullscreen mode Exit fullscreen mode

Nightwatch 使用的语法与 Mocha 相同describe()。如果您已经熟悉 Mocha,甚至可以将其用作测试运行器,但我们目前暂不这样做。如果您想使用 Mocha,只需在 Nightwatch 配置文件中添加几个参数即可,Nightwatch 网站上有相关文档。

现在是时候运行上述测试了,为此我们将使用 Chrome 浏览器运行 Nightwatch,如下所示:

npx nightwatch test/component/newArrivalsTest.js --env chrome
Enter fullscreen mode Exit fullscreen mode

这将打开 Chrome 浏览器并渲染组件,然后执行测试。如果您不希望在测试期间看到浏览器窗口弹出,可以传递参数--headless,如下所示:

npx nightwatch test/component/newArrivalsTest.js --env chrome --headless
Enter fullscreen mode Exit fullscreen mode

测试输出应如下所示:

[New Arrivals Component Test] Test Suite
──────────────────────────────────────────────────────────────
ℹ Connected to ChromeDriver on port 9515 (652ms).
  Using: chrome (97.0.4692.99) on MAC OS X.


  Running tests the component:
──────────────────────────────────────────────────────────────
  ✔ Expected element <web element{e53f9b1e-11d3-4dc4-8728-4d3cd077343e}> to be present (1ms)

OK. 1 assertions passed. (781ms)
Enter fullscreen mode Exit fullscreen mode

当然,您可以通过访问文档页面或运行以下命令来查阅 Nightwatch 运行器提供的所有 CLI 选项:

npx nightwatch --help
Enter fullscreen mode Exit fullscreen mode

扩展 <NewArrivals> 测试

您可能已经注意到,我们的组件测试覆盖范围不够广,这意味着该测试的实用性还不够高。因此,我们将对其进行少量扩展。

我们将检查该NewArrivals组件,并检查其中是否有名为 的属性newArrivals,该属性在 html 中用于渲染结果。

现在的测试代码是这样的。我们重构了组件挂载到钩子函数中before,这样就可以只在测试代码块内部进行检查it。该expect库由 Nightwatch 提供,它基于流行且功能强大的Chai.js断言库。更多关于如何使用该库的信息,expect请访问Nightwatch 文档网站。

describe('New Arrivals Component Test', function() {

  let component;

  before(async () => {
    component = await browser.mountVueComponent('/src/components/new-arrivals/NewArrivals.vue', {
      plugins: {
        router: '/src/lib/router.js'
      }
    })
  });

  it('checks if the component has been mounted', function(browser) {
    expect(component).to.be.present;
    expect(component).to.have.property('newArrivals');
    expect(component).text.toContain('The Memory Police')

    expect.elements('div.col-md-6').count.toEqual(4);       expect(component.property('newArrivals')).to.be.an('array').with.length(1);   
  });
});
Enter fullscreen mode Exit fullscreen mode

步骤 4 – 对 Vue.js 应用进行端到端测试

本教程即将结束,在我们认为已经拥有一个可运行的 Vue.js 应用程序之前,我们需要添加对端到端测试的支持,并在 Github Actions 上设置 CI 流水线。

幸运的是,我们无需安装或配置任何其他工具(除非需要一些高级的报告工具),目前 Nightwatch 就能满足我们端到端自动化测试的所有需求。除了 Chrome 之外,Nightwatch 还内置支持所有主流浏览器,包括 Firefox、Edge 和 Safari,这得益于它与 W3C WebDriver API 和 Selenium 的集成。它还允许您使用BrowserStackSauceLabsCrossBrowserTestingLambdaTest等分布式云测试平台。

目前,我们先简化一下,只专注于编写一些基本的自动化测试,并在 Chrome、Firefox 和 Safari 中运行它们。

编写首页端到端测试

让我们从首页端到端测试开始,并在 下创建一个新文件test/e2e/homePageTest.js。语法与组件测试相同,但运行端到端测试时,我们将使用应用程序的编译版本。

当然,我们可以用开发版本运行这些测试,但据我所知,软件开发中的惯例是在尽可能模拟生产环境的环境中运行端到端测试。我想,这就是为什么它们被称为端到端测试的原因吧,因为它们是针对最终产品运行的。

运行生产版本

要运行生产构建,我们有两种选择,每种选择都涉及运行一个Vite命令,该命令被封装在 NPM 任务中。

  1. npm run build这将生成 index.html 和其他静态资源。如果您已经设置了本地 Web 服务器,则可以使用此选项。
  2. npm run preview这将生成一个生产版本,并默认使用内置的开发服务器运行它http://localhost:5000

第二个选项显然更直接,所以我们直接运行preview命令看看会发生什么:

$ npm run preview

> vue-bookstore@0.0.0 preview /Users/andrei/workspace/vue-bookstore
> vite preview

  > Local: http://localhost:5000/
  > Network: use `--host` to expose

Enter fullscreen mode Exit fullscreen mode

编写测试脚本

现在我们已经有了可以用于生产环境的构建版本,可以开始编写实际的测试代码了test/e2e/homePageTest.js。我们先从简单的测试开始,只包含以下内容:

describe('Homepage End-to-end Test', () => {

  it('tests if homepage is loaded', browser => {
    browser
      .navigateTo('http://localhost:3000')
      .assert.visible('#app .new-arrivals-panel')
      .expect.elements('#app .new-arrivals-panel .col-md-6').count.toEqual(4)
  });

  it('adds 2 volumes of "Rhinoceros and Other Plays" to cart', browser => {
    browser
      .click('.new-arrivals-panel .col-md-6:nth-child(2) button.add-to-cart')
      .click('.new-arrivals-panel .col-md-6:nth-child(2) button.add-to-cart')
      .assert.textEquals('.shopping-cart .badge', '2');
  });

  after(browser => browser.end());
});
Enter fullscreen mode Exit fullscreen mode

该测试验证“新品上市”面板是否显示在页面上,以及是否包含我们已经看到的全部 4 个条目。

在 Chrome 浏览器中运行测试脚本

要在 Chrome 中运行此命令,其与组件测试的命令非常相似:

npx nightwatch test/e2e/homePageTest.js --env chrome
Enter fullscreen mode Exit fullscreen mode

输出结果为:

[Homepage End-to-end Test] Test Suite
──────────────────────────────────────────────────────────────
ℹ Connected to ChromeDriver on port 9515 (2454ms).
  Using: chrome (97.0.4692.99) on MAC OS X.


  Running tests the homepage:
──────────────────────────────────────────────────────────────
  ✔ Testing if element <#app .new-arrivals-panel> is visible (157ms)
  ✔ Expected elements <#app .new-arrivals-panel .col-md-6> count to equal: "4" (18ms)

OK. 2 assertions passed. (765ms)
Enter fullscreen mode Exit fullscreen mode

在 Firefox 中运行测试脚本

如果我们还想在 Firefox 浏览器中运行端到端测试,只需安装GeckoDriver(W3C WebDriver API 的 Firefox 特定实现)即可。除非您想进一步自定义,否则无需其他配置即可使其正常工作。

那么,让我们从 NPM 安装它吧:

npm i geckodriver --save-dev
Enter fullscreen mode Exit fullscreen mode

然后使用以下命令运行 Nightwatch:

npx nightwatch test/e2e/homePageTest.js --env firefox
Enter fullscreen mode Exit fullscreen mode

输出结果如下:


[Homepage End-to-end Test] Test Suite
──────────────────────────────────────────────────────────────
ℹ Connected to GeckoDriver on port 4444 (1737ms).
  Using: firefox (96.0.2) on MAC (20.6.0).


  Running tests the homepage:
──────────────────────────────────────────────────────────────
  ✔ Testing if element <#app .new-arrivals-panel> is visible (54ms)
  ✔ Expected elements <#app .new-arrivals-panel .col-md-6> count to equal: "4" (6ms)

OK. 2 assertions passed. (612ms)
Enter fullscreen mode Exit fullscreen mode

在 Safari 中运行测试脚本

如果你使用的是 Mac,那么safaridriver它可能已经安装好了,具体取决于你的 Safari 版本。

您可以使用以下方法进行检查:

safaridriver --help
Enter fullscreen mode Exit fullscreen mode

输出结果应如下所示:

Usage: safaridriver [options]
    -h, --help                Prints out this usage information.
    --version                 Prints out version information and exits.
    -p, --port                Port number the driver should use. If the server is already running, the port cannot be changed. If port 0 is specified, a default port will be used.
    --enable                  Applies configuration changes so that subsequent WebDriver                           sessions will run without further authentication.
    --diagnose                Causes safaridriver to log diagnostic information for all sessions hosted by this instance. See the safaridriver(1) man page for more details about diagnostic logging.
Enter fullscreen mode Exit fullscreen mode

在 Safari 中运行第一个测试之前,您只需使用以下命令启用自动化:

safaridriver --enable
Enter fullscreen mode Exit fullscreen mode

然后只需运行 Nightwatch 测试即可:

npx nightwatch test/e2e/homePageTest.js --env safari
Enter fullscreen mode Exit fullscreen mode

在多个浏览器中并行运行

如果您需要在多个浏览器中运行 Nightwatch 测试(组件测试或端到端测试),您也可以在多个浏览器中并行运行这些测试。

只需将浏览器以逗号分隔的列表形式传递即可(不含空格):

在 Firefox 和 Chrome 中运行

 npx nightwatch test/e2e/homePageTest.js --env firefox,chrome
Enter fullscreen mode Exit fullscreen mode

在 Firefox、Chrome 和 Safari 中运行

 npx nightwatch test/e2e/homePageTest.js --env firefox,chrome,safari
Enter fullscreen mode Exit fullscreen mode

Nightwatch 还支持并行运行测试,方法是将测试脚本文件的总数分配到可配置数量的 worker 上。但由于我们目前只有一个文件,所以这部分内容将略过。更多关于并行处理的信息,请访问Nightwatch 文档网站。

步骤 5 – 使用 GitHub Actions 启用持续集成

看来是时候收尾并整合所有内容了。在GitHub Actions中启用持续部署之前,我们需要创建testNPM任务。

创建“npm test”任务

现在我们的示例项目中既有组件测试也有端到端测试。当然,这只是最基本的测试,所以并不全面,但我认为这是一个很好的开始。

要让 Nightwatch 运行测试文件夹内的所有测试,最简单的方法是将该文件夹作为第二个 CLI 参数传递。我们将添加一个名为 `npm test` 的新 NPM 任务,test因此让我们编辑 `npm test` 文件package.json,并在“scripts”字典中添加以下内容:

{
  "test": "nightwatch ./test"
}
Enter fullscreen mode Exit fullscreen mode

我们可以运行 NPM 任务并传递与 Nightwatch 相关的 CLI 参数,如下所示:

npm test -- --env chrome --headless
Enter fullscreen mode Exit fullscreen mode

我们将使用--headless模式在 Github Actions 中运行测试。

添加 GitHub Action 工作流

最后,我们可以添加 Github Actions 工作流,以便我们的测试可以在每次推送和每次拉取请求时运行。

这样做非常简单。我们将使用 Node.js 模板,并在列表中添加一些新步骤,具体如下:

  • 在后台启动开发服务器
  • 构建项目并以预览模式启动开发服务器,同时也在后台运行。
  • 在 Chrome 浏览器中以无头模式运行组件测试和端到端测试

创建 GitHub Actions 工作流意味着在文件夹中添加一个名为node.js.yml.github/workflows的新文件,其内容应如下所示。当您从 GitHub 项目导航到 Actions 部分并选择 Node.js 模板时,大部分内容将自动生成。

name: Node.js CI

on:
  push:
    branches: [ main ]

  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [12.x, 14.x]
    steps:
      - uses: actions/checkout@v2
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v2
        with:
          node-version: ${{ matrix.node-version }}

      - run: npm ci

      - name: Start vite dev server
        run: npm run dev &

      - name: Build the app
        run: npm run build

      - name: Start vite dev server in preview
        run: npm run preview &

      - name: Run Nightwatch tests
        run: npm test
Enter fullscreen mode Exit fullscreen mode

就是这样。每次新的 Git 推送或新的拉取请求都会触发一次新的构建。构建将在两个独立的环境中运行,一个用于 Node 12,另一个用于 Node 14,具体配置已在工作流定义中确定。

接下来该何去何从

该项目已发布在 GitHub 上,网址为https://github.com/beatfactor/middlemarch,其中包含本文介绍的所有代码以及一些额外的样式和图片。此外,它还包含购物车代码和一个模拟结账页面。

项目预览

按照通常的步骤,您就可以在本地计算机上运行它:

git clone https://github.com/beatfactor/middlemarch
npm install
npm run dev
Enter fullscreen mode Exit fullscreen mode

欢迎提交拉取请求或报告问题。

获取支持

Vue3、Vite 和 Pinia**

Vue.js 核心团队通过以下渠道为 Vue3、Vite 和 Pinia 提供社区支持:

Nightwatch.js

如需获得与 Nightwatch 测试相关的任何支持,我们设有以下渠道:

文章来源:https://dev.to/andreirusu_/create-test-and-deploy-a-single-page-app-with-vue-3-vite-and-pinia-5097