fix: 1、支持标签反向同步;

Description:

Log:
This commit is contained in:
mikigo 2023-09-27 17:46:59 +08:00
parent af57ebb8fe
commit a7f70d65ed
9 changed files with 180 additions and 13 deletions

View File

@ -4,6 +4,8 @@
new
- 支持标签反向同步:将 `csv` 中的标签同步到 `pms`
- 解除子项目的工程名称以 `autotest_` 开头的限制,子项目工程名称可以为任意名称;
配置文件 `globalconfig.ini` 中的 `APP_NAME` 和命令行参数 `-a/--app` 仅支持传入工程名称的全称:
@ -18,7 +20,7 @@ new
youqu manage.py run -a apps/autotest_deepin_music
```
`apps` 开头可以获得命令行补全,使用更加便捷。
输入以 `apps` 开头可以获得命令行补全,使用更加便捷。
- 新增导入全局配置对象:
@ -38,6 +40,10 @@ new
- 增加了在线文档的显示宽度;
fix
- 修复从 `pms` 标签【设备类型】为 `null` 时,同步到 `csv` 文件写入为 `null`
## 2.2.32023/9/15
new

View File

@ -4,7 +4,7 @@
支持自动同步脚本 `ID`(用例 `py` 文件的 `ID`)到 `CSV` 文件;
【使用方法一】
**【使用方法一】**
配置文件方式,通过一下几个配置来控制:
@ -18,9 +18,13 @@ PY_ID_TO_CSV = yes
如果不存在 `CSV` 文件会直接创建一个并写入用例脚本的 `ID`
此功能默认会将 `CSV` 文件中多余的ID行删掉以处理人工删除了用例脚本文件`CSV` 文件里面对应的 `ID` 行未删除的问题;
此功能默认会将 `CSV` 文件中多余的 `ID` 行删掉,以处理人工删除了用例脚本文件,但 `CSV` 文件里面对应的 `ID` 行未删除的问题;
【使用方法二】
```sh
youqu manage.py csvctl
```
**【使用方法二】**
命令行参数的方式:
@ -32,11 +36,11 @@ youqu manage.py csvctl -p2c
每次操作会将 `CSV` 文件先备份到 `report/pyid2csv_back` 目录下;
### 2. 从PMS自动同步标签信息
### 2. 从PMS自动同步标签到CSV
用于自动同步 `PMS` 用例标签数据至本地 `CSV` 文件;
【使用方法一】
**【使用方法一】**
配置文件方式,通过以下几个配置来控制:
@ -44,6 +48,7 @@ youqu manage.py csvctl -p2c
APP_NAME = # 这个参数可填可不填,但是填了可以提高用例的执行速度,因为在用例收集阶段可以指定到具体的应用库。(下同)
PMS_USER = # PMS的用户名
PMS_PASSWORD = # PMS的密码
CSV_NAME_TO_PMS =
```
`[pmsctl-pms_link_csv]` 节点下指定 `CSV` 文件名与 `PMS` 用例模块的对应关系,比如:
@ -69,7 +74,7 @@ youqu manage.py pmsctl -p2c
每次执行时原 `CSV` 文件会自动备份在 `report` 目录下,因此你不用担心脚本执行导致你的数据丢失。
【使用方法二】
**【使用方法二】**
按照我们一贯的风格,你也可以不去管配置文件,完全通过命令行参数传入:
@ -79,6 +84,40 @@ youqu manage.py pmsctl -p2c -u ut00xxxx -p you_password -plc music:81
每次操作会将 `CSV` 文件先备份到 `report/pms2csv_back` 目录下;
### 3. 从CSV文件同步标签到PMS
用于将 `CSV` 文件中的标签同步到 `PMS` 用例库用例中;
**【使用方法一】**
配置文件方式,通过一下几个配置来控制:
```ini
APP_NAME =
# PMS的用户名
PMS_USER =
# PMS的密码
PMS_PASSWORD =
;需要同步到pms的csv文件名称,不加.csv后缀
;如果要做反向同步此参数必传;
;如果不传此参数可以扫描所有的csv文件但是此操作太危险暂时不考虑
CSV_NAME_TO_PMS =
```
配置好后,在命令行执行:
```shell
youqu manage.py pmsctl -c2p
```
**【使用方法二】**
完全通过命令行参数传入:
```shell
youqu manage.py pmsctl -c2p -a apps/autotest_com_deepin_lianliankan/ -c lianliankan -u my_user -p my_pwd
```
## 导出CSV文件
框架提供导出指定标签用例的功能:

View File

@ -24,6 +24,7 @@ from setting.globalconfig import GlobalConfig
from src.startapp import StartApp
from src import logger
from src.pms.pms2csv import Pms2Csv
from src.pms.csv2pms import Csv2Pms
from src.rtk._base import SubCmd
from src.rtk._base import Args
from src.rtk.local_runner import LocalRunner
@ -81,6 +82,8 @@ class Manage:
pyid2csv=None,
export_csv_file=None,
pms2csv=None,
csv2pms=None,
csv_name=None,
pms_link_csv=None,
send2task=None,
):
@ -124,6 +127,8 @@ class Manage:
self.default_pyid2csv = pyid2csv
self.default_export_csv_file = export_csv_file
self.default_pms2csv = pms2csv
self.default_csv2pms = csv2pms
self.default_csv_name = csv_name
self.default_pms_link_csv = pms_link_csv
self.default_send2task = send2task
@ -374,9 +379,8 @@ class Manage:
"""pms相关功能命令行参数"""
sub_parser_pms.add_argument(
"-a", "--app", default="",
help="应用名称:deepin-music 或 autotest_deepin_music 或 apps/autotest_deepin_music"
help="应用名称:apps/autotest_deepin_music 或 autotest_deepin_music"
)
sub_parser_pms.add_argument(
"-u", "--pms_user", default="", help="pms 用户名"
)
@ -391,6 +395,14 @@ class Manage:
"-p2c", "--pms2csv", action='store_const', const=True, default=False,
help="从PMS爬取用例标签到csv文件"
)
sub_parser_pms.add_argument(
"-c2p", "--csv2pms", action='store_const', const=True, default=False,
help="将csv文件里面的标签同步到PMS"
)
sub_parser_pms.add_argument(
"-c", "--csv_name", default="",
help="将csv文件里面的标签同步到PMS时csv文件的名称"
)
sub_parser_pms.add_argument(
"--send2task",
choices=["yes", ""],
@ -409,6 +421,8 @@ class Manage:
Args.pms_user.value: args.pms_user or self.default_pms_user,
Args.pms_password.value: args.pms_password or self.default_pms_password,
Args.pms2csv.value: args.pms2csv or self.default_pms2csv,
Args.csv2pms.value: args.csv2pms or self.default_csv2pms,
Args.csv_name.value: args.csv_name or self.default_csv_name,
Args.pms_link_csv.value: args.pms_link_csv or self.default_pms_link_csv,
Args.send2task.value: args.send2task or self.default_send2task,
Args.task_id.value: args.task_id or GlobalConfig.TASK_ID,
@ -421,6 +435,13 @@ class Manage:
password=pms_kwargs.get(Args.pms_password.value) or GlobalConfig.PMS_PASSWORD,
pms_link_csv=pms_kwargs.get(Args.pms_link_csv.value),
).write_new_csv()
elif pms_kwargs.get(Args.csv2pms.value):
Csv2Pms(
app_name=pms_kwargs.get(Args.app_name.value),
user=pms_kwargs.get(Args.pms_user.value) or GlobalConfig.PMS_USER,
password=pms_kwargs.get(Args.pms_password.value) or GlobalConfig.PMS_PASSWORD,
csv_name=pms_kwargs.get(Args.csv_name.value),
).post_to_pms()
elif (
pms_kwargs.get(Args.send2task.value)
and pms_kwargs.get(Args.task_id.value)
@ -430,6 +451,8 @@ class Manage:
Send2Pms.case_res_path(pms_kwargs.get(Args.task_id.value)),
Send2Pms.data_send_result_csv(pms_kwargs.get(Args.trigger.value))
)
else:
raise ValueError
@staticmethod
def start_app(startapp=None):
@ -443,7 +466,7 @@ class Manage:
"""csv相关功能命令参数"""
sub_parser_csv.add_argument(
"-a", "--app", default="",
help="应用名称:deepin-music 或 autotest_deepin_music 或 apps/autotest_deepin_music"
help="应用名称:apps/autotest_deepin_music 或 autotest_deepin_music"
)
sub_parser_csv.add_argument(
"-k", "--keywords", default="", help="用例的关键词"

View File

@ -203,6 +203,11 @@ EXPORT_CSV_FILE =
;导出 case_list.csv 文件时配置的字段名,用例名称默认存在第一列,无需添加
EXPORT_CSV_HEARD = 用例级别,用例类型,测试级别,是否跳过
;需要同步到pms的csv文件名称,不加.csv后缀
;如果要做反向同步此参数必传;
;如果不传此参数可以扫描所有的csv文件但是此操作太危险暂时不考虑
CSV_NAME_TO_PMS =
[log_cli]
;日志相关配置(不打印构造函数和魔法函数的功能说明)

View File

@ -136,6 +136,7 @@ class _GlobalConfig:
PY_ID_TO_CSV = csv_cfg.get_bool("PY_ID_TO_CSV", default=False)
EXPORT_CSV_FILE = csv_cfg.get("EXPORT_CSV_FILE", default="")
EXPORT_CSV_HEARD = csv_cfg.get("EXPORT_CSV_HEARD", default="用例级别,用例类型,测试级别,是否跳过").replace(" ", "")
CSV_NAME_TO_PMS = csv_cfg.get("CSV_NAME_TO_PMS", default="")
# [log_cli]
log_cli = GetCfg(GLOBAL_CONFIG_FILE_PATH, "log_cli")

View File

@ -221,7 +221,7 @@ class CmdCtl:
)
@classmethod
def kill_process(cls, process, grep_list: str = None):
def kill_process(cls, process, grep_list: [list, tuple] = None):
"""
杀进程
:param process: 进程名

91
src/pms/csv2pms.py Normal file
View File

@ -0,0 +1,91 @@
#!/usr/bin/env python3
# _*_ coding:utf-8 _*_
# SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
# SPDX-License-Identifier: GPL-2.0-only
import os
from urllib.parse import urlencode
from setting import conf
from setting.globalconfig import FixedCsvTitle
from src.pms._base import _Base
from src.rtk._base import transform_app_name
class Csv2Pms(_Base):
__author__ = "mikigo<huangmingqiang@uniontech.com>"
config_error_log = "请检查您传递的 '命令行参数' 或 setting/globalconfig.ini 里的配置项"
def __init__(
self,
app_name: str = None,
user: str = None,
password: str = None,
csv_name=None
):
super().__init__(user=user, password=password)
self.username = user
self.password = user
self.base_url = "https://pms.uniontech.com"
self.walk_dir = (
f"{conf.APPS_PATH}/{transform_app_name(app_name)}"
if app_name
else conf.APPS_PATH
)
self.csv_name = csv_name or conf.CSV_NAME_TO_PMS
if not self.csv_name:
raise EnvironmentError(self.config_error_log)
def get_csv_info(self):
csv_path = None
for root, _, files in os.walk(self.walk_dir):
for file in files:
if f"{self.csv_name}.csv" == file:
csv_path = f"{root}/{file}"
if csv_path is None:
raise FileNotFoundError(self.config_error_log)
with open(csv_path, "r", encoding="utf-8") as f:
txt_list = f.readlines()
csv_heads = txt_list[0].strip().split(",")
csv_head_index_map = {}
for index, title in enumerate(csv_heads):
for i in FixedCsvTitle:
if i.value == title.strip():
csv_head_index_map[i.name] = {
"head_name": i.value,
"head_index": index,
}
taglines = [txt.strip().split(",") for txt in txt_list[1:]]
return csv_head_index_map, taglines
def post_to_pms(self):
csv_head_index_map, taglines = self.get_csv_info()
def csv_map(x):
return csv_head_index_map.get(x).get('head_index')
for i in taglines:
case_id = i[csv_map(FixedCsvTitle.case_id.name)]
edit_url = f"{self.base_url}/testcase-edit-{case_id}.html"
data = {
'isAutomation': '',
}
if i[csv_map(FixedCsvTitle.device_type.name)] in ("PPL", "COL"):
data["deviceType"] = i[csv_map(FixedCsvTitle.device_type.name)]
if i[csv_map(FixedCsvTitle.case_from.name)] == "":
data["caseSource"] = ""
if i[csv_map(FixedCsvTitle.online_obj.name)] == "CICD":
data["lineCD"] = ""
bytes_data = urlencode(data).encode("utf-8")
res = self.rx.session.open(
fullurl=edit_url,
data=bytes_data,
timeout=10
)
print(f"{case_id}-{data}{res.status}")

View File

@ -23,7 +23,7 @@ from src.rtk._base import transform_app_name
class Pms2Csv(_Base):
"""获取pms数据同步到本地csv文件"""
__author__ = "huangmingqiang@uniontech.com"
__author__ = "mikigo<huangmingqiang@uniontech.com>"
config_error_log = "请检查您传递的 '命令行参数' 或 setting/globalconfig.ini 里的配置项"
@ -96,7 +96,7 @@ class Pms2Csv(_Base):
"case_type": case_type,
"case_from": "BUG" if case_from == "" else "",
"device_type": device_type.split("(")[0]
if device_type or device_type != "null"
if device_type and device_type != "null"
else "",
"online_obj": "CICD" if online_obj == "" else "",
}

View File

@ -67,8 +67,10 @@ class Args(Enum):
pyid2csv = "pyid2csv"
export_csv_file = "export_csv_file"
pms2csv = "pms2csv"
csv2pms = "csv2pms"
pms_link_csv = "pms_link_csv"
send2task = "send2task"
csv_name = "csv_name"
def transform_app_name(app_name):