美文网首页
让度量的理想照进现实(下)

让度量的理想照进现实(下)

作者: hxfirefox | 来源:发表于2019-07-16 08:45 被阅读0次

    上篇对自动化测试防护有效性度量进行了分析与设计解决了数据来源、数据结构、数据用途的问题,但在工程实施上因陋就简地采取手工统计的方式。毋庸置疑,这肯定不是度量实施的最终形态,毕竟手工实施存在不少不确定性,特别是实施者引入的不确定性。要消除这种不确定性就要尽量依赖非人工的方式,从这点出发可以考虑下面这样的一个系统来完成。

    度量系统设想图

    在这个系统中,自动化测试防护运行在CI环境上,每天会执行一次全量的自动化测试,执行完的失败结果解析后推送到系统上作为原始数据存储在数据库中,而这个原始数据就是上篇中为手工统计设计的表格,系统在存储原始数据的同时为原始数据产生一个唯一标识方便后面的衍生数据进行关联。

    该系统的用户分两类,一类是自动化测试用例的守护者,他们负责对失败用例进行分析后在系统上填写失败原因;另一类则是利用系统中的数据进行度量(后称度量者),如前面文章提到的一些例子,利用系统中的原始数据与衍生数据可以产生许多十分有意思的结果。

    这套系统看上去所需的东西不太多,但实际上在工程实施过程中需要考虑许多问题,为了清晰描述这些问题,我们仍然采用度量中的三个关键问题的顺序来分析系统中需要解决的问题。

    数据来源

    运行自动化测试的CI环境将产生我们需要的数据,运行后的报告通常是便于解析XML或HTML格式的,通过工具脚本解析后才是真正的数据源,而数据源与我们设计的系统通常并不部署在一起,需要通过某种手段将数据源输送出去,一般的做法是使用REST接口。

    flask

    REST对数据源的获取可以采用push或者pull的方式,考虑到CI环境通常是随CI事件触发动态分配而我们设计的系统固定运行,采用CI向度量系统push数据的方式更为合理,因此度量系统需要提供一套REST接口能够让CI推送自动化测试运行结果的原始数据。

    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route('/qmonitor/api/v1.0/failcase', methods=['POST'])
    def create_fail_record():
          pass
    
    if __name__ == '__main__':
        app.run(host="0.0.0.0", port="15001", debug=True)
    

    REST框架选择较多,Java、Ruby或是Python都可以考虑。这里选择了基于Python的Flask,它非常轻量化可利用极少的代码构建出一个Web后端而把注意力集中在开发业务上(如上所示)。

    数据结构

    上篇提到原始数据和衍生数据是度量展开的基础,在一阶段通过手工统计的方式形成了两张表,现在我们要借助数据库来管理这些数据。简单分析就不难看出原始数据与衍生数据存在着关联,原始数据条目(后称用例)与衍生数据条目(后称分析)1:1对应,我们选择了PostgreSQL作为数据库。

    postgresql

    还有一点需要讨论的是数据库中表定义是将用例、分析数据分表存储还是合表存储。我们希望用例尽量少地被修改,只有插入操作以及必要的删除操作,而分析依赖守护者更新,所以分表更适合,至于呈现到web页面的内容(用例+分析)则可以通过数据库提供的关联查询实现。

    class FailAnalysis(db.Model):
        __tablename__ = 'fail_analysis'
    
        r_id = db.Column(db.String(36), db.ForeignKey('fail_testcases.r_id'), primary_key=True)
        reason_category = db.Column(db.Integer, default=0)
        reason_detail = db.Column(db.String(256))
        fix_plan = db.Column(db.Integer, default=0)
        fix_date = db.Column(db.Date)
    
        def __init__(self, r_id):
            self.r_id = r_id
    
        def save(self):
            db.session.add(self)
            db.session.commit()
            return self
    
        def update(self):
            db.session.commit()
            return self
    
        def remove(self):
            db.session.delete(self)
            db.session.commit()
            return self
    

    选择Flask的另一个好处是它强大的扩展,尤其是在数据库的操作上,Flask-SQLAlchemy提供了ORM(Object Relational Mapping,对象关系映射)而无需直接编写SQL,这种写法对SQL了解不深的我来说真的是太友好了。

    数据使用

    前面探讨系统设计的时候提到两类用户,他们使用数据的方式是不一样的。作为守护者关注的是用例展现与分析编辑功能,例如失败的用例中与自己关联的是哪些?失败用例的相关信息在哪里获取?如何填写原因分类与明细?自己的修订方式是否符合系统的要求?作为度量者关注的则是度量指示的呈现,例如拦截率、失败用例分布、失败原因分布、历史趋势等。在拥有数据的基础上,无论哪一种使用方式都可以借助社区成熟的组件实现,例如D3、EChart等,重点仍然是对业务模型的映射以及易用性地提升。

    早期实现

    在前端实现上我就不展开细说了,实在是受限自身水平连门都没摸着,任何一个有前端开发经验的人都能做的比我更好,这里只能放一张系统早期完工后的截图,从中应该能一窥数据使用的端倪。

    总结

    用了两篇文章来讲我如何从度量想法到人工统计再到设计和实现一个在线系统来对支撑数据搜集、分析和统计。实际上我在考虑人工统计的时候就已经在思考如何实现一个线上系统(Flask+PostgreSQL+Nginx),正如我文章提到的这样一个系统的业务模型并不复杂通过回答三个问题(从哪里来,长什么样,要怎么用)可以大体上逼近,此外通过构建线上系统,我们也发现类似度量的实现也是相似的,这就为这个线上系统的扩展提供了可能。

    对度量来说,“坐而论道”是重要的,但如果想要真正牵引改进的发生,那么请让度量的理想照进现实吧!

    相关文章

      网友评论

          本文标题:让度量的理想照进现实(下)

          本文链接:https://www.haomeiwen.com/subject/stvyhctx.html