持续集成 docker 和自动化脚本 --python 栈

王守义十三香 · 2020年11月19日 · 最后由 T 回复于 2020年12月10日 · 4180 次阅读

一年经验的小白,第一次在社区发帖,写的太 low 大家见谅哈

引子

来了家新公司,持续集成用的是 gitlab 的 CI/CD,我不会这玩意儿,上家公司用的是 jenkins😭 ,所以这块之后弄明白了再写吧。
测试脚本是这周二写完的,写完 push 到 gitlab,leader 说要用 docker 部署,所以让我写个 Dockerfile,问题来了。

Dockerfile

首先给大家看看我最外层的执行脚本 run.py,html 报告是发邮件用的,平常主要还是看 allure。

import os
import time
import pytest
from common.action import del_file
from common.send_email import SendEmail

if __name__ == '__main__':
    # 清除allure目录下所有文件
    del_file('result/report/allure')

    # allure测试报告路径
    allure_path = 'result/report/allure'

    # html报告路径
    now = time.strftime("%Y-%m-%d %H:%M:%S")
    html_path = 'result/report/html/{}.html'.format(now)

    # 执行测试并生成allure报告 & html测试报告
    pytest.main(['-s', '--alluredir', allure_path, 'testcase', '--html={}'.format(html_path), '--self-contained-html'])

    # 运行allure服务
    os.system('allure serve -p 80 result/report/allure')

    # html报告邮件发送
    html_dir = SendEmail().acquire_report_address('result/report/html')
    SendEmail().send_email(html_dir)

常规来说,我的 Dockerfile 应该是这样的:

FROM python:3.8
ADD . usr/testframwork  # testframwork是我的项目名称
RUN pip install -r requirements.txt
WORKDIR usr/testframwork
ENTRYPOINT python3 run.py

问题来了,基础镜像用的 python3.8,那我的 allure 怎么办,allure 还依赖 java 呢,所以为了我的 allure 报告,我需要定制一个基础镜像。

制作包含 python3,java,allure 的基础镜像

制作

首先 pull 一个 centos7 吧,因为之前买过一个云服务器,也是 centos7,用的比较顺手

docker pull centos7 
docker run -d --name centos-allure -i -t centos /bin/bash  # 运行centos镜像
docker exex -it centos-allure /bin/bash  # 进入

现在进入到镜像内部了,下一步是给这个容器配置 python、java、allure 环境
先 yum install wget,python 和 java 就直接源码安装,也没什么坑,记得把脚本需要的第三方库给 pip install 上去,不然 docker build 会慢得抠脚,还时常失败。
接下来我们来搞 allure

cd /home
wget https://repo.maven.apache.org/maven2/io/qameta/allure/allure-commandline/2.8.0/allure-commandline-2.8.0.tgz 
tar -zxvf  allure-commandline-2.8.0.tgz 
vi /etc/profile
    export PATH=$PATH:/home/allure-2.7.0/bin
source /etc/profile

到这里有的同学们以为 allure 就搞定了,其实并没有,这里有个大坑。source /etc/profile 之后执行 allure --version,没有丝毫毛病。
等我退出容器重新进入,发现 allure --version 输出了个寂寞,须得重新 source /etc/profile 才行。

怎么解决呢,百度了一下 Linux 环境变量相关的,在~/.bashrc 文件 (也可能是~/.bash_profile,我忘了) 下加上 source /etc/profile,
这样用户每次进入的时候就会执行一下这个命令,这样就 ok,可以往下进行了。有些同学以为这样 allure 就搞定了。。。其实并没有
之后 exit 退出容器,执行打包命令:

# bigllxx是我docker hub的用户名,/ 后面接镜像名称,: 后面要接个版本号
docker commit <containerID> bigllxx/centos-allure:1.0.0

然后镜像打包成功,执行 docker images ,看到这个镜像正乖乖躺在我的仓库里

Dockerfile 文件再编写

基础镜像做好了,那就重写一下 Dockerfile 吧,基础镜像换成我们自己做的 centos-allure:1.0.0,这里开了个 80 的端口号,因为我的 allure 服务指定的是 80 端口

FROM bigllxx/centos-allure:1.0.0
ADD . usr/testframwork
WORKDIR usr/testframwork
EXPOSE 80
ENTRYPOINT python3 run.py

搞定,接下来就要把我的测试脚本打包成一个镜像了,给大家看看我的目录结构:

就在 Dockerfile 的同级目录下,也就是项目目录下执行命令

 #  docker build -t <imageName> 要放到镜像的目录/文件
docker build -t testframwork .

打包完成,docker images ,看到 testframwork 镜像乖乖躺在我的仓库里
重头戏来了,要启动镜像了,成败在次一举
docker run -p 127.0.0.1:2015:80 --name testframwork testframwork
。。。
败了,提示 allure not found
** 了个 Dj 的
。。。

再次制作

我思考了一下,报这个错肯定是环境变量的问题,环境变量好像是用户进入系统之后才生效,但是在 docker run 的时候,容器内部环境变量是不是不生效的?
那为什么 python 可以?因为 python 配了软链,对,那我给 allure 也配个软链试试

# 再次进入容器
docker exex -it <containerID> /bin/bash
# 给allure配置软链
ln -s ln -s  /home/allure-2.8.0/bin/allure /usr/bin/allure
# 退出容器
exit
# 打包镜像
docker commit <containerID> bigllxx/centos-allure:1.1.0

这样我们 1.1.0 版本的 centos-allure 就做好了,更改一下 Dockerfile,让其 FROM bigllxx/centos-allure:1.1.0

FROM bigllxx/centos-allure:1.1.0
ADD . usr/testframwork
WORKDIR usr/testframwork
EXPOSE 80
ENTRYPOINT python3 run.py

我们重新 build 再运行一遍看看

# 先把上面的垃圾容器和镜像都删掉
docker rm -f testframwork
docker rmi -f  testframwork
# 再重新构建运行
docker build -t testframwork .
docker run -p 127.0.0.1:2015:80 --name testfw testframwork

这次 allure 又出幺蛾子了,没有报 not found,但是报了一个没找到 JAVA_HOME。
想起来了,java 的环境变量也是配在/etc/profile 里面的,那我给 java 也弄个软链试试
。。。弄了一会,发现 java 本来就有软链,浪费时间了。

仔细看了下报错,发现 allure 找的是 JAVA_HOME,但是 JAVA_HOME 是个目录啊,总不能给目录弄个软链。

Dockerfile 再编写

突然想起来 Dockerfile 里面有个 ENV,好像是弄环境变量的。我去弄弄试试:

FROM bigllxx/centos-allure:1.1.0
ADD . usr/testframwork
WORKDIR usr/testframwork
# java环境变量
ENV JAVA_HOME /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.272.b10-1.el7_9.x86_64
ENV JRE_HOME ${JAVA_HOME}/jre
ENV CLASSPATH .:${JAVA_HOME}/lib:${JRE_HOME}/lib
ENV PATH ${JAVA_HOME}/bin:$PATH
EXPOSE 80
ENTRYPOINT python3 run.py

然后重新 build,运行

# 先把上面的垃圾容器和镜像都删掉
docker rm -f testframwork
docker rmi -f  testframwork
# 再重新构建运行
docker build -t testframwork .
docker run -p 127.0.0.1:2015:80 --name testfw testframwork

成功搞定,访问 127.0.0.1:2015,看到 allure 了,成功搞定。
这样就实现了 不需要任何外部依赖的 docker 接口自动化项目构建,服务器只要有个 docker 环境就能跑,就有 allure 报告可以看

还没有结束

当我把代码 push 到 gitlab 给开发同学看了之后,开发同学告诉我:建议你这个镜像 run 完就销毁掉,
因为你把它留着,占将近 1 个 G 的内存,就为了看个测试报告,不值当,可以把测试报告的那个文件夹想办法弄到宿主机,
然后在宿主机上弄个 allure,run 完你的脚本之后,把容器销毁掉,然后直接在宿主机起 allure 服务。
我一听有道理,想起来 docker 有个挂载,我在 run 的时候把宿主机的一个目录挂载到容器放 allure 报告的目录不就好了,
能不能行呢,我又去百度了一下,容器挂载宿主机的目录,容器里的这个目录变了,宿主机的变不变?
然后百度了个寂寞,我自己都被这个问题丑到了。

服务器安装 allure,挂载容器报告目录

还是实践出真知,直接开干。
先在我们测试服务器 新建个文件夹,用来下载 allure 和挂载容器的报告目录

mkdir /home/bigllxx/allure
cd /home/bigllxx/allure
wget https://repo.maven.apache.org/maven2/io/qameta/allure/allure-commandline/2.8.0/allure-commandline-2.8.0.tgz 
tar -zxvf  allure-commandline-2.8.0.tgz 
ln -s  /home/bigllxx/allure/allure-2.8.0/bin/allure /usr/bin/allure
# 新建存放用来挂载allure报告的目录
mkdir allure-report

接下来又要重写 Dockerfile 了,在宿主机启动 allure,就不需要 java 环境和端口号了

FROM bigllxx/centos-allure:1.1.0
ADD . usr/testframwork
WORKDIR usr/testframwork
ENTRYPOINT python3 run.py

然后改一下 run.py,把运行 allure 服务的 os.system(xxx) 给注释掉
之后重新构建运行,注意需要挂载

docker build -t testframwork .
docker run -v /home/bigllxx/allure/allure-report:/usr/testframwork/result/report/allure --name testframwork testframwork

发现 allure-report 目录下成功生成了很多文件

我们 allure 一下
allure serve -p 7788 /home/bigllxx/allure/allure_report
allure 服务成功被起起来,帅气

还没有结束

这篇文章也敲了一会了,慢慢想起来:allure 放在服务器了,那代表 java 环境也不需要了,那我要自己做这个基础镜像干什么呢?

回到原点

FROM python:3.8
ADD . usr/testframwork  # testframwork是我的项目名称
RUN pip install -r requirements.txt
WORKDIR usr/testframwork
ENTRYPOINT python3 run.py

盖了帽了

共收到 4 条回复 时间 点赞

看了这么久,回到原点😂

是你被耍了 还是我们被耍了😂

感觉思想挺不错的....

5楼 已删除
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册