Docker+Jenkins自动化测试实践

前期介绍:

  1. 基于Python+unittest的接口自动化测试框架,打算使用Docker容器技术+jenkins持续集成的能力实现接口自动化测试的持续集成
  2. 前提:了解jenkins的使用

Docker简介

概念

  • 虚拟化:一种资源管理技术(虚拟机、内存管理、硬盘分区管理)
  • Docker是什么:
    • 虚拟化技术的一种,虚拟容器技术,模拟一个极小的linux系统(dockerfile)
    • 沙箱机制:基于一个exe文件创建的应用,都是相互独立的(隔离),比如一个iso,可以在vmware中创建多个虚拟机,这些虚拟机是相互独立的
    • 镜像:类似创建centos的.iso镜像文件
    • 容器:基于docker镜像创建出来的系统(相当于.iso镜像创建的linux系统)
      • windows>>>虚拟技术(VMware软件)>>>.iso镜像文件>>>得到一个centos系统
      • linux>>>虚拟技术(docker软件)>>>镜像文件(体积小)>>>得到一个centos系统

docker解决什么问题:
一个场景:假如写了一个网站,想要让其他人也能访问,那么需要配置相同的软件(数据库、web服务器、插件、库等),但是这个过程由于各种原因比如软件版本、操作系统版本等有很大概率会运行失败

docker安装

参考文档

  • 我们可以设置yum源为阿里云(速度更快)yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  • 我们可以安装docker社区版(docker-ce社区版免费)yum -y install docker-ce docker-ce-cli containerd.io
  • 安装后查看docker版本docker -v
  • 设置ustc镜像站点(指定注册中心地址)
vim /etc/docker/daemon.json
{
"registry-mirrors":["https://docker.mirrors.ustc.edu.cn"]
}

docker优点

  1. 快速的构建环境
  2. 资源占用很少
  3. 运维更简单了
  4. 一台机子可以创建N个容器,合理利用资源节约资源

docker应用场景

  1. 部署测试环境,生成环境,验收环境
  2. 微服务结构
  3. 自动化项目的部署

Docker常用命令

docker启停命令

  1. 启动docker服务:systemctl start docker
  2. 停止docker服务:systemctl stop docker
  3. 重启:systemctl restart docker
  4. 查看docker状态:systemctl status docker
  5. 查看docker版本:docker -v
  6. 开机自动启动:systemctl enable docker

docker镜像命令

jenkins镜像命令
docker pull qinhaili/new_enkins:haili
python镜像命令
docker pull qinhaili/python3:haili
  1. 查看镜像:docker images
  2. 拉取镜像:docker pull 镜像名称:标签
    在这里找镜像(docker hub):https://hub.docker.com
    如果拉取镜像的时候不加标签,默认拉取最新的镜像,标签为latest
  3. 搜索镜像:docker search 镜像名称
    不能直接找到对应的详细版本信息,只能去网站上去找
  4. 删除镜像
  5. docker rmi 镜像名称:标签
  6. docker rmi -f  镜像名称:标签
  7. docker rmi 镜像id
  8. 修改镜像名称docker tag 老镜像名称::标签 新镜像名称:标签,案例:docker tag python:3.10.7-alpine python3.10.7:haili

docker中的容器命令

  1. 创建容器:
    1. 交互式创建容器:docker run -it python3.10.7:haili
      1. -i:表示以交互式的方式运行容器
      2. -t:分配一个命令行的client终端
      3. 创建容器后,会自动执行cmd里面的命令,查看cmd命令在这里:docker image inspect 镜像名:标签
    2. 守护式创建容器:docker run -di --name test 镜像名:标签 /bin/bash
      1. --name:为将要创建的容器起一个名称
      2. /bin/sh:在容器内运行的命令,指示容器使用Bash shell,当容器启动的时候,就会打开一个Bourne shell以供用户交互(这里边的命令会覆盖上述提到的cmd命令,如果这里没有指定,仍会默认执行cmd中的命令)

Bourne shell 是 Unix 系统中的一种标准的命令行解释器,它通常是 Bash shell 的一个轻量级替代品,具有较少的功能和更少的依赖

  1. 查看运行中的容器:docker ps,查看所有运行中的容器:docker ps -a

    image

  2. 删除容器:docker rm 容器名称/id

  3. 进入容器:docker exec -it docker_name /bin/shimage

    1. docker exec -it -u 0 docker_name /bin/sh
    2. docker exec -it --user root docker_name /bin/sh
  4. 退出容器:exit;
    image

  5. 容器启动与停止:

    1. 启动:docker start 容器名称(或者容器id)
    2. 停止:docker stop 容器名称(或者容器id)
    3. 重启:docker restart 容器名称(或者容器id)
    4. 杀掉:docker kill 容器名称(或者容器id)
  6. 文件拷贝(宿主机文件和容器文件相互隔离)

    1. 语法:docker cp 宿主机需要拷贝的容器或者目录 容器名称:容器目录
    2. 案例:docker cp test.py test_docker:/mnt/
  7. 目录映射(宿主机文件和容器文件相互同步)

    1. docker run -id -v /mnt/:/mnt/ --name=python52 python3.10.7:haili /bin/sh

Dockerfile

基于某个基础的镜像(从docker hub上拉取下来)来打自己的镜像(结合自己项目情况,安装了自己项目所需要的软件等的镜像)

Dockerfile语法

Dockerfile中不要写注释!!!,以下仅为说明演示使用

# 使用基础镜像(FROM 镜像名称:标签)
FROM ubuntu:latest

# 设置工作目录(指定workspace,也就是进入容器后要进入哪个目录中)
WORKDIR /app

# 复制当前目录下的所有文件到容器的 /app 目录中(我们可以将所需要的依赖使用pip freeze命令导出到req.txt文件中,然后放到/app目录中)
COPY . /app
# 也可以使用
ADD ./req.txt /app
# 二者的区别是ADD会自动解压,COPY仅仅是复制

# 安装相关依赖
RUN apt-get update && apt-get install -y python3 python3-pip && pip3 install -r req.txt

# 启动应用程序
CMD ["python3", "main.py"]

注:
RUN命令是在容器创建的时候执行的命令
CMD命令是在容器启动的时候执行的命令,但是如果启动容器的时候传了命令进入启动命令,那么这里的命令就不会执行了,启动容器的时候执行的代码当然是我们的脚本执行代码
image

参考资料:Dockerfile 指令详解 - 测试派

Dockerfile指令解释

打镜像的命令

创建 Docker 镜像的命令是 docker build。下面是使用 docker build 命令打包镜像的基本语法:

docker build [OPTIONS] PATH | URL | -

其中:

  • OPTIONS:可以使用一系列选项来配置镜像构建的行为,例如指定镜像名称、标签、使用的 Dockerfile 路径等。
  • PATH | URL | -:指定 Dockerfile 所在的路径,可以是本地目录的路径、远程 URL 或者 -(表示标准输入)。

以下是一些常用的选项:

  • -t, --tag:为生成的镜像设置名称和标签。
  • --file:指定要使用的 Dockerfile 路径,默认为当前目录下的 Dockerfile
  • -f, --force-rm:在构建过程中删除任何临时容器。
  • --no-cache:在构建过程中不使用缓存。
  • -q, --quiet:减少输出信息,只显示构建进度条。

例如,要在当前目录下的 Dockerfile 中构建一个名为 myimage,标签为 latest 的镜像,可以使用以下命令:

docker build -t myimage:latest .

这将会在当前目录下的 Dockerfile 中构建镜像,并为其设置名称为 myimage,标签为 latest
需要注意的是,在执行 docker build 命令时,需要确保当前目录下存在 Dockerfile 文件,而且名称中的字母必须为小写字母,否则会报错

Docker+jenkins实现接口自动化思路

安装python环境

  1. 准备一个python容器
  2. 自己手动打一个镜像(有项目执行依赖包的镜像)
    1. 编写Dockerfile用来打镜像,参考如下:
FROM python:3-alpine  # 第一行非注释行必须是FROM  
WORKDIR /app         #设置容器的工作空间目录
ADD ./xxx.txt /app   #讲宿主机的依赖包文件添加到镜像里面
RUN pip install -r xxx.txt  #安装依赖包,RUN是在打镜像的过程中执行的命令,建议少用RUN
CMD ["python","main.py"]   #创建容器后自动执行的命令,但是如果启动容器的时候传了命令进去,这个命令会被覆盖
  1. 根据自己创建的镜像,创建一个python容器执行项目(指定容器运行的时候执行的命令):
docker build -t 镜像名称:标签 Dockerfile所在的目录
.:表是当前目录
案例: docker build -t ApiTestFrame20240416 .

Jenkins拉取代码并执行

第一步:创建一个Jenkins容器:

docker run -id --name=apijenkins -p 8809:8080 -u=root -v /usr/bin/docker:/usr/bin/docker -v /var/run/docker.sock:/var/run/docker.sock jenkins/jenkins:latest-jdk17

将宿主机的docker(docker客户端) 和docker.sock(docker客户端与服务器通讯的文件)映射到jenkins容器,执行docker命令的时候想就相当于在宿主机执行docker命令
命令解析:
这条命令作用是用 Docker 启动一个名为 "apijenkins" 的容器,并在其中运行 Jenkins 服务。

  • docker run: 这是 Docker 命令,用于创建并运行一个新的容器。
  • -id: 这是两个选项的结合。-i 选项告诉 Docker 在后台运行容器(detached mode),而 -d 选项告诉 Docker 使用交互模式,即使没有连接到它。这两个选项的结合通常用于需要后台运行的交互式容器。
  • --name=apijenkins: 这个选项用于为容器指定一个名称,即将创建的容器的名称为 "apijenkins"。
  • -p 8809:8080: 这个选项指定了端口映射,将主机上的 8809 端口映射到容器内的 8080 端口。这样,在主机上通过访问 8809 端口就可以访问到 Jenkins 服务。
  • -u=root: 这个选项指定了容器内执行命令时使用的用户身份,这里指定为 root 用户。
  • -v /usr/bin/docker:/usr/bin/docker: 这个选项用于将主机上的 /usr/bin/docker 目录挂载到容器内的 /usr/bin/docker 目录,这样容器内的应用程序就可以访问主机上的 Docker 可执行文件。
  • -v /var/run/docker.sock:/var/run/docker.sock: 这个选项用于将主机上的 Docker 守护进程的 Unix 套接字(socket)挂载到容器内的相同路径,这样容器内的应用程序就可以通过 Docker API 与主机上的 Docker 守护进程进行通信。
  • jenkins/jenkins:latest-jdk17: 这是要使用的 Docker 镜像的名称和标签。这里是从名为 "jenkins/jenkins" 的镜像中拉取标签为 "latest-jdk17" 的版本。

综上所述,该命令将创建一个名为 "apijenkins" 的容器,使用 "jenkins/jenkins:latest-jdk17" 镜像,并在容器内运行 Jenkins 服务。该容器将主机上的 8809 端口映射到容器内的 8080 端口,允许通过浏览器访问 Jenkins 服务。同时,该容器内的应用程序可以通过挂载主机上的 Docker 可执行文件和 Docker 守护进程的 Unix 套接字来与 Docker 进行交互。

第二步:jenkins构建后执行命令创建python容器

上一步创建号jenkins容器并且启动后,就可以在浏览器中访问jenkins页面,新建一个item,设置好代码仓库等必要配置后,进入item,找到item名称/Configure/Build Steps,在Execute shell中添加如下代码:
image

start.sh这个文件需要在项目中创建一个start.sh文件,文件中添加以下命令用于参照指定的python镜像来创建python容器并且运行测试代码:

docker run --rm -w=$WORKSPACE --volumes-from=apijenkins apitestframe20240416

命令解析:

  • docker run: 用于创建并运行一个新的容器。
  • --rm: 这个选项指定了容器退出时自动删除容器。这意味着当容器退出后,Docker 将自动删除该容器的文件系统。这对于临时性的任务非常有用,可以避免容器堆积在系统中。
  • -w=$WORKSPACE: 这个选项指定了容器的工作目录。$WORKSPACE 是一个环境变量,其值将被替换为当前宿主机的工作目录。这样,在容器内执行的命令将在指定的工作目录中执行。
  • --volumes-from=apijenkins: 这个选项指定了容器使用来自另一个名为 "apijenkins" 的容器挂载的卷。这意味着容器将共享 "apijenkins" 容器中挂载的卷,使得容器间可以共享数据。 (apijenkins是上述自己打的python镜像)
  • apitestframe20240416: 这是要运行的容器镜像的名称或 ID。Docker 将使用这个镜像来创建并运行一个新的容器。

总体而言,这行命令将创建并运行一个基于镜像 "apitestframe20240416" 的新容器。该容器将在当前宿主机的工作目录中运行,并共享名为 "apijenkins" 容器中挂载的卷。容器运行完毕后将会自动删除。

第三步:构建

做好上边工作之后,就可以去build我们的item了,构建完成后会自动生成HTML报告,但是在实际使用过程中发现生成的html报告没有样式,后来查阅后可以通过插件的方式来解决:

  1. 安装两个插件:startup trigger和groovy
  2. 在item配置选项中,设置两个地方:
    1. 勾选Build Triggers中的Build when job nodes start
    2. Build Steps中添加Execute system Groovy script,然后添加以下代码就可以了:System.setProperty("hudson.model.DirectoryBrowserSupport.CSP","")

如果插件安装不下来(网络原因、版本兼容问题等等),也可以用下面这种方式,只不过这种方式需要每次都先执行一遍:找到manage jenkins/tools and actions/script consol中执行上述代码

总结

image

面试问题

如何实现持续集成?

面试过程中首要回答是逻辑清晰的思路,如果面试官追求细节问题再去回答,不要事无巨细就去把所有知道的细节都输出

通过Jenkins+Docker方式实现:

  1. 将自动化测试框架代码传到git仓库
  2. 创建jenkins容器
  3. 通过jenkins拉取测试代码
  4. 创建python容器,将jenkins拉取到的代码映射到python容器中执行
  5. 执行完成之后,自动删除python容器,在jenkins和邮件中查看测试报告

拓展(待补充)

Docker是一个C/S架构的应用
客户端位置:/usr/bin/
docker通讯文件:docker.sock,位置:/var/run
查看日志:docker logs 容器名称
Docker+jenkinsPipeline 运行 python 自动化 - 测试派

posted @ 2024-05-08 17:33  爱老的虎油  阅读(33)  评论(0编辑  收藏  举报