PPT
实战内容
- 熟悉业务:litemall后台管理系统
- 接口自动化
- 持续集成:Jenkins
接口列表
https://litemall.hogwarts.ceshiren.com/swagger-ui.html
获取 token
获取X-Litemall-Admin-Token是调用Litemall商城后台管理API接口的第一步,相当于创建了一个登录凭证,其它的业务API接口,都需要依赖于X-Litemall-Admin-Token来鉴权调用者身份。
请求方式: POST(HTTP )
请求地址: https://litemall.hogwarts.ceshiren.com/admin/auth/login
参数说明:
参数 | 是否必填 | 说明 |
---|---|---|
username | 是 | 用户名,默认管理员admin123 |
password | 是 | 密码,默认密码admin123 |
返回结果:
{
"errno":0,
"data":{
"adminInfo":{
"nickName":"admin123",
"avatar":"https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif"
},
"token":"830cd329-befb-4ec5-9960-626197abaa9a"
},
"errmsg":"成功"
}
备注:X-Litemall-Admin-Token 使用方法:在每个业务接口的headers中添加token键值对,键为“X-Litemall-Admin-Token”,值为具体的token值。
上架商品
管理员可以通过此接口实现商品上架功能。
请求方式:POST(HTTP)
**请求地址:**https://litemall.hogwarts.ceshiren.com/admin/goods/create
请求示例:
{
"goods":{
"picUrl":"",
"gallery":[
],
"isHot":true,
"isNew":true,
"isOnSale":true,
"goodsSn":"12491264512421",
"name":"Hogwarts",
"counterPrice":"8888"
},
"specifications":[
{
"specification":"规格",
"value":"标准",
"picUrl":""
}
],
"products":[
{
"id":0,
"specifications":[
"标准"
],
"price":0,
"number":0,
"url":""
}
],
"attributes":[
{
"attribute":"材质",
"value":"纯棉"
}
]
}
参数说明 :
参数 | 字段类型 | 是否必填 | 说明 |
---|---|---|---|
goods | 对象 | 是 | 商品信息对象 |
specifications | 数组 | 是 | 商品规格对象 |
products | 数组 | 是 | 商品价格信息对象 |
attributes | 数组 | 是 | 商品参数对象 |
返回结果:
{"errno":0,"errmsg":"成功"}
详细字段说明:
- goods对象请求示例
{
"picUrl":"",
"gallery":[
],
"isHot":true,
"isNew":true,
"isOnSale":true,
"goodsSn":"12491264512421",
"name":"Hogwarts",
"counterPrice":"8888"
}
- goods对象参数说明 :
参数 | 字段类型 | 是否必填 | 说明 |
---|---|---|---|
picUrl | 字符串 | 否 | 商品图片 |
gallery | 数组 | 否 | 宣传画廊图片 |
isHot | 布尔值 | 否 | 是否热卖 |
isNew | 布尔值 | 否 | 是否新品 |
isOnSale | 布尔值 | 否 | 是否在售 |
goodsSn | 字符串 | 是 | 商品编号 |
name | 字符串 | 是 | 商品名称 |
counterPrice | 字符串 | 否 | 市场售价 |
- specifications对象示例
{
"specification":"规格",
"value":"标准",
"picUrl":""
}
- specifications对象字段说明
参数 | 字段类型 | 是否必填 | 说明 |
---|---|---|---|
specification | 字符串 | 是 | 固定值为“规格” |
value | 字符串 | 是 | 固定值为“标准” |
picUrl | 字符串 | 否 | 图片地址 |
- products对象示例
{
"id":0,
"specifications":[
"标准"
],
"price":0,
"number":0,
"url":""
}
- products对象字段说明
- products对象字段说明
参数 | 字段类型 | 是否必填 | 说明 |
---|---|---|---|
id | 数字 | 否 | 字段编号 |
specifications | 数组 | 是 | 固定元素是"标准" |
price | 数字 | 是 | 货品售价 |
number | 数字 | 是 | 货品数量 |
url | 字符串 | 否 | 货品图片地址 |
- attributes对象示例
{
"attribute":"材质",
"value":"纯棉"
}
- attributes对象字段说明
参数 | 字段类型 | 是否必填 | 说明 |
---|---|---|---|
attribute | 字符串 | 否 | 商品参数名称 |
value | 字符串 | 否 | 商品参数值 |
商品列表
请求方式:GET (HTTP)
参数说明 :
参数 | 字段类型 | 是否必填 | 说明 |
---|---|---|---|
goodsSn | 字符串 | 否 | 商品编号 |
name | 字符串 | 否 | 商品名称 |
goodsId | 字符串 | 否 | 商品ID |
返回结果:
{
"errno":0,
"data":{
"total":1,
"pages":1,
"limit":20,
"page":1,
"list":[
{
"id":1181318,
"goodsSn":"12491264512421",
"name":"Hogwarts",
"categoryId":0,
"brandId":0,
"gallery":[
],
"keywords":"",
"brief":"",
"isOnSale":true,
"sortOrder":100,
"picUrl":"",
"isNew":true,
"isHot":true,
"unit":"’件‘",
"counterPrice":8888,
"retailPrice":0,
"addTime":"2022-03-12 10:11:41",
"updateTime":"2022-03-12 10:11:41",
"deleted":false
}
]
},
"errmsg":"成功"
}
删除商品
请求方式:POST(HTTP)
**请求地址:**https://litemall.hogwarts.ceshiren.com/admin/goods/delete
请求示例:
{
"id":1181318,
"goodsSn":"12491264512421",
"name":"Hogwarts"
}
参数说明 :
参数 | 字段类型 | 是否必填 | 说明 |
---|---|---|---|
id | 数字 | 是 | 商品id |
goodsSn | 字符串 | 否 | 商品编号 |
name | 字符串 | 否 | 商品名称 |
返回结果:
{"errno":0,"errmsg":"成功"}
日志 logger.py
import logging
def info(msg):
"""
日志方法
:param msg: 要打印到日志中的信息
:return: info 级别的日志
"""
# 指定 log 日志的存放位置(需要先创建目录,否则会报错)
# 指定日志的编码格式
file_handler = logging.FileHandler(filename="../logs/apitest.log", encoding="utf-8")
# 设置日志的等级
logging.getLogger().setLevel(logging.INFO)
# 设置日志的内容格式
formatter = logging.Formatter('%(asctime)s %(name)s %(levelname)s %(module)s:%(lineno)d %(message)s')
file_handler.setFormatter(formatter)
steam_handler = logging.StreamHandler()
# 日志格式与句柄的绑定
steam_handler.setFormatter(formatter)
# 设置生效
logging.getLogger().addHandler(file_handler)
logging.getLogger().addHandler(steam_handler)
return logging.info(msg)
内容
持续集成
- 代码一定要能在本地调试通
- 要能保证持续集成的代码代码在云服务或其他服务器是执行通过的(不要受环境影响)
# 生成环境管理文件,读取当前环境所有依赖,加载到requirements文件中
pip freeze > requirements.txt
# 安装环境配置文件中的所有环境
pip install -r requirements.txt
- 问题: 如果直接安装对应环境,会导致,如果持续集成的服务器有多套环境,那么可能就会有依赖冲突的问题。
- 解决方案: 使用venv 环境去做环境隔离。
# 生成venv环境
python3 -m venv venv
# 激活venv环境,让当前项目使用该项目的venv环境
source venv/bin/activate
# jenkins build shell
# 生成venv环境
python3 -m venv venv
# 激活venv环境
source venv/bin/activate
pip install --upgrade pip
# 安装相关的环境依赖
pip --default-timeout=100 install selenium==3.141.0 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
pip --default-timeout=100 install pytest -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
pip --default-timeout=100 install faker -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
# 通常代表用例的执行命令
python -m pytest litemall/cases/test_product_launch.py
# jenkins build shell
# 生成venv环境
python3 -m venv venv
# 激活venv环境
source venv/bin/activate
pip install --upgrade pip
# 安装相关的环境依赖
pip --default-timeout=100 install allure-pytest -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
pip --default-timeout=100 install pytest -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
pip --default-timeout=100 install requests -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
pip --default-timeout=100 install jsonpath -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
# 通常代表用例的执行命令
python -m pytest litemall/cases/test_product_launch.py
- allure配置
课后练习
- 完成更新商品的用例逻辑