| 应用打包还是测试团队老大难问题?

| 应用打包还是测试团队老大难问题?_第1张图片
如果接口测试仅仅只是掌握一些requests或者其他一些功能强大的库的用法,是远远不够的,还需要具有根据公司的业务以及需求去定制化一个接口自动化测试框架能力。所以在这个部分,会主要介绍接口测试用例分析以及通用的流程封装是如何完成的。

Docker是一个开源的应用容器引擎,基于 Go 语言开发,Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的系统。
Docker 是世界领先的软件容器平台,Docker 官方的口号是”调试你的应用,而不是调试环境“。在进行多人协作开发时,开发者可以使用 Docker 来消除所谓“我这里运行是好的”(works on my machine)问题,运维人员使用 Docker 来并行的运行和管理应用来获得更优计算密度,基于各自独立的容器,不会因为环境原因导致应用运行错误。
如下图所示:在工作当中,如果我们面对这样多的服务、多个服务器,以及多种环境,我们应该如何处理呢?如果还继续用传统的方式打包部署,我们会浪费多少时间?

所以在 Docker 横空出世之前,应用打包一直是大部分研发团队的痛点,在 Docker 出现后,它以更高效的利用系统资源、更快速的启动时间、一致的运行环境、持续交付和部署、更轻松的迁移、更轻松的维护和拓展,6大优点迅速火了起来。
Docker 的三个概念:

  • 镜像(Image):是一个包含有文件系统的面向Docker引擎的只读模板。任何应用程序运行都需要环境,而镜像就是用来提供这种运行环境的。例如一个 Ubuntu 镜像就是一个包含 Ubuntu 操作系统环境的模板。
    • 容器(Container):类似于一个轻量级的沙盒,可以将其看作一个极简的 Linux 系统环境(包括 root 权限、进程空间、用户空间和网络空间等),以及运行在其中的应用程序。Docker 引擎利用容器来运行、隔离各个应用。容器是镜像创建的应用实例,可以创建、启动、停止、删除容器,各个容器之间是是相互隔离的,互不影响。注意:镜像本身是只读的,容器从镜像启动时,Docker 在镜像的上层创建一个可写层,镜像本身不变。
    • 仓库(Repository):镜像仓库,是 Docker 用来集中存放镜像文件的地方。

Docker 是开源的商业产品,有两种版本:社区版(Community Edition,缩写为 CE)和企业版(Enterprise Edition,缩写为 EE)。企业版包含了一些收费服务,一般用不到。我们下面将会演示 Docker CE版本的使用方法。
Docker 支持很多操作系统平台,有大家常用的 Microsoft Windows 系列操作系统(Docker 不支持 Windows 10 家庭版系统),Linux 发行版和 macOS 系统。

Windows 上有两种安装 Docker 方式:

• 第一种:访问 Docker 网站下载 Docker Desktop软件的 exe 文件,下载地址:
https://download.docker.com/win/stable/Docker%20Desktop%20Installer.exe
• 第二种:使用 Chocolatey 包管理工具安装 Docker。(包管理工具需自行下载安装)
choco install docker-for-windows

  1. 切换到管理员权限
  2. su root

4. 安装必要的一些系统工具
5. ```
6. apt-get update
apt-get -y install apt-transport-https ca-certificates curl

software-properties-common

3.安装 GPG 证书

curl -fsSL 
http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg 
| sudo apt-key add -

4.写入软件源信息

add-apt-repository "deb [arch=amd64] 
http://mirrors.aliyun.com/docker-ce/linux/ubuntu 
$(lsb_release -cs) stable"

5.更新并安装 Docker-CE

apt-get -y update

apt-get -y install docker-ce

1.切换到管理员权限

su root

2.安装必要的一些系统工具

yum install -y yum-utils device-mapper-persistent-data lvm2

3.添加软件源信息

yum-config-manager --add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

4.更新并安装 Docker-CE

yum makecache fast

yum -y install docker-ce

• 第一种:访问 Docker 网站下载 Docker Desktop 的 dmg 安装包,下载地址:https://download.docker.com/mac/stable/Docker.dmg
• 第二种:使用包管理工具方式来安装 Docker,使用Homebrew工具安装 Docker。(包管理工具需自行下载安装)

brew cask install docker

  1. 启动 Docker
  2. systemctl start docker

4. 重新启动 Docker
5. ```
6. systemctl restart docker
  1. 开机时自动启动 Docker
  2. systemctl enable docker

10. 查看 Docker 运行状态
11.```
systemctl status docker

⬇️ 点击“阅读原文”,提升测试核心竞争力!
原文链接

获取更多相关资料+v~ ceshiren001
获取更多技术文章分享
更多干货可关注公众号一键获取哦~

首先在做用例分析之前,可以通过追查公司一年来所有的故障原因,定位问题起因,或者通过与CTO、产品经理、研发、运维、测试调查,得到质量痛点,还可以分析业务架构、流程调用,以及监控系统了解到业务的使用数据,从而得到质量需求。

得到质量需求之后,通过与产品经理、项目经理、研发总监等对接后得知待测业务范围、业务场景用例、业务接口分析,从而确定公司的测试计划。将测试计划与质量需求结合进行分析,就可以开始进行业务用例的设计,而接口测试用例分析,也在其内。

| 应用打包还是测试团队老大难问题?_第2张图片

接口封装思想主要分为3个大维度,配置、接口封装、业务流程。其中配置主要用作根据配置文件获取初始配置和依赖;接口封装遵循apiobject设计模式,对接口的调用进行抽象封装;业务流程则负责数据初始化、业务用例设计,包含有多个api形成的流程定义,不要再包含任何接口实现细节、以及断言。后面将会与实战案例结合,进行详细的介绍。

由于信息安全的原因,许多的接口在传输的时候会对请求与响应进行加密处理,如果直接对这部分数据做断言显然是行不通的。还需要对这部分接口额外进行解密的处理之后,才可以对已解密的接口进行断言。

在进行实战之前,需要先准备一个对响应加密的接口。对它发起一个get请求后,得到一个加密过后的响应信息。

先准备一个json格式demo

{"topics":
{
"orange":"movie",
"shool":"testing-studio",
"president":"seveniruby"
}
}

使用base64对其做加密,得到一个加密后的文件demo64.txt

base64 demo.json >demo64.txt

使用python命令在“demo64.txt”所在目录启动一个服务

python -m http.server 10000

启动后的样子如图:

使用curl命令对这个服务进行get请求

curl http://127.0.0.1:10000/demo64.txt

如果请求成功的话就代表环境已经准备成功

调用base64,直接对返回的请求做解密,即可得到解密后的响应,将解密后的响应转为json格式,此时就可以对这个返回值做断言且不会报错了

import base64
import json
import requests
class TestEncode:
    url = "http://127.0.0.1:10000/demo64.txt"
        def test_encode(self):
                r = requests.get(self.url)
                        encode = json.loads(base64.b64decode(r.content))
                                assert encode["topics"]["president"] == "seveniruby"

这样的写法显然不够优雅,如果被测接口的协议发生变化,requests库无法支持改变后的协议,需要调用别的第三库发送请求信息,则还是需要修改底层的源码。碰到这种情况,可以增加一层封装,构造一层更加通用的发送方法。

首先需要通过一个字典的结构体,保存所有的请求信息,包括发送的协议、解码方式、请求method等等,而这种字典形式的结构体也为后面的数据驱动改造做好了一个重要的铺垫。

 req_data={
             "schema": "http",
                         "method": "get",
                                     "url": "http://127.0.0.1:10000/demo64.txt",
                                                 "headers": None
                                                         }

通过请求信息的结构体中的schema,添加判断条件,去选择不同的请求协议。举个例子,如果schema为“http”的话,就选择调用被封装的requests库。

class ApiRequest:
    #构造send方法,通过
        def send(self, data: dict):
                if "http" == data["schema"] :
                            res = requests.request(
                                            data["method"],data["url"],header=data["headers"])
                                                        return json.loads(base64.decode(res.content))
                                                                elif "dubbo" ==  data["schema"]:
                                                                            pass
                                                                                    elif "websocket" == data["schema"]:
                                                                                                pass
                                                                                                        else:
                                                                                                                    pass    

调用在ApiRequest类中的send方法发送请求并进行断言

class TestEncode:
   def test_api(self):
           req_data={
                       "schema": "http",
                                   "encoding": "base64",
                                               "method": "get",
                                                           "url": "http://127.0.0.1:10000/demo64.txt",
                                                                       "headers": None
                                                                               }
                                                                                       re = ApiRequest()
                                                                                               data = re.send(req_data)
                                                                                                       assert data["topics"]["president"] == "seveniruby"

如果面对不同的算法,还需要修改底层的源码,所以需要把算法封装。需要使用哪个算法,就使用哪个。封装的思想与上面相同。首先在字典结构体中添加一个encoding字段,用来判断选择的不同的加密条件

 req_data={
             "schema": "http",
                         "method": "get",
                                     "url": "http://127.0.0.1:10000/demo64.txt",
                                                 "headers": None,
                                                             "encoding": "base64"
                                                                     }

还是通过请求信息的结构体中的encoding,添加判断条件,去选择不同的解密方式。

class ApiRequest:
    def send(self, data: dict):
            if "http" == data["schema"] :
                        res = requests.request(
                                        data["method"],data["url"],headers=data["headers"])
                                                    return json.loads(base64.b64decode(res.content))
                                                                #通过请求信息的结构体中的`encoding`,去选择不同的解密方式。
                                                                            if data["encoding"] == "base64":
                                                                                            return json.loads(base64.b64decode(res.content))
                                                                                                        elif data["encoding"] == "private":
                                                                                                                        return json.loads(
                                                                                                                                            requests.post("url", data=res.content).content)
                                                                                                                                                        else:
                                                                                                                                                                        return json.loads(res.content)

首先需要明确在面对一个加密的响应结果,可以使用什么样的处理方式:

  1. 如果知道使用的是哪个通用加密算法的话,可以自行解决。
    1. 如果不了解对应的加密算法的话,可以让研发提供加解密的lib。
    1. 如果既不是通用加密算法、研发也无法提供加解密的lib的话,可以让加密方提供远程解析服务,这样算法仍然是保密的。
      本篇文章主要提供的就是在了解使用加密算法的情况下,如何处理这样的解密算法。但是封装的思路都是相通的,不管是面对哪种情况,都可以通过格式化的数据,指明数据的内容,并通过一层逻辑的封装,将加解密或者选择的协议封装进去。

⬇️ 点击“阅读原文”,提升测试核心竞争力!
原文链接

获取更多相关资料+v~ ceshiren001
获取更多技术文章分享

你可能感兴趣的:(压力测试)