如何Dockerize您的端到端验收测试

本文作为使用Selenium Docker映像以及CodeceptJS和Express服务器的“操作方法”指南。

其中,我们将涵盖:

  • 什么是E2E验收测试?
  • 为什么要使用Docker?
  • 松散耦合的测试工具
  • 测试工具层
  • 创建测试项目

E2E验收测试

验收测试是典型软件开发过程中的一个阶段。它涵盖了测试,以确定产品是否符合总体要求规格,以及是否“已接受”为准备交付。在将产品投入生产之前,这通常是测试的最后阶段。这可能包括基于用户的验收测试,基于业务的验收测试,甚至包括alpha / beta测试。

端到端(E2E)测试是验收测试的一种实现。这是验收测试的方法,但这些术语不是同义词。它允许从头到尾测试应用程序的流程,看它是否按设计执行。在Web应用程序的情况下,它将涉及确定用户场景并测试用户将按顺序采取的每个步骤。如果方案未成功完成,则测试失败。

存在各种工具来自动化该过程,模拟用户与应用程序的交互。

为何选择Docker?

创建和运行E2E测试通常被认为是一个片状和复杂的过程。它需要大量的设置,在不同的机器或CI(持续集成)环境中运行时仍然很容易失败。为本地测试和CI测试安装和维护不同的浏览器和WebDrivers需要时间。即使完成了,它仍然会因为简单的问题而失败,例如开发人员本地计算机或CI中屏幕分辨率是否不同

Docker的标准优势也适用:无需处理操作系统兼容性或安装了依赖项。要运行Selenium Server,您需要安装Java(或者至少要显式启动/停止)。要运行Express,您需要Node.js,而对于Chrome,您需要Chrome本身以及ChromeDriver。

使用Docker时,可以消除这些依赖性。您只需使用已包含这些容器的不同容器,无论它们在哪台机器上运行,它们的功能都完全相同。当您认为将Docker构建到CI中是多么容易时,Docker化您的测试过程将成为一个明显的选择。

松散耦合的测试工具

在编写E2E测试时有几个框架可用,而对于新手来说,很难知道选择哪个并投入时间。如果选错了,你就会浪费很多时间。

这就是CodeceptJS的用武之地。CodeceptJS是一个测试框架,采用场景驱动的行为驱动开发(BDD)方法,使用API​​语言,非工程师易于理解和使用。然而,或许更重要的是,它是后端不可知的。它是在几个流行的测试库(例如WebDriverIO或Puppeteer)之上编写的,它的单个高级API可以与您选择的任何一个进行通信。它的创作者认为

您的测试不应该绑定到您的执行引擎。无论您选择Selenium还是Puppeteer,您的测试应该看起来几乎相同。如果您(稍后)感觉到一个引擎的限制,您可以轻松地将测试切换到其他引擎。

测试工具层

 

模拟用户与浏览器交互的每一层都有一些不同的产品

让我们采用自下而上的方法来研究每个层如何构建在最后一层上。

最初引用Selenium是值得的,Selenium是一个长期运行的项目,其中包含一组活跃使用的工具,它们现在由Selenium WebDriver,Grid,Server和IDE组成。在创建这些工具时,他们设定了许多行业标准,通常以他们来自Selenium产品的名字而令人困惑地命名。这可以在'Selenium WebDriver'和在其开发中建立的'WebDriver线协议'中看到。适用的那些将在下面更详细地显示。

浏览器

任何网络浏览器:Chrome,Firefox,Internet Explorer,Safari,Opera等。通常在文档中称为“用户代理”。

W3C的WebDriver线协议

WebDriver有线协议是一种与Web浏览器交互的平台和语言中立方式。它定义了一个在请求/响应对中使用JSON over HTTP 的通用RESTful Web服务。它允许从外部源操作DOM元素,同时还允许导航到网页,用户输入,JavaScript执行等。

最初由Selenium为Selenium WebDriver编写,该协议现已进入编辑草案阶段,成为官方的W3C标准

其他协议确实退出,但这里不会详细介绍。所有解释都将假设一个实现WebDriver有线协议的后端。

另一个值得注意的协议是Puppeteer使用的Chrome DevTools协议。Puppeteer不使用Selenium Server,并捆绑了最新版本的Chromium,供本地使用。如果你想在Docker中运行Puppeteer,你可以使用CodeceptJS图像(Puppeteer和Nightmare附带)或者按照官方指南创建可以支持它的自定义图像

浏览器WebDrivers

这些是金属丝的webdriver协议的浏览器的特定实现中,例如ChromeDriver用于Chrome或GeckoDriver用于Firefox。每个都充当一个独立的服务器,用于接收来自使用WebDriver API 的客户端的请求(通常是测试所在的位置)。为了与目标浏览器通信,必须安装正确的WebDriver实现。

Selenium Server

如果测试是在定义它们的同一台机器上运行,那么使用的客户端WebDriver API实现(如下所述)可以直接与浏览器WebDriver通信,并且不需要Selenium Server

但是,如果要在不同的计算机上运行测试,无论是在CI中,在跨多个计算机或虚拟机(VM)的Selenium Grid设置中,在远程测试平台(如BrowserStackSauceLabs)上,还是在Docker中,都要运行 Selenium使用服务器。它充当代理,将来自客户端WebDriver API的请求转发到正确的浏览器WebDriver,并从浏览器传回响应。

 

正如我们稍后将看到的,'machine'也可以换成'container'

客户端WebDriver实现

各种工具实现了客户端WebDriver有线协议。这里的协议可以看作是通过上述层向浏览器发送请求的API。使用该协议的许多工具都是完整的框架,例如WebDriverIO,它们包含自己的测试运行器。

其他实现包括:原始的 Selenium WebDriver,Protractor,Appium等。

每个库的目标都是为了获得相同的结果,但焦点和API实现略有不同。这可以像Protractor browser.get(url)WebDriverIO 一样基本browser.url(url)

一个API来统治它们

如本节开头所述,这是CodeceptJS发挥作用的地方。它将其他客户端WebDriver协议(或其他)实现称为“ 帮助程序 ”,并允许您在使用一种API语言时指定您喜欢的帮助程序。CodeceptJS并不关心所选帮助程序正在使用哪种协议。

WebDriverIO,Puppeteer,Protractor,Nightmare和Appium都是现有的助手。

在CodeceptJS中,I.amOnPage(url)无论选择哪个帮助程序,上一个命令都是如此。这意味着如果您想将后端切换到支持的其他助手之一,则不必重新编写测试。它可以覆盖或添加到通过自定义类,你应该想的默认API方法。

创建测试项目

有这么多层,这开始听起来很复杂,但在CodeceptJS的初始化脚本和Docker镜像之间,我们可以快速找到一个有效的例子。

我们将生产什么
 

现在将使用两个容器,但这可以扩展

我们将在CodeceptJS中编写一个简单的测试,指定一个WebDriverIO后端帮助程序,它将与standalone-firefox Docker容器中的远程浏览器进行通信。我们将使用Express“hello world”应用程序,但这可以被您希望的任何应用程序取代。

 

很快,只需要两个命令来运行Dockerized应用程序和所有测试套件

一旦我们完成了所有设置,我们将只能运行两个命令来运行测试:

  • docker-compose up --build
  • docker exec -it app npm run test:e2e

通过在两个并排的终端窗口中运行,我们可以看到容器正在运行并且测试实时执行。

先决条件
  • Docker,适用于您正在开发的任何一台机器。
  • 您还可以安装Node.js,&npm进行本地开发和调试,但这些也可以在Docker中完全运行。
文件结构

我们将在下面生成文件结构。你可以在Github上看到一个工作示例

|-- .gitignore 
|-- output/
|-- Dockerfile
|-- app.js
|-- docker-compose.yml
|-- package.json
|-- package-lock.json
|-- e2eTests/
|-- common_test.js
|-- docker.conf.js
依赖

首先,我们将使用Express作为依赖项创建package.json,将CodeceptJS和WebDriverIO创建为dev依赖项。

{
  "name": "example-standalone-firefox",
  "version": "1.0.0",
  "description": "Example of Dockerizing E2E testing",
  "scripts": {
    "start": "node app.js",
    "test:e2e": "codeceptjs run --steps --verbose --config=./e2eTests/docker.conf.js"
  },
  "dependencies": {
    "express": "^4.16.3"
  },
  "devDependencies": {
    "codeceptjs": "^1.2.0",
    "webdriverio": "^4.12.0"
  }
}

 

我们还包括两个脚本,一个用于运行我们将添加的Express应用程序(npm run start),另一个用于运行我们的CodeceptJS测试(npm run test:e2e)。

codeceptjs run --steps --verbose --config=./e2eTests/docker.conf.js

 

--steps非常适合在测试运行时在终端中显示输出,同时--verbose进一步扩展详细程度。--verbose可能不需要作为标准,但有利于查看示例的工作原理。--config向我们展示了后端配置文件的路径,在这种情况下保存在一个单独的e2eTests目录中。

我们的应用

接下来我们需要一个应用来测试。为此,我们将运行Express“ hello world ”应用程序app.js

const express = require('express');

const app = express();

app.get('/', (req, res) => res.send('Hello World!'));

const server = app.listen(3000, () => {
    const port = server.address().port
    console.log(`Example app listening on port ${port}`)
 })

 

您可以使用npm run start然后localhost:3000在浏览器中查看此内容。

测试配置

CodeceptJS需要两个文件,一个配置文件和一个测试文件。测试文件非常简单:它测试可以访问应用程序,保存屏幕截图,并检查页面上是否可以看到文本“Hello”。

Feature('Basic test');

Scenario('navigate to homepage', I => {
  I.amOnPage('http://app:3000');
  I.saveScreenshot('frontpageScreenshot.png');
  I.see('Hello');
});

 

我们将使用多个Docker容器的第一个迹象显示在使用app:3000而不是localhost:3000localhost只能在一个容器内理解。如果正在从另一个容器运行命令(在本例中是我们的第二个Selenium容器中的Firefox),那么它需要更明确的引用。我们可以直接使用第一个容器的IP地址,但使用容器的名称更容易阅读。

在这种情况下,app将是运行应用程序的容器的名称,因此我们可以使用app:3000。不要担心,如果你还没有遵循这一点,看看我们docker-compose.yml的结构将有所帮助。

我们还需要一个主配置文件。这可以用JSON或JS编写,但在这里我们使用JS。我们来看看这个:

exports.config = {
  tests: './*_test.js',    // how to know which files are test files
  output: './output',      // where to save screenshots
  helpers: {
   WebDriverIO: {               // which backend helper to use
     url: 'http://app:3000',    // a base URL to start on
     host: 'firefox-container', // identifying where selenium runs
     browser: 'firefox',        // a series of config options
     smartWait: 5000,              
     waitForTimeout: 10000,
     desiredCapabilities: {        // for a demo app we do not want 
         acceptInsecureCerts: true,   to worry about SSL certs
     }
   },
  },
  name: 'codeceptjs-docker',
};

 

设置Docker

回到上面“我们将要生成什么”部分中的图表,我们可以看到我们将使用两个Docker容器。他们必须彼此了解并能够沟通。一个将包含我们的应用程序和测试,一个包含Selenium Server,GeckoDriver和Firefox,因此我们不需要在本地计算机上安装Firefox。

Docker Compose是一个“定义和运行多容器Docker应用程序的工具。”它使用命令 启动Docker容器docker-compose up,并使用它来阻止它们docker-compose down。如果正在使用用户定义的Dockerfile,--build则用于构建它,或者第一次docker-compose up运行,或者如果对Dockerfile进行了更改。docker-compose.yml是定义up命令将执行的操作的文件。

我们的下一步是创建这个docker-compose.yml。它严重依赖于缩进。

version: "2"        // which version of compose syntax you are using
services:
  app:
    container_name: app  // explicit so we can use this for app:3000
    build: .             // a self defined Dockerfile, see below
    ports:               // exposes port 3000 (where express runs)
      - "3000:3000"         to other containers, and to our local       
    depends_on:             browser
      - firefox-container
    volumes:             // maps so changes to these can be seen
      - ./e2eTests:/e2eTests
      - ./package.json:/package.json
      - ./package-lock.json:/package-lock.json
      - ./.gitignore:/.gitignore
      - ./app.js:/app.js

  firefox-container:      // we'll look at this below
    container_name: firefox-container
    image: selenium/standalone-firefox:3.12.0-americium
    volumes:
      - /dev/shm:/dev/shm
    ports:
      - "4444:4444"

 

对于我们的Selenium服务器,驱动程序和浏览器,我们使用可从公众预先定义的图像泊坞枢纽称为硒/独立Firefox的。我们指定我们想要的版本,3.12.0-americ。如果我们没有指定它,默认情况下将使用最新的图像(这不是一件坏事)。至于建议,我们将其配置为共享主机的内存,以防止浏览器崩溃中运行,并揭露4444端口,默认端口硒。我们还将此映射到本地计算机上的端口4444,允许我们localhost:4444/wd/hub/static/resource/hub.html在浏览器中访问。

对于我们的app容器,我们不只是使用由其他人构建的图像,而是编写Dockerfile来指定我们的应用程序的构建方式。与selenium-firefox容器相同,我们在这种情况下公开了一个端口3000,因为Express是默认运行的地方。通过使用3000:3000我们可以localhost:3000在Docker中运行应用程序时访问它,以便在我们的本地浏览器中查看它。

我们的Dockerfile使用公共node:carbon映像作为基础,设置工作目录,将一些文件从本地计算机复制到容器,运行npm install以便容器具有所有需要的依赖项,然后运行npm start我们指定的命令。

FROM node:carbon 
WORKDIR ./ 
COPY ./package.json ./package-lock.json ./app.js ./ 
RUN npm install 
CMD [ "npm", "start" ]

 

这意味着在docker-compose up --build运行时,它将遵循这些步骤,从而使我们的应用程序准备好并在端口3000上运行。

注意:--build只有在第一次docker-compose up运行时,或者对Dockerfile或其中执行的步骤进行了更改时才需要该标志。例如,如果我们在我们中添加了另一个依赖项,package.json那么如果我们没有重建我们的映像,那么Doc​​ker就不会知道它,就像npm install在Dockerfile中运行一样。

运行测试

我们现在有一个简单的应用程序,为它编写的测试,以及将运行我们的应用程序,Selenium Server和Firefox的Docker Compose配置。

我们可以开始使用所有这些docker-compose up --build

正在运行的Docker容器中运行命令,docker exec可以从另一个终端窗口使用。格式为:

docker exex <flags> <container_name> <command>

我们将使用的命令是:

docker exec -it app npm run test:e2e

我们现在可以看到我们的测试正在运行,并在执行时看到每个步骤!从这里我们可以扩展我们的测试,添加其他测试(结束文件名_test.js),并使用相同的两个命令来运行它们。无需更多设置。

您现在拥有一个易于扩展的E2E测试设置,无论运行哪台计算机,都可以依赖该设置以相同的方式运行。它是用API命令编写的,开发人员和非开发人员都可以轻松理解。现在剩下的就是决定你的应用应该具备哪种行为,然后进行测试!

最后的话

SeleniumHQ还生成用于Chrome测试的 Docker 镜像,以及使用Selenium Grid一次运行多个Chrome和Firefox实例的图像。

CodeceptJS还有在Docker中运行CodeceptJS的说明,因此不需要在应用程序中将其指定为依赖项。

在我写的一篇名为“ 亚马逊弹性容器服务的初学者指南 ”的文章的第一部分中,可以看到关于Docker如何工作的更具技术性,但仍然是初级的描述

感谢您阅读?

更新: 
我最近为寻找测试复杂应用程序的后续步骤的任何人编写了Customizing CodeceptJS e2e测试

资源

转载于:https://www.cnblogs.com/a00ium/p/10874886.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值