接口测试之代码项目实战

本文详细介绍了接口测试的代码实现过程,包括代码实现接口测试和工具实现接口测试的区别,以及一个实际的代码项目实战。实战中涉及登陆模块和员工模块的接口测试,包括登陆接口的封装、自动化测试用例编写、测试套件批量运行、参数化测试以及日志初始化等。项目使用了Python的requests、unittest和parameterized库。
摘要由CSDN通过智能技术生成

代码项目实战

面试题:代码实现接口测试和工具实现接口测试的区别?

优点:

工具:工具使用简单,学习成本低;

代码:灵活,逼格比较高(注意:也可以面试管说逼格比较高。还有面试时,可以夸讲面试官,说他问题问得好)

缺点:

工具:不灵活,

代码:学习成本比较高

什么时候选择工具,什么时候选择代码?

如果项目中,定制化需求比较少,测试人员编码水平不高时,可以选择工具,例如:postman、jmeter等

如果项目中,定制化需求比较多,测试人员编码水平都还可以时,可以选择代码,例如:python+requests+unittest

接口自动化框架代码实现顺序

  • 实现顺序:从下往上,从里往外
  • 设计顺序:从外到内,从上往下
  • 核心功能模块:api,script,data
  • 设计顺序:script -> api -> data
  • 实现顺序:data -> api -> script

1,初始化项目

创建项目目录结构

在这里插入图片描述

安装依赖包

  • requests
  • pymysql
  • parameterzied
  • HTMLTestRunner

requests,pymysql,parameterized在File->Setting->Project Intepreter->点击+号 进行安装

在这里插入图片描述

2,初始化日志

  • 1 编写日志的代码:写在app.py中

    • 日志的等级:5个等级(了解)

      低于日志等级的日志都不会打印

      • DEBUG
      • INFO
      • WARN
      • ERROR
      • CRITICAL
#app.py 初始化日志的函数代码
# 获取当前项目路径
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# 初始化日志函数
def init_logging():
    # 创建日志器
    logger = logging.getLogger()
    # 设置日志等级
    logger.setLevel(logging.INFO)
    # 设置处理器
    # 设置控制台处理器
    sh = logging.StreamHandler()
    # 设置文件处理器
    # TimedRotatingFileHandler 可以用来帮助我们切分日志:按照时间来设置日志
    filename = BASE_DIR + "/log/ihrm.log"
    fh = logging.handlers.TimedRotatingFileHandler(filename, when='M', interval=1, backupCount=7)
    # 设置格式化器
    fmt = '%(asctime)s %(levelname)s [%(name)s] [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s'
    formatter = logging.Formatter(fmt)
    # 将格式化器添加到处理器当中
    sh.setFormatter(formatter)
    fh.setFormatter(formatter)
    # 将处理器添加到日志器
    logger.addHandler(fh)
    logger.addHandler(sh)
  • 2 初始化日志
#api.__init__.py
import app
import logging

# 初始化日志
# 为什么要在api.__init__.py中初始化日志呢?
# 这是因为,我们后面进行接口测试时,都会调用封装的API接口,调用时,会自动运行__init__.py函数,初始化日志器,从而实现,自动初始化日志的功能
app.init_logging()

logging.info("TEST日志器能不能正常工作")

3,登陆模块接口测试

1 封装IHRM登陆接口

  • app.py中设置全局属性

在这里插入图片描述

#app.py部分代码
HOST = "http://182.92.81.159"
HEADERS = {
   "Content-Type":"application/json"}

2 实现IHRM登陆接口测试用例

  • 在script中新增test_login.py文件,用于实现登陆接口测试用例

    • 先实现第一个测试用例:登陆成功
    #scritp.test_login.py
    import unittest,logging
    from api.login_api import LoginApi
    
    class TestIHRMLogin(unittest.TestCase):
        def setUp(self) -> None:
            pass
    
        @classmethod
        def setUpClass(cls) -> None:
            # 初始化登陆类
            cls.login_api = LoginApi()
    
        def tearDown(self) -> None:
            pass
    
        @classmethod
        def tearDownClass(cls) -> None:
            pass
    
    
        def test01_login_success(self):
            # 调用封装的登陆接口
            response = self.login_api.login('13800000002','123456')
            # 接收返回的json数据
            jsonData = response.json()
            # 调试输出登陆接口返回的数据,日志输出只能用作为{}占位符
            logging.info("登陆成功接口返回的数据为: {}".format(jsonData))
    
            # 断言
            self.assertEqual(200, response.status_code) # 断言响应状态码
            self.assertEqual(True, jsonData.get("success")) # 断言success
            self.assertEqual(10000, jsonData.get("code")) # 断言code
            self.assertIn("操作成功", jsonData.get("message")) # 断言message
    
    
    

    3 优化断言

    分析登陆成功的代码,发现登陆成功中,断言有4行

    # 断言
    self.assertEqual(200, response.status_code) # 断言响应状态码
    self.assertEqual(True, jsonData.get("success")) # 断言success
    self.assertEqual(10000, jsonData.get("code")) # 断言code
    self.assertIn("操作成功", jsonData.get("message")) # 断言message
    

    这4行中可以考虑利用封装技术优化成一行

    封装:减少代码冗余,

    思路:1.我们的断言代码中,self,response,都是高度重复的代码,可以优化。

    2.剩余4个预期结果,都是会动态变化的,所以也可以优化

    优化方式:把self,response,4个断言数据作为参数传递给通用断言类处理。

    实现代码:通用断言工具类写在utils.py中

    # utils.py
    # 编写断言代码函数
    # 可能的问题:self,response为什么可以作为参数传递?
    # 答:这是因为self,response都是对象
    def assert_common(self, response, http_code, success, code, message):
        self.assertEqual(http_code, response.status_code)  # 断言响应状态码
        self.assertEqual(success, response.json().get("success"))  # 断言success
        self.assertEqual(code, response.json().get("code"))  # 断言code
        self.assertIn(message, response.json().get("message"))  # 断言message
    

    优化后再改写登陆成功案例,至此断言优化完毕

    # script.test_login.py
    import unittest,logging
    from api.login_api import LoginApi
    from utils import assert_common
    
    class TestIHRMLogin(unittest.TestCase):
        def setUp(self) -> None:
            pass
    
        @classmethod
        def setUpClass(cls) -> None:
            # 初始化登陆类
            cls.login_api = LoginApi()
    
        def tearDown(self) -> None:
            pass
    
        @classmethod
        def tearDownClass(cls) -> None:
            pass
    
    
        def test01_login_success(self):
            # 调用封装的登陆接口
            response = self.login_api.login('13800000002','123456')
            # 接收返回的json数据
            jsonData = response.json()
            # 调试输出登陆接口返回的数据,日志输出只能用作为{}占位符
            logging.info("登陆成功接口返回的数据为: {}".format(jsonData))
    
            # 断言
            # self.assertEqual(200, response.status_code) # 断言响应状态码
            # self.assertEqual(True, jsonData.get("success")) # 断言success
            # self.assertEqual(10000, jsonData.get("code")) # 断言code
            # self.assertIn("操作成功", jsonData.get("message")) # 断言message
    
            assert_common(self,
                          response,
                          200, True, 10000, "操作成功")
    

    4 实现剩余登陆测试用例代码

    import unittest,logging
    from api.login_api import LoginApi
    from utils import assert_common
    
    class TestIHRMLogin(unittest.TestCase):
        def setUp(self) -> None:
            pass
    
        @classmethod
        def setUpClass(cls) -> None:
            # 初始化登陆类
            cls.login_api = LoginApi()
    
        def tearDown(self) -> None:
            pass
    
        @classmethod
        def tearDownClass(cls) -> None:
            pass
    
    
        def test01_login_success(self):
            # 调用封装的登陆接口
            response = self.login_api.login('13800000002','123456')
            # 接收返回的json数据
            jsonData = response.json()
            # 调试输出登陆接口返回的数据,日志输出只能用作为{}占位符
            logging.info("登陆成功接口返回的数据为: {}".format(jsonData))
    
            # 断言
            # self.assertEqual(200, response.status_code) # 断言响应状态码
            # self.assertEqual(True, jsonData.get("success")) # 断言success
            # self.assertEqual(10000, jsonData.get("code")) # 断言code
            # self.assertIn("操作成功", jsonData.get("message")) # 断言message
    
            assert_common(self,
                          response,
                          200, True, 10000, "操作成功")
    
        def test02_username_is_not_exist(self):
            # 调用封装的登陆接口
            response = self.login_api.login('13900000002','123456')
            # 接收返回的json数据
            jsonData = response.json()
            # 输出
            logging.info("账号不存在时输出的数据为: {}".format(jsonData))
            # 断言
            assert_common(self, response, 200, False, 20001, "用户名或密码错误")
    
        def test03_password_is_error(self):
            # 调用封装的登陆接口
            response = self.login_api.login('13800000002','error')
            # 接收返回的json数据
            jsonData = response.json()
            # 输出
            logging.info("密码错误时输出的数据为: {}".format(jsonData))
            # 断言
            assert_common(self, response, 200, False, 20001, "用户名或密码错误")
    
        def test04_username_have_special_char(self):
            # 调用封装的登陆接口
            response = self.login_api.login('!@#$%^&*()_-+=','error')
            # 接收返回的json数据
            jsonData = response.json()
            # 输出
            logging.info("账号输入特殊字符时输出的数据为: {}".format(jsonData))
            # 断言
            assert_common(self, response, 200, False, 20001, "用户名或密码错误")
    
        def test05_username_is_empty(self):
            # 调用封装的登陆接口
            response = self.login_api.login('','error')
            # 接收返回的json数据
            jsonData = response.json()
            # 输出
            logging.info("账号为空输出的数据为: {}".format(jsonData))
            # 断言
            assert_common(self, response, 200, False, 20001, "用户名或密码错误"</
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值