使用Selenium和Docker进行端到端测试的终极指南

Automated end to end testing is the most effective way to test your app. It also requires the least effort to get the benefit of tests if you currently have no tests at all. And you don’t need a ton of infrastructure or cloud servers to get there. In this guide we’ll see how we can easily overcome the two main hurdles of end to end testing.

自动化的端到端测试是测试应用程序的最有效方法。 如果您目前根本没有测试,那么也需要最少的精力来获得测试的好处。 而且,您不需要大量的基础架构或云服务器即可到达那里。 在本指南中,我们将看到如何轻松克服端到端测试的两个主要障碍。

The first hurdle is Selenium. The API you use to write tests is ugly and non-intuitive. But it is not that difficult to use, and with a few convenient functions it can become a breeze to write Selenium tests. The effort is well-rewarded because you can automatically test your end users' flows end to end.

第一个障碍是Selenium。 您用来编写测试的API难看且不直观。 但这并不难使用,并且具有一些方便的功能,可以轻松编写Selenium测试。 付出的努力是值得的,因为您可以自动测试端用户的端到端流量。

The second hurdle is putting components together in an isolated environment. We want the frontend, the backend, the database and everything else your app uses. We will use Docker compose to put things together and automate the tests. It is easy even if you have your components in different Git repositories.

第二个障碍是将组件放置在隔离的环境中。 我们需要前端,后端,数据库以及您的应用程序使用的所有其他功能。 我们将使用Docker compose将内容放在一起并自动执行测试。 即使您的组件位于不同的Git存储库中,也很容易。

在Selenium中编写端到端测试 (Writing end to end tests in Selenium)

Even if you are an API only business, you have a frontend, and an admin or back office frontend. So end to end tests ultimately talk to a frontend application.

即使您是仅使用API​​的企业,也可以拥有一个前端以及一个管理员或后台办公室前端。 因此,端到端测试最终会与前端应用程序对话。

The industry standard tool is Selenium. Selenium provides an API to talk to the web browser and interact with the DOM. You can check what elements are displayed, fill inputs and click around. Anything a real user would do with your application, you can automate.

行业标准工具是Selenium。 Selenium提供了一个与Web浏览器对话并与DOM交互的API。 您可以检查显示了哪些元素,填充输入并单击。 真正的用户对您的应用程序所做的任何事情,都可以实现自动化。

Selenium uses something called the WebDriver API. It is not very handy to use at first glance. But the learning curve is not steep. Creating a few convenience functions will get you productive in no time. I won’t go into the details of the WebDriver API here. You can have a look at this excellent article to dig deeper.

Selenium使用一种称为WebDriver API的东西。 乍看之下使用起来不是很方便。 但是学习曲线并不陡峭。 创建一些便捷功能将使您立即获得生产力。 在这里,我不会详细介绍WebDriver API。 您可以看一下这篇出色的文章,以进行更深入的研究。

There are also libraries to make your life easier. Nightwatch is the most popular.

还有图书馆,使您的生活更轻松。 守夜人是最受欢迎的。

If you have an Angular application, Protractor is your best friend. It integrates with the Angular event loop and allows you to use selectors based on your model. That is gold.

如果您有Angular应用程序,则量角器是您最好的朋友。 它与Angular事件循环集成在一起,并允许您基于模型使用选择器。 那是黄金。

Writing a test for your most critical user feature or your app should take only a few hours, so go ahead. It will run automatically ever after. Let's see how.

为您最关键的用户功能或应用编写测试仅需要几个小时,因此请继续。 此后它将自动运行。 让我们看看如何。

在Docker中运行测试 (Running your tests in Docker)

We need to run our tests in an isolated environment so the outcome is predictable. And so we can enable Continuous Integration easily. We'll use Docker compose.

我们需要在孤立的环境中运行测试,以便可以预测结果。 因此,我们可以轻松启用持续集成 。 我们将使用Docker compose。

Selenium provides Docker images out of the box to test with one or several browsers. The images spawn a Selenium server and a browser underneath. It can work with different browsers.

Selenium提供了开箱即用的Docker映像,可以使用一个或多个浏览器进行测试。 这些图像产生一个Selenium服务器和下面的浏览器。 它可以与不同的浏览器一起使用。

Let’s start with one browser for now: headless-chrome. You can see the docker-compose.yml file below (the commands are from an Angular example).

现在让我们从一个浏览器开始:headless-chrome。 您可以在下面看到docker-compose.yml文件(命令来自Angular示例)。

Note: If you've never used Docker you can easily install it on your computer. Docker has the troublesome tendency of forcing you to sign up for an account just to download the thing. But you actually don't have to. Go to the release notes (link for Windows and link for Mac) and download not the latest version but the one right before. This is a direct download link.

注意:如果您从未使用过Docker,则可以轻松地将其安装在计算机上。 Docker有一种麻烦的趋势,迫使您仅注册一个帐户来下载东西。 但是实际上您不必这样做。 转到发行说明( 适用于Windows的 链接适用于Mac的链接 ),而不是下载最新版本,而是下载之前的版本。 这是直接下载链接。

version: '3.1'

services:
 app-serve:
   build: .
   image: myapp
   command: npm run serve:production
   expose:
    - 4200

 app-e2e-tests:
   image: myapp
   command: dockerize -wait tcp://app-serve:4200 
             -wait tcp://selenium-chrome-standalone:4444 
             -timeout 10s -wait-retry-interval 1s bash -c "npm run e2e"
   depends_on:
     - app-serve
     - selenium-chrome-standalone

 selenium-chrome-standalone:
   image: selenium/standalone-chrome
   expose:
    - 44444

The file above tells Docker to spin up an environment with 3 containers:

上面的文件告诉Docker启动具有3个容器的环境:

  • Our app to test: the container uses the myapp image which we’ll build right below

    我们要测试的应用程序:容器使用了我们将在下面构建的myapp图像
  • A container running the tests: the container uses the same myapp image. It uses dockerize to wait for the servers to be up before running the tests

    一个运行测试的容器:该容器使用相同的myapp映像。 它使用dockerize等待服务器启动,然后再运行测试

  • The Selenium server: the container uses the official Selenium image. Nothing to do here. We could run the tests from the same container as the app. Splitting it makes things clearer. It also allows you to separate outputs from the 2 containers in the result logs.

    Selenium服务器:容器使用官方的Selenium映像。 在这儿无事可做。 我们可以从与应用程序相同的容器中运行测试。 拆分它可以使事情更清晰。 它还允许您从结果日志中的2个容器中分离输出。

The containers will live inside a private virtual network and see each other as http://the-container-name (more here on networking in Docker).

这些容器将位于私有虚拟网络中,并且彼此之间的名称为http:// the-container-name(有关Docker中的网络的更多信息 )。

We need a Dockerfile to build the myapp image used for the containers. It should turn your frontend code into a bundle as close to production as possible. Running unit tests and linting is a good idea at that stage. After all, there's no need to run end to end tests if the basics do not work.

我们需要一个Dockerfile来构建用于容器的myapp映像。 它应该将您的前端代码变成尽可能接近生产的捆绑包。 在那个阶段运行单元测试和整理是个好主意。 毕竟,如果基础知识不起作用,则无需进行端到端测试。

In the Dockerfile below we use a node image as base, install dockerize, and bundle the application. It is important to build for production. You don’t want to test a development build that is pre-optimizations. Many things can go wrong there.

在下面的Dockerfile中,我们使用节点映像作为基础,安装dockerize并捆绑该应用程序。 为生产而建造很重要。 您不想测试预优化的开发版本。 那里很多事情都会出错。

FROM node:12.13.0 AS base

ENV DOCKERIZE_VERSION v0.6.0

RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
   && tar -C /usr/local/bin -xzvf dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
   && rm dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz

RUN mkdir -p ~/app
WORKDIR ~/app

COPY package.json .
COPY package-lock.json .

FROM base AS dependencies

RUN npm install

FROM dependencies AS runtime

COPY . .
RUN npm run lint
RUN npm run test:ci
RUN npm run build --production

Now that we have all the pieces together let's run the tests using this command:

现在,我们已经将所有部分放在一起,让我们使用以下命令运行测试:

docker-compose up --build --abort-on-container-exit

It is long-ish, so script it in your project somehow. It will build the myapp image based on the provided Dockerfile and then start all the containers. Dockerize makes sure your app and Selenium are up before executing the tests.

它太长了,因此请以某种方式在您的项目中编写脚本。 它将基于提供的Dockerfile构建myapp映像,然后启动所有容器。 Dockerize在执行测试之前确保您的应用程序和Selenium已启动。

The --abort-on-container-exit option will kill the environment when one container exists. Since only our testing container is meant to exit (the others are servers), that is what we want.

当一个容器存在时,--abort-on-container-exit选项将终止环境。 由于只有测试容器是要退出的(其他是服务器),所以这就是我们想要的。

The docker-compose command will have the same exit code as the exiting container. It means you can easily detect from the command line if the tests succeeded or not.

docker-compose命令将具有与退出容器相同的退出代码。 这意味着您可以从命令行轻松检测测试是否成功。

You are now ready to run end to end tests locally and on any server supporting Docker. That's pretty good!

现在,您可以在本地以及任何支持Docker的服务器上运行端到端测试。 太好了!

The tests run with only one browser for now, though. Let’s add more.

不过,目前测试仅在一个浏览器上运行。 让我们添加更多。

在不同的浏览器上测试 (Testing on different browsers)

The standalone Selenium image spins up a Selenium server with the browser you want. To run the tests on different browsers you need to update your tests' configuration and use the selenium/hub Docker image.

独立的Selenium映像使用所需的浏览器启动Selenium服务器。 要在不同的浏览器上运行测试,您需要更新测试的配置并使用selenium / hub Docker映像。

The image creates a hub between your application and the standalone Selenium images. Replace the selenium container section in your docker-compose.yml as follows:

该映像在您的应用程序和独立的Selenium映像之间创建了一个中心。 替换docker-compose.yml中的Selenium容器部分,如下所示:

selenium-hub:
    image: selenium/hub
    container_name: selenium-hub
    expose:
      - 4444
  chrome:
    image: selenium/node-chrome
    volumes:
      - /dev/shm:/dev/shm
    depends_on:
      - selenium-hub
    environment:
      - HUB_HOST=selenium-hub
      - HUB_PORT=4444
  firefox:
    image: selenium/node-firefox
    volumes:
      - /dev/shm:/dev/shm
    depends_on:
      - selenium-hub
    environment:
      - HUB_HOST=selenium-hub
      - HUB_PORT=4444

We now have 3 containers: Chrome, Firefox and the Selenium hub.

现在,我们有3个容器:Chrome,Firefox和Selenium集线器。

All the Docker images provided by Selenium are in this repository.

Selenium提供的所有Docker映像都在此存储库中

Careful! There is a tricky timing effect to consider. We use dockerize to have our test container wait for the Selenium hub to be up. That is not enough because we need to wait for the standalone images to be ready – in fact to register themselves to the hub.

小心! 需要考虑一个棘手的时序影响。 我们使用dockerize让我们的测试容器等待Selenium集线器启动。 这还不够,因为我们需要等待独立映像准备就绪-实际上是将其注册到集线器。

We can do this by waiting for the standalone images to expose a port, but that is not a guarantee. It is easier to wait a few seconds before starting the tests. Update your test script to wait 5 seconds before the tests start (you can add a sleep command after the dockerize call).

我们可以通过等待独立映像公开端口来做到这一点,但这不是保证。 在开始测试之前等待几秒钟比较容易。 将测试脚本更新为在测试开始前等待5秒钟(您可以在dockerize调用之后添加sleep命令)。

Now you can be sure that your tests won’t start until all the browsers are ready. Waiting is not ideal but a few seconds are worth it. There is nothing more annoying than failing tests because of unstable automations.

现在,您可以确定直到所有浏览器准备就绪,测试才能开始。 等待不是很理想,但值得等待几秒钟。 由于自动化不稳定,没有比失败的测试更令人讨厌的了。

Good. We have now covered the front end part. Let’s add the back end.

好。 现在我们已经涵盖了前端部分。 让我们添加后端。

将后端添加为容器或git模块 (Add the back end as containers or git modules)

The above might seem overkill to test only the front end part of your app. But we're aiming for much more. We want to test the whole system.

上面的内容似乎仅测试应用程序的前端部分就显得有些过头了。 但是我们的目标是更多。 我们要测试整个系统。

Let’s add a database and a back end to our Docker compose environment.

让我们在Docker撰写环境中添加一个数据库和一个后端。

If you are a front end developer you might think "we are the front end team – we don’t care about testing the back end." Are you sure?

如果您是前端开发人员,您可能会认为“我们是前端团队-我们不在乎测试后端”。 你确定吗?

The front end is always the last part to integrate all the other pieces. That means crunch time. Crunch time that would no longer exist if you were able to test the front end with the back end continuously and catch errors sooner.
前端始终是集成所有其他组件的最后一部分。 那意味着关键时间。 如果您能够连续测试前端和后端并尽早发现错误,那么不再需要紧缩时间。

The technique I describe here is very easy to apply even if your back end is in a different repository.

即使您的后端位于其他存储库中,我在这里描述的技术也很容易应用。

This is what the docker-compose.yml looks like:

这是docker-compose.yml的样子:

version: '3.1'

services:
 db:
   image: postgres
   environment:
     POSTGRES_USER: john
     POSTGRES_PASSWORD: mysecretpassword
   expose:
     - 5432
 backend:
   context: ./backend
   dockerfile: ./backend/Dockerfile
   image:mybackend
   command: dockerize
       -wait tcp://db:5432 -timeout 10s
       bash -c "./seed_db.sh && ./start_server.sh"
   environment:
     APP_DB_HOST: db
     APP_DB_USER: john
     APP_DB_PASSWORD: mysecretpassword
   expose:
     - 8000
   depends_on:
     - db
 app-serve:
   build: .
   image: myapp
   command: npm run serve:sw
   expose:
    - 4200
 app-e2e-tests:
   image: myapp
   command: dockerize -wait tcp://app-serve:4200 
        -wait tcp://backend:8000 
        -wait tcp://selenium-chrome-standalone:4444 -timeout 10s 
        -wait-retry-interval 1s bash -c "npm run e2e:docker"
   depends_on:
     - app-serve
     - selenium-chrome-standalone
 selenium-chrome-standalone:
   image: selenium/standalone-chrome
   expose:
    - 44444

In this example we added a postgres database and a container for the back end to run. Dockerize synchronizes the containers' commands.

在此示例中,我们添加了一个postgres数据库和一个供后端运行的容器。 Dockerize同步容器的命令。

If your system has more than one back end component, add as many containers as you need. You need to wire the container dependencies properly. This means proper hostnames as environment variables on your components. And order of startup if some components depend on others.

如果您的系统具有多个后端组件,请根据需要添加任意数量的容器。 您需要正确连接容器依赖项。 这意味着适当的主机名将作为组件上的环境变量。 和启动顺序(如果某些组件依赖于其他组件)。

The Selenium tests you have written should not need any modifications. You might need to put test data in the database. To keep this step in the testing area we added the seeding script before the backend startup script. This way we are sure that things happen in the proper order:

您编写的Selenium测试不需要任何修改。 您可能需要将测试数据放入数据库中。 为了使此步骤保持在测试区域中,我们在后端启动脚本之前添加了种子脚本。 这样,我们可以确保事情以正确的顺序发生:

  • The DB starts and is ready to accept connections

    数据库启动并准备接受连接
  • A script seeds the DB data

    脚本播种数据库数据
  • The back end and the front end start – so the tests can start

    后端和前端开始–因此测试可以开始

单一储存库 (Monorepository)

If you look at the back end container you can see there is a catch. It uses an image called mybackend built from a file located at backend/Dockerfile. This implies that your back end is in the same git repository in a folder called backend. The name is just an example of course.

如果您查看后端容器,您会发现有一个陷阱。 它使用从位于backend / Dockerfile的文件构建的名为mybackend的映像。 这意味着您的后端位于名为backend的文件夹中的同一git存储库中。 名称只是一个例子。

If your back end and front end are in the same repository you are good. Define the Dockerfile to build your back end and adjust the startup command to what you need.

如果您的后端和前端在同一个存储库中,那么您就很好。 定义Dockerfile来构建您的后端,并根据需要调整启动命令。

That’s all good but usually the back end is not in the same repository. Or you can have many back end components in different repositories. What do you do then?

很好,但是通常后端不在同一个存储库中。 或者,您可以在不同的存储库中有许多后端组件。 那你怎么办呢?

多个存储库 (Multiple repositories)

The super clean solution is to have a CI process on each back end component repository.

超级干净的解决方案是在每个后​​端组件存储库上都有一个CI流程。

If you don’t have any you can check out the API end to end testing with Docker guide to get started. It uses the same techniques as this article so you have a consistent setup across your whole project.

如果没有,您可以使用Docker指南查看API端到端测试以开始使用。 它使用与本文相同的技术,因此您可以在整个项目中进行一致的设置。

The CI process for each component runs automated tests. Upon success it pushes a docker image with the component to a private Docker registry. The back end container in our docker-compose.yml file above would use this image.

每个组件的CI流程运行自动化测试。 成功后,它将带有组件的Docker映像推送到私有Docker注册表。 上面的docker-compose.yml文件中的后端容器将使用此图像。

This solution requires a private Docker registry to store your images. You can use Docker Hub but then it becomes public. If you don't have one already and don’t plan to do so, it is not worth the effort.

此解决方案需要一个专用的Docker注册表来存储您的映像。 您可以使用Docker Hub,但是它将变为公共。 如果您还没有,并且不打算这样做,那是不值得的。

The other solution is to use the submodules feature in git. Your back end repository becomes a virtual child of your front end repository. You just need to add the file .gitmodules like this to your front end repository:

另一种解决方案是在git中使用子模块功能。 您的后端存储库将成为前端存储库的虚拟子代。 您只需要将.gitmodules这样的文件添加到前端存储库中:

[submodule "backend"]
  path = backend
  url = git@your:backend/repository.git
  branch = develop

Run the command git submodule update --remote which will pull the specified branch of the back end repository into a folder called "backend". Add as many submodules as you need if you have more than one back end component.

运行命令git submodule update --remote其中 会将后端存储库的指定分支拉到名为“ backend”的文件夹中。 如果您有多个后端组件,则根据需要添加任意数量的子模块。

That’s it. Have your CI run the submodule command and from a file system perspective it's as if you're in a monorepository.

而已。 让您的CI运行submodule命令,从文件系统的角度来看,就好像您在单一存储库中一样。

If you don’t want the back end code locally while developing the front end just don’t run the command. You’ll have an empty back end folder.

如果在开发前端时不希望本地后端代码,请不要运行该命令。 您将有一个空的后端文件夹。

版本控制和后端/前端不兼容 (Versioning and back end/front end incompatibilities)

The 2 techniques above test the front end with the latest “CI tests passed” version of your back end. That may lead to broken builds if your components are not compatible at times.

上面的两种技术使用后端的最新“ CI测试通过”版本来测试前端。 如果您的组件有时不兼容,则可能会导致构建失败。

If they are compatible more often than not, stick to the “always test with the latest versions” approach. You’ll fix the occasional incompatibilities on the fly.

如果它们经常兼容,则坚持“始终使用最新版本进行测试”的方法。 您将即时解决偶尔出现的不兼容问题。

That won’t work, though, if incompatibilities are business as usual. In this case you need to manually control version updates. That is very easy to do.

但是,如果不兼容是常有的事,那将是行不通的。 在这种情况下,您需要手动控制版本更新。 那很容易做到。

You can lock the version of a component in the docker-compose.yml file or in the .gitmodules file. When pushing to the Docker registry you would tag the component image with the commit number of the corresponding code. The relevant docker-compose.yml file section becomes:

您可以在泊坞窗,compose.yml文件或文件.gitmodules锁定组件的版本。 当推送到Docker注册表时,您将使用相应代码的提交号标记组件映像。 相关的docker-compose.yml文件部分变为:

backend:
  image: backendapp:34028fc

Similarly the .gitmodules file would not target a branch head but a given commit:

类似地, .gitmodules文件将不会以分支头为目标,而是以给定的提交为目标:

[submodule "backend"]
  path = backend
  url = git@your:backend/repository.git
  branch = 34028fc

Bonus: version updates are versioned with your code. You can track which version was used for each build. This is useful when fixing failed builds or trying to reproduce old bugs.

奖励:版本更新与您的代码一起进行版本控制。 您可以跟踪每个版本使用的版本。 当修复失败的版本或尝试重现旧错误时,这很有用。

We could push the approach to the next level. You could have a dedicated repository that would wire all your components as git modules. Bumping the versions could be a form of delivery and handover to the test/QA team.  

我们可以将方法推向新的高度。 您可能有一个专用的存储库,该存储库会将所有组件连接为git模块。 版本冲突可能是一种交付形式,也可能是移交给测试/质量检查团队的一种形式。

In theory it is best to keep the latest versions of components working together more often than not. And drop the need for manual versioning. If that is not the case that is OK. Ignore the purists who will tell you that you are not following best practices and so on.

从理论上讲,最好使组件的最新版本经常协同工作。 并无需手动版本控制。 如果不是这种情况,那就可以了。 忽略纯粹主义者,他们会告诉您您没有遵循最佳实践等。

If you are just starting don't aim for the stars at first. Pick what works best for you to enjoy the benefits of automated testing right now. Then keep improving your process along the way.
如果您只是刚开始,请不要一开始就瞄准星星。 选择最适合您的方法,立即享受自动化测试的好处。 然后继续改进您的过程。

编写可维护的Selenium测试的奖励 (Bonus on writing maintainable Selenium tests)

Back to Selenium and three important bits of advice to help you write good UI tests.

返回Selenium和三个重要的建议,以帮助您编写良好的UI测试。

First, avoid CSS selectors if you can. Selenium works on the DOM and can identify elements by IDs or CSS or XPath. Use IDs as much as possible even if you have to add them to your app code for only this purpose. CSS and XPath selectors are shaky. As soon as your application structure changes, they will be broken.

首先,请尽可能避免使用CSS选择器。 Selenium在DOM上工作,可以通过ID或CSS或XPath标识元素。 即使您仅出于此目的将ID添加到您的应用代码中,也应尽可能使用ID。 CSS和XPath选择器不稳定。 一旦您的应用程序结构发生更改,它们就会被破坏。

Second, use the Page Objects approach. It is about encapsulating your application so selectors are not directly used in tests. If your page HTML/CSS changes, your tests will have to be rewritten to use new selectors. Page Objects abstract selectors and turn them into user actions. Here is a great article on how to use Page Objects properly.

其次,使用页面对象方法。 它与封装应用程序有关,因此选择器不会直接在测试中使用。 如果页面HTML / CSS更改,则必须重写测试以使用新的选择器。 页面对象抽象选择器,并将其转变为用户操作。 这是一篇有关如何正确使用页面对象的精彩文章。

Third, don’t build long user journeys in your tests. If your tests fail at the 50th action it’s going to be difficult to reproduce and fix. Create test suites that play part of the scenarios starting from the login page. This way you are always a few clicks away from the bug your tests will catch.

第三,不要在测试中建立漫长的用户旅程。 如果您的测试在第50个操作中失败,则将很难重现和修复。 从登录页面开始,创建包含部分场景的测试套件。 这样,您总是可以从测试中捕获到的错误中单击几下。

Also don’t risk writing tests that rely on state from previous actions. Test suite coupling is something you want to avoid.

同样不要冒险编写依赖于先前操作状态的测试。 测试套件耦合是您要避免的事情。

Let's take a practical example. Say you are testing a SaaS application for schools. The use cases could be:

让我们举一个实际的例子。 假设您正在为学校测试SaaS应用程序。 用例可以是:

  • Create a class

    建立课程
  • Register kids' and parents' data

    登记孩子和父母的数据
  • Setup the weekly plan for the class

    设置课程的每周计划
  • Check absences

    检查缺席
  • Input grades

    输入等级

Along the way you will have the login process and some navigation checks.

在此过程中,您将具有登录过程和一些导航检查。

You could write a test that goes through the whole chain as described above. And this would be convenient because to declare kids you need a class to exist. To check absences you need a weekly plan in place. And you need kids to input grades. It’s a quick win to build one test suite that does all these things at first.

您可以编写一个遍及整个链的测试,如上所述。 这很方便,因为声明孩子需要一个类。 要检查缺勤情况,您需要制定每周计划。 而且您需要孩子输入成绩。 建立一个首先完成所有这些功能的测试套件是一项捷径。

If you have nothing at the moment and want to achieve good test coverage quickly: go for it! Done is better than perfect if it allows you to catch errors in your application now.

如果您目前一无所获,并且希望快速获得良好的测试覆盖率,那就去吧! 如果它允许您立即捕获应用程序中的错误,则完成比完美还好。

The cleaner solution would be to use a baseline scenario to start smaller test suites. In the example above the baseline scenario should be to create a class and register kids' data.

较干净的解决方案是使用基线方案启动较小的测试套件。 在上面的示例中,基准场景应该是创建一个班级并注册孩子的数据。

Create a test suite that does exactly that: create a class and registered kids' and parents' data. Always run it first. If this stops working then you don’t need to move further on. This version of the code will never reach end users anyway.

创建一个完全符合此要求的测试套件:创建一个班级并注册孩子和父母的数据。 始终先运行它。 如果此操作停止,则您无需继续进行下去。 无论如何,此版本的代码将永远无法到达最终用户。

Then create a function that encapsulates the baseline scenario. It will be duplicate code to some extent with the previous test suite. But it will allow you to have a one line function to use as a setup hook for all the other test suites. This is the best of both worlds: test scenarios starting from a fresh state in the application with minimal effort.

然后创建一个封装基线方案的函数。 在以前的测试套件中,它将在某种程度上是重复的代码。 但这将使您拥有一个功能,可以用作所有其他测试套件的设置挂钩。 这是两全其美的方法:以最小的努力从应用程序的新状态开始测试场景。

结论 (Conclusion)

I hope this article gave you some good insight into how you can quickly set up end to end tests for a complex system. Multiple components in multiple repositories should not be a barrier. Docker compose makes it easy to put things together.

我希望本文能使您对如何快速设置复杂系统的端到端测试有很好的了解。 多个存储库中的多个组件不应成为障碍。 Docker compose使将事情放在一起变得容易。

End to end tests are the best way to avoid crunch time. In complex systems, late delivery of some components puts a burden on other teams. Integrations are done in a rush. Code quality drops. That's a vicious circle. Testing often and catching cross component errors early is the solution.

端到端测试是避免紧缩时间的最佳方法。 在复杂的系统中,某些组件的延迟交付给其他团队带来了负担。 匆忙完成集成。 代码质量下降。 那是一个恶性循环。 解决方案是经常测试并尽早发现跨组件错误。

Selenium tests can be done quick and dirty to get going fast. That is perfectly OK. Automate things. Then improve. Remember:

Selenium测试可以快速而又肮脏地进行以快速进行。 完全可以。 使事情自动化。 然后改善。 记得:

Done is better than perfect any day of the year.
在一年中的任何一天,做的总比做的好。

Thanks for reading!

谢谢阅读!

If you want more of my articles like this, you can find them on The Fire CI Blog.

如果您想要更多此类文章,可以在The Fire CI Blog上找到它们。

翻译自: https://www.freecodecamp.org/news/end-to-end-tests-with-selenium-and-docker-the-ultimate-guide/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值