一、背景:

工作中测试发现,有些素材进入编辑页面,没有进行修改操作,直接点提交保存后,素材有些字段也会被修改掉。

二、需求:

在前端操作发现的字段问题,暴露出可能其他素材的其他字段都存在这样的问题,所以需要对所有模块的素材进行测试,不修改直接点击提交保存后,前后的数据是否保持一致。

但是,一个素材在mysql数据库表里面多达86多个字段,加上成品类、全屋定制、硬装定制的各种模型、贴图、线条、门窗构件,字段和各种素材组合起来,对比的数据量是巨大的,靠肉眼看估计要测几天,眼睛还能好好的吗,而且很大可能会出现看错,看漏的情况,所以,啥也不说了,默默打开Pycharm,干起来吧。

三、相关模块:

成品类:

1.模型:模型、组合 

2.贴图 

3.替换材质    

4.门窗:模型

5.自由建模:构件

全屋定制:

6.橱柜:模型、贴图、线条

硬装定制:

7.铺砖:瓷砖、线条、铺贴方案、水刀

8.顶墙:模型、贴图、收边条

9.水电:模型、贴图、方案库

10.涂料:贴图

四、方案构思

确定素材有bug的字段

1.取成品类模型素材做单元测试

2.将测试环境代码回滚到有bug的版本

3.在数据库里面将成品素材的相关字段改成默认值(默认值可以任何值,为了方便,default = 1)

4.在工厂后台前端,进入该素材的编辑页面,不做任何修改,直接点击提交保存

5.在数据库里面看该素材,哪些字段值是和默认值不一样的,该字段就是存在bug,找出该字段

验证素材有bug的字段是否被修复

1.测试环境更新修复bug的代码

2.重复上面3、4

5.在数据库里面看该素材,如果所有字段值和默认值全都相等,可以判断bug已经修复(特别关注找出存在bug的字段)

五、代码实现

工作量最大的是 四的第3、5步,涉及对数据库操作和结果的判断。

代码文件夹mysql 包含 4个 文件,分别说明下其作用:

1、db_field.txt 文件

因为每个模型所对应的素材的字段是不一样的,所以需要知道不同模块的素材的字段值,才能批量修改素材的字段值为默认值,故查询素材在SQL里面的字段和字段值存为一个字典,然后写入db_field.txt 文件保存。

2、db_modify.text 、db_submit.txt 文件分别是保存设置默认值的SQL查询的数据和编辑无修改保存后SQL查询的数据

结果的判断就是这2个文件数据的对比

比对mysql两个表的数据 mysql对比数据差异_python

3.代码文件DbCrud.py 是对数据库增删改查

# !/usr/bin/python
# -*- coding:utf-8 -*-
# Time    : 2020-03-05 23:11
# author  : Zhoujunjun
# File    : Dbcurd

import sys
import os
from decimal import *
from DbCrud import *
workpath = os.path.abspath(os.path.dirname(os.getcwd()))
sys.path.append(workpath)
from dbconfig import *

# 调用dbconfig模块的函数打开数据库连接
db, cursor = connet_db()

keep_value = ['materialid',
              'materialname',
              'productid',
              'categoryid',
              ]

def read_db_field():
    with open('db_field.txt', 'r') as f:
        db_list = f.readlines()
        materialtest = eval(db_list[1])
    return materialtest

def update_db(updata, materialid):
    # 读取素材字段
    materialtest = read_db_field()
    for key in materialtest:
        # keep_value的字段值不做修改
        if key not in keep_value:
            sql = "update designmaterial set %s = %s  where materialid in %s" % (
                key, updata, materialid,)
            # print(sql)
            cursor.execute(sql)
            db.commit()

def selcect_db():
    global ret1, ret2
    cursor.execute(
        "select * from designmaterial where materialid = '100002998'")
    ret1 = cursor.fetchall()
    cursor.execute("desc designmaterial")
    ret2 = cursor.fetchall()
    print(ret1)

if __name__ == '__main__':
    materialid = ('100002998', '100002990')
    updata = 9
    update_db(updata, materialid)
    selcect_db()
    db.close()

4.代码文件JudgeData.py 是进行数据结果的判断

# !/usr/bin/python
# -*- coding:utf-8 -*-
# Time    : 2020-03-15 09:59
# author  : Zhoujunjun
# File    : JudgeDbdata

import sys
import os
dirpath = os.getcwd()
workpath = os.path.abspath(os.path.dirname(os.getcwd()))
sys.path.append(dirpath)
sys.path.append(workpath)
from DbCrud import *
from dbconfig import *



class JudgeDbdata(object):
    def __init__(self):
        pass

    def connet_db(self):
        global db , cursor
        db, cursor = connet_db()

    def get_index_dict(self):
        """
        获取数据库对应表中的字段名
        """
        index_dict = dict()
        index = 0
        for desc in cursor.description:
            index_dict[desc[0]] = index
            index = index + 1
        return index_dict

    def get_dict_data_sql(self, sql):
        """
        运行sql语句,获取结果,并根据表中字段名,转化成dict格式(默认是tuple格式)
        """
        cursor.execute(sql)
        data = cursor.fetchall()
        index_dict = self.get_index_dict()
        res = []
        for datai in data:
            resi = dict()
            for indexi in index_dict:
                resi[indexi] = datai[index_dict[indexi]]
            res.append(resi)
        return res

    def write_db(self, file, materialid, sql):
        sql = sql
        ret = self.get_dict_data_sql(sql)
        fo = open(file, 'w')
        for i in ret:
            fo.write('\n' + str(i) + '\n')
        fo.close()

    def judge_dict(self):
        """
        dict1 = {'a':1,'b':2,'c':3,'d':4}
        dict2 = {'a':1,'b':2,'c':5,'e':6}

        differ = set(dict1.items()) ^ set(dict2.items())
        print(differ)
        #所有差异
        #输出:{('c', 3), ('e', 6), ('c', 5), ('d', 4)}
        diff = dict1.keys() & dict2

        diff_vals = [(k, dict1[k], dict2[k]) for k in diff if dict1[k] != dict2[k]]
        print(diff_vals)
        #相同key,不同value
        #输出:[('c', 3, 5)]
        """
        db1 = open('db_modify.txt', 'r')
        db1 = db1.readlines()
        # print(len(db1),db1)
        db2 = open('db_submit.txt', 'r')
        db2 = db2.readlines()
        # print(db2)
        if db1 == db2:
            print("all right")
        else:
            for i in range(0, len(db1)):
                if db1[i] == db2[i]:
                    if db1[2:12] == 'materialid':
                        print('all right')
                    else:
                        pass
                else:
                    dict1 = eval(db1[i])
                    dict2 = eval(db2[i])
                    diff = dict1.keys() & dict2

                    diff_vals = [(k, dict1[k], dict2[k])
                                 for k in diff if dict1[k] != dict2[k]]
                    print(diff_vals)

if __name__ == '__main__':
    pass

5.代码文件 main.py 为程序执行入口,命令:python main.py 素材ID 0/1/2/3

# !/usr/bin/python
# -*- coding:utf-8 -*-
# Time    : 2020-03-23 14:23
# author  : Zhoujunjun
# File    : main

import JudgeDbdata as jd
import DbCrud as dc
import dbconfig as df
import sys
import os
dirpath = os.getcwd()
workpath = os.path.abspath(os.path.dirname(os.getcwd()))
sys.path.append(dirpath)
sys.path.append(workpath)

"""
使用方法: python JudgeDbdata 素材id 0/1/2/3
"""

# 需要查询的素材id
# materialid = ('100002998', '100002990')
# python 命令输入的第1个参数为素材ID
materialid = (str(sys.argv[1]), '')

# python 命令输入第2个参数决定file的值
i = int(sys.argv[2])

# 查询的素材字段写入db_field.txt,修改前的查询素材sql结果写入文件db_modify.txt,前端不修改编辑提交素材后,查询素材sql结果写入文件db_submit.txt
file = ['db_field.txt', 'db_modify.txt', 'db_submit.txt', 'select'][i]

# 查询素材数据SQL语句
sql = "select * from designmaterial where materialid in %s" % (materialid,)

# 将相关素材的相关字段改成默认值
updata = 1

a = jd.JudgeDbdata()

if file == 'db_field.txt':
    # 修改前查询素材的表字段和字段值写入db_field.txt
    a.connet_db()
    a.write_db(file, materialid, sql)
    print('db_field.txt文件写入完成')

elif file == 'db_modify.txt':
    # 调用DbCurd模块的函数,执行修改素材相关字段默认值
    dc.update_db(updata, materialid)
    dc.db.close()
    # 把修改后的查询结果写入文件db_modify.txt
    a.connet_db()
    a.write_db(file, materialid, sql)
    print('db_modify.txt文件写入完成')
    jd.db.close()

elif file == 'db_submit.txt':
    # 工厂后台前端不修改提交保存后,查询数据写入文件db_submit.txt
    a.connet_db()
    a.write_db(file, materialid, sql)
    print('db_submit.txt文件写入完成')
    # 判断修改前和编辑提交后,查询的素材数据db_modify.txt和db_submit.txt是否相同,如果不同,输出不同的字段和值
    a.judge_dict()
    jd.db.close()

elif file == 'select':
    a.connet_db()
    select_ret = a.get_dict_data_sql(sql)
    print(select_ret)

所以,整个测试流程为:

1.python main.py materialid 0

2.python main.py materialid 1

3.进入工厂后台对应模块的素材编辑页面,不修改直接点提交保存

4.python main.py materialid 2

比对mysql两个表的数据 mysql对比数据差异_linux_02

取10个模块的其中一个素材执行以上流程,可以覆盖全部的测试场景,完成10次的测试流程时间并得出结果大约在30分钟。

六、环境配置及相关

gitcommand.sh文件 是一个Linux执行git push代码到堡垒机的脚本。

因为连接的数据库是测试环境的数据库,只能在堡垒机上面操作,所以,代码也只能在堡垒机上面运行,具体操作步骤:

在堡垒机上面配置虚拟环境,并使用命令 workon fmb_venv 进入虚拟环境,安装需要的python包,再从gitlad pull 代码下来,执行测试流程就可以了