TA的每日心情 | 无聊 昨天 09:34 |
---|
签到天数: 1052 天 连续签到: 2 天 [LV.10]测试总司令
|
4#
楼主 |
发表于 2020-4-15 14:05:41
|
只看该作者
咦?这里我们貌似引入了一个新词模板,没错flask中使用Jinja作为模板。
我们一起来看下Jinja中一些常用知识点。
- <font color="black">0:表达式
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
- <htmllang="en">
- <head>
- <title>My Webpage</title>
- </head>
- <body>
- <ulid="navigation"> {% for item in navigation %}
- <li><ahref="{{ item.href }}">{{ item.caption }}</a></li>
- {% endfor %} </ul>
- <h1>My Webpage</h1> {{ a_variable }}
- </body>
- </html></font>
复制代码 两种分隔符{% … %} 和 {{ … }}. 前者用于执行表达式, 后者打印表达式的结果.
- 1.变量
- #这两种表达方式是一样的,如果属性不存在默认的设置是返回空字符串
- {{ foo.bar }}{{ foo['bar']}}
- 2.Filters(过滤器,我们也可以自定义过滤器)
- 对变量操作的函数,以|的形式写在后面
- #几个例子
- 1. attr(obj, name)
- foo|attr("bar")<=>(等价于) foo["bar"]
- 2.batch(value, linecount, fill_with=None)
- #从左边取3个值,fill_with为不够的情况下的填充值
- {%-for row in items|batch(3,' ')%}
- 4.注释Comments
- #写在{# ... #}之间
- {# note: disabled template because we no longer usethis
- {%for user in users %}...{% endfor %}#}
- 5.空白 whitespace control
- 1.没有配置trim_blocks 和 lstrip_blocks
- <div>{%ifTrue%} yay {% endif %}</div> -><div> yay </div>
- 2. 配置了 trim_blocks 和 lstrip_blocks
- <div> yay </div>
- 3. 手动开启lstrip_blocks
- <div> {%+ if something %}yay{% endif %} </div>
- 4. 手动删除空白
- {%for item in seq -%}{{ item }}{%- endfor %}
- 6.转换符Escaping
- # 使用{{}} ,或者raw block {% raw %}
- {{'{{'}}{% raw %}<ul>{%for item in seq %}<li>{{ item }}</li>
- {% endfor %}</ul>{% endraw %}
- 7.Line Statements
- 配置后可以mark a line as a statement
- # for item in seq:
- <li>{{ item }}</li>## this comment is ignored
- # endfor
- 这种方法同{%for item in seq %}<li>{{ item }}</li>{% endfor %}
- 8.模板继承 Template Inheritance
- #1.父类模板 Template
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
- <html lang="en"><html xmlns="http://www.w3.org/1999/xhtml">
- <head>{% block head %}
- <link rel="stylesheet" href="style.css"/>
- <title>{% block title %}{% endblock %}-MyWebpage</title>
- {% endblock %}
- </head>
- <body><div id="content">{% block content %}{% endblock %}</div>
- <div id="footer">{% block footer %}©Copyright2008by<a href="http://domain.invalid/">you</a>. {% endblock %} </div>
- </body>
复制代码 2.子类模板继承Child Template
- {% extends "base.html" %}
- {% block title %}Index{% endblock %}
- {% block head %} {{ super() }}
- <style type="text/css"> .important { color: #336699; } </style> {% endblock %} {% block content %} <h1>Index</h1>
- <p class="important"> Welcome on my awesome homepage. </p> {% endblock %}
复制代码
3.还可以用self,引用block的变量
- <title>{% block title %}{% endblock %}</title>
- <h1>{{ self.title() }}</h1> {% block body %}{% endblock %}
复制代码 Super Blocks 引用parent block的内容
- {% block sidebar %} <h3>Table Of Contents</h3> ... {{ super() }} {% endblock %}
复制代码
5.block 结束符也可以加上名字
- {% block sidebar %} {% block inner_sidebar %} ...
- {% endblock inner_sidebar %}
- {% endblock sidebar %}
复制代码 6.block中的变量引用
- {% for item in seq %} <li>{% block loop_item %}{{ item }}{% endblock %}</li> # 打印为空,因为block内部不能引用外面的item变量 {% endfor %}
- 需要改变为 {% for item in seq %} <li>{% block loop_item scoped %}{{ item }}{% endblock %}</li> {% endfor %}
复制代码
- 7.If a template object was passed to the template context you can extend from that object as well {% extends layout_template %}
复制代码
Jinja2模板的用法非常多,我们只需要掌握常用的即可,遇到不会的直接去官网搜吧。
下面贴上我这边Index.html页面源码中所用到的Jinja:
基类模板内容:
- <!doctype html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>{% block title %} {% endblock %}</title>
- <link rel="stylesheet" type="text/css" href="../static/css/bootstrap.min.css">
- <script src="../static/js/jquery.min.js"></script>
- <script type="text/javascript" src="../static/js/echarts-all.js"></script>
- <script type="text/javascript" src="../static/js/bootstrap.js"></script>
- <script type="text/javascript" src="../static/js/events.js"></script>
- {% block head %}{% endblock %}
- </head>
- <body>
- <nav class="navbar text-info" role="navigation">
- <ul class="nav nav nav-tabs panel-title">
- <li class="dropdown">
- <a class="dropdown-toggle" data-toggle="dropdown" href="#">前端性能<b class="caret"></b></a>
- <ul class="dropdown-menu">
- <li><a href="/index">Clinical项目</a></li>
- <li><a href="#">GeStorage项目</a></li>
- <li><a href="#">Training项目</a></li>
- <li><a href="#">PerformanceTiming学习</a></li>
- </ul>
- </li>
- <li class="dropdown">
- <a class="dropdown-toggle" data-toggle="dropdown" href="#">UI自动化测试<b class="caret"></b></a>
- <ul class="dropdown-menu">
- <li><a href="ui_auto">Clinical项目</a></li>
- <li><a href="ui_auto">GeStorage项目</a></li>
- <li><a href="ui_auto">Training项目</a></li>
- <li><a href="ui_auto">RobotFrame知识库</a></li>
- <li><a href="ui_auto">UI自动化脚本设计</a></li>
- </ul>
- </li>
- <li class="dropdown">
- <a class="dropdown-toggle" data-toggle="dropdown" href="#">接口自动化测试<b class="caret"></b></a>
- <ul class="dropdown-menu">
- <li><a href="service_auto">Clinical项目</a></li>
- <li><a href="service_auto">GeStorage项目</a></li>
- <li><a href="service_auto">Training项目</a></li>
- <li><a href="#">接口测试知识库</a></li>
- </ul>
- </li>
- <li class="dropdown">
- <a class="dropdown-toggle" data-toggle="dropdown" href="#">兼容性自动化测试<b class="caret"></b></a>
- <ul class="dropdown-menu">
- <li><a href="#">Clinical项目</a></li>
- <li><a href="#">GeStorage项目</a></li>
- <li><a href="#">Training项目</a></li>
- <li><a href="#">兼容性实施原理</a></li>
- </ul>
- </li>
- <li class="dropdown">
- <a class="dropdown-toggle" data-toggle="dropdown" href="#">性能测试<b class="caret"></b></a>
- <ul class="dropdown-menu">
- <li><a href="#">Clinical项目</a></li>
- <li><a href="#">GeStorage项目</a></li>
- <li><a href="#">Training项目</a></li>
- <li><a href="#">性能测试实施细则</a></li>
- </ul>
- </li>
- <li><a href="per_auto">全局变量配置</a></li>
- </ul>
- </nav>
- <div id="content" class="container">
- {% block content %}
- {% endblock %}
- </div>
- </body>
- </html>
复制代码 我这边index.html内容如下:
{% extends "base.html" %} //继承基类模板
- {% block title %}平台主页{% endblock %}
- {% block content %}
- <div class="row">
- <label>项目版本</label>
- <select id="project_version" onchange="optionChange()">
- {% for option in project_version.Clinical %}
- <option value={{option}}>{{option}}</option>
- {% endfor %}
- </select>
- <button id="redo" onClick="ajaxReRun()">重新执行</button>
- </div>
- <br>
- <table id="pages_summary" class="table table-hover">
- <th>页面名称</th>
- <th>页面URL</th>
- <th>DNS耗时</th>
- <th>Request耗时</th>
- <th>解析DOM耗时</th>
- <th>DomReady耗时</th>
- <th>LoadEvent耗时</th>
- <th>白屏时长</th>
- <th>整个页面加载耗时</th>
- {% for page in page_load_result %} //Jinja中的循环体
- <tr class="active hover">
- <td class="active"><a href="javascript:{{page.page_name}}()">{{page.page_name}}</a></td>
- <script type="text/javascript">
- function {{page.page_name}}()
- {
- var href = $('#project_version').get(0).selectedOptions[0].text + "_" +"{{page.page_name}}";
- location.href = href
- }
- </script>
- <td class="active">{{page.url}}</td>
- <td class="active">{{page.dns}}</td>
- <td class="active">{{page.request}}</td>
- <td class="active">{{page.dom_parser}}</td>
- <td class="active">{{page.dom_ready}}</td>
- <td class="active">{{page.load_event}}</td>
- <td class="active">{{page.whitewait}}</td>
- <td class="active">{{page.loadall}}</td>
- </tr>
- {% endfor %} //Jinja中循环体的结束标识
- </table>
- <br><br>
- <h4>所有页面加载数据统计堆叠图</h4>
- <div id="page_summary_chart">
- <table id="data_chart" width="100%">
- <tr>
- <td align="center">
- <div id="chart" class="text-align:center" style="width: 1250px;height:650px;">
- <script type="text/javascript">
- // 基于准备好的dom,初始化echarts实例
- var myChart = echarts.init(document.getElementById('chart'));
- // 指定图表的配置项和数据
- option = {
- tooltip : {
- trigger: 'axis',
- axisPointer : {type : 'shadow'}
- },
- legend: {
- data:['dns(ms)', 'request(ms)', 'dom_parser(ms)', 'dom_ready(ms)', 'load_event(ms)', 'whitewait(ms)', 'loadall(ms)'],
- },
- toolbox: {
- show : true,
- feature : {
- mark : {show: true},
- dataView : {show: true, readOnly: false},
- magicType : {show: true, type: ['line', 'bar', 'stack', 'tiled']},
- restore : {show: true},
- saveAsImage : {show: true}
- }
- },
- calculable : true,
- xAxis : [
- {
- type : 'value'
- }
- ],
- yAxis : [
- {
- type : 'category',
- data : {{page_chart_data.page_name|safe}}
- }
- ],
- series : [
- {
- name:'dns(ms)',
- type:'bar',
- stack: 'Time',
- itemStyle : { normal: {label : {show: true, position: 'insideRight'}}},
- data: {{page_chart_data.dns|safe}}
- },
- {
- name:'request(ms)',
- type:'bar',
- stack: 'Time',
- itemStyle : { normal: {label : {show: true, position: 'insideRight'}}},
- data: {{page_chart_data.request|safe}}
- },
- {
- name:'dom_parser(ms)',
- type:'bar',
- stack: 'Time',
- itemStyle : { normal: {label : {show: true, position: 'insideRight'}}},
- data: {{page_chart_data.dom_parser|safe}}
- },
- {
- name:'dom_ready(ms)',
- type:'bar',
- stack: 'Time',
- itemStyle : { normal: {label : {show: true, position: 'insideRight'}}},
- data: {{page_chart_data.dom_ready|safe}}
- },
- {
- name:'request(ms)',
- type:'bar',
- stack: 'Time',
- itemStyle : { normal: {label : {show: true, position: 'insideRight'}}},
- data: {{page_chart_data.request|safe}}
- },
- {
- name:'load_event(ms)',
- type:'bar',
- stack: 'Time',
- itemStyle : { normal: {label : {show: true, position: 'insideRight'}}},
- data: {{page_chart_data.load_event|safe}}
- },
- {
- name:'whitewait(ms)',
- type:'bar',
- stack: 'Time',
- itemStyle : { normal: {label : {show: true, position: 'insideRight'}}},
- data: {{page_chart_data.whitewait|safe}}
- },
- {
- name:'loadall(ms)',
- type:'bar',
- stack: 'Time',
- itemStyle : { normal: {label : {show: true, position: 'insideRight'}}},
- data: {{page_chart_data.loadall|safe}}
- }
- ]
- };
- // 使用刚指定的配置项和数据显示图表。
- myChart.setOption(option);
- </script>
- </div>
- </td>
- </tr>
- </table>
- </div>
- {% endblock %}
- (PS:在一个表格中循环查询到的结果并输出到页面)
复制代码
下面贴出来我这边views.py文件里的全部内容供同学们参考:
- # -*- coding:utf-8 -*-
- import sqlite3
- import sys
- import time
- import requests
- from flask import render_template, g, redirect, url_for, request, send_file
- from selenium import webdriver
- import config
- from Web import web_app
- reload(sys)
- sys.setdefaultencoding("utf-8")
- # 定义根路由
- @web_app.route('/')
- def root():
- return render_template('login.html')
- @web_app.route('/login_success')
- def login_success():
- return render_template('login_success.html')
- # 定义路由index
- @web_app.route('/index', methods=['GET', 'POST'])
- def index():
- if request.method == 'POST':
- version = request.form.get("selected_version", "null")
- else:
- version = 'syf1.1.1'
- g.db = sqlite3.connect(config.db_dir)
- summary_data_sql = 'select page_name, url, dns, request, dom_parser, dom_ready, load_event, whitewait, loadall '\
- + " from WebLoad where version='" + str(version) + "'" + ' order by page_name'
- page_load_result = query_db(summary_data_sql)
- g.db.close()
- project_version = config.project_version_info
- # 将页面信息转换为Echarts使用的数据
- page_chart_data = {}
- page_name_list = []
- page_dns_list = []
- page_request_list = []
- page_dom_parser_list = []
- page_dom_ready_list = []
- page_load_event_list = []
- page_whitewait_list = []
- page_loadall_list = []
- for result in page_load_result:
- page_name_list.append(str(result['page_name']).strip("u'"))
- page_dns_list.append(result['dns'])
- page_request_list.append(result['request'])
- page_dom_parser_list.append(result['dom_parser'])
- page_dom_ready_list.append(result['dom_ready'])
- page_load_event_list.append(result['load_event'])
- page_whitewait_list.append(result['whitewait'])
- page_loadall_list.append(result['loadall'])
- page_chart_data['page_name'] = page_name_list
- page_chart_data['dns'] = page_dns_list
- page_chart_data['request'] = page_request_list
- page_chart_data['dom_parser'] = page_dom_parser_list
- page_chart_data['dom_ready'] = page_dom_ready_list
- page_chart_data['load_event'] = page_load_event_list
- page_chart_data['whitewait'] = page_whitewait_list
- page_chart_data['loadall'] = page_loadall_list
- return render_template('index.html', project_version=project_version, page_load_result=page_load_result, page_chart_data=page_chart_data)
- # 定义重新执行脚本的路由
- @web_app.route('/redo', methods=['GET', 'POST'])
- def redo():
- if request.method == 'GET':
- return 'route does not support get'
- else:
- # 向测试环境发生get请求来验证测试环境是否存在
- env_for_test = request.form.get("selected_version", "null")
- current_env = config.hosts['164'] + env_for_test
- env_test_code = requests.get(current_env).status_code
- if env_test_code == 200:
- # 定义页面名称列表
- all_page_data = {}
- page_urls = config.page_urls
- timing_js = config.timing_js
- # 统计页面加载时间的6个维度登录页专用
- index_data = {'dns': 0, 'request': 0, 'dom_parser': 0, 'dom_ready': 0, 'load_event': 0, 'whitewait': 0, 'loadall': 0}
- # index页面资源的信息登录页专用
- page_index_info = []
- # 将统计数据保存到sqlite
- connection = sqlite3.connect(config.db_dir)
- cursor = connection.cursor()
- # 先删除页面资源细分表webDetailLoad所有数据
- clear_resource_sql = "delete from PageDetail where project='Clinical' and version='" + env_for_test + "'"
- cursor.execute(clear_resource_sql)
- # 先清理上次的数据
- clear_webload_sql = "delete from WebLoad where project='Clinical' and version='" + env_for_test + "'"
- cursor.execute(clear_webload_sql)
- connection.commit()
- # get到clinical登录页(登录页需要单独收集其页面加载性能指标)
- driver = webdriver.Chrome()
- login_url = current_env + '/login/index'
- driver.get(login_url)
- driver.maximize_window()
- time.sleep(5)
- time_line = driver.execute_script(config.timing_js)
- # 将页面加载时间存入all_page_data
- for key in index_data.keys():
- index_data[key] = time_line[key]
- # 将index的数据存入all_page_data
- all_page_data['Index'] = index_data
- # 获得index页面所有的资源实体
- entries = driver.execute_script(config.get_entries_js)
- # 遍历登录页面所有资源
- for items in entries:
- # 以页面名:数组形式保存页面信息
- page_index_resource = {}
- # 资源名称
- page_index_resource['name'] = items['name']
- # 资源类型分类
- resource_type = str(items['name']).split('.')[-1]
- if resource_type in ['jpg', 'png', 'gif', 'jpeg']:
- page_index_resource['resourceType'] = 'img'
- elif resource_type == 'js':
- page_index_resource['resourceType'] = 'js'
- elif resource_type == 'css':
- page_index_resource['resourceType'] = 'css'
- else:
- if items['initiatorType'] == 'xmlhttprequest':
- page_index_resource['resourceType'] = 'xmlhttprequest'
- elif items['initiatorType'] == 'script':
- page_index_resource['resourceType'] = 'js'
- else:
- page_index_resource['resourceType'] = 'other'
- # 资源大小
- page_index_resource['transferSize'] = items['transferSize']
- # 资源耗时
- page_index_resource['duration'] = items['duration']
- # 将登录页资源信息存入列表
- page_index_info.append(page_index_resource)
- # 将登录页资源列表信息存入字典对象对应key为Index
- save_resource_sql = 'insert into PageDetail ' + "values('Clinical','" + str(env_for_test) + "'," + "'" + str(
- 'Index') + "'," + "'" + str(page_index_resource['name']) + "'," + "'" + str(
- page_index_resource['resourceType']) + "'," + "'" \
- + str(page_index_resource['transferSize']) + "'," + "'" + str(
- page_index_resource['duration']) + "'," + 'CURRENT_TIMESTAMP)'
- cursor.execute(save_resource_sql)
- connection.commit()
复制代码
|
|