Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
zcyuefan committed Apr 11, 2017
1 parent e607fee commit 9738ac6
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 134 deletions.
27 changes: 23 additions & 4 deletions smart_QC/apps/test_api/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"""
file doc
"""

from __future__ import unicode_literals
from xadmin.plugins.actions import BaseActionView, ACTION_CHECKBOX_NAME
from django.utils.translation import ugettext as _
from django.utils.encoding import force_unicode
Expand All @@ -19,6 +19,7 @@
from xadmin.views.base import filter_hook

from models import TestEnvironment
from tasks import run_case


class RunCase1(BaseActionView):
Expand Down Expand Up @@ -66,14 +67,32 @@ def update_models(self, queryset):
if n:
queryset.update(last_run_status='1')
# 调用task 方法,进行异步请求
arguments_str = self.request.POST.get('arguments', '')
if arguments_str:
try:
arguments_obj = eval(arguments_str)
selected_environment = arguments_obj.get('test_environment', '')
selected_case = arguments_obj.get('case', '')
if int(selected_environment.get('id')) and isinstance(selected_case, list):
run_case(test_environment=selected_environment, case=selected_case)
# run_case.delay(test_environment=selected_environment, case=selected_case)
self.message_user(_("Successfully add the task to run the %(count)d %(items)s.") % {
"count": n, "items": "case"
}, 'success')
else:
self.message_user(_('Invalid environment or case!'),
'error')
except Exception:
import traceback
print(traceback.format_exc())
self.message_user(_('Invalid arguments, please select valid test environment and case!'), 'error')
else:
self.message_user(_('Arguments field is required!'), 'error')
# if self.delete_models_batch:
# queryset.delete()
# else:
# for obj in queryset:
# obj.delete()
# self.message_user(_("Successfully deleted %(count)d %(items)s.") % {
# "count": n, "items": model_ngettext(self.opts, n)
# }, 'success')

# @filter_hook
def do_action(self, queryset):
Expand Down
1 change: 1 addition & 0 deletions smart_QC/apps/test_api/adminx.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python
# encoding=utf-8
# Register your models here.
from __future__ import unicode_literals
import xadmin
from xadmin import views
from models import TestHost, TestEnvironment, CaseTag, OriginalAPI, APITemplate, Case, ReplayLog, Variable, Assertion
Expand Down
75 changes: 67 additions & 8 deletions smart_QC/apps/test_api/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,76 @@
# update:

"""
file doc
celery异步任务
"""

from __future__ import unicode_literals
from celery import shared_task
from models import TestHost, Case

# 限制api group调用其他用例的层数,避免相互调用产生死循环,分别是[初值, 当前递归层数, 限制递归层数]
# INVOKE_LEVEL = [1, 1, 3]
INVOKE_LEVEL = {"from": 1, "current": 1, "to": 3}

@shared_task
def run_case(test_environment, case):
"""
执行接口测试用例
:param test_environment:测试环境
:param case:测试用例
:return:
"""
valid_hosts = TestHost.objects.filter(testenvironment__id=test_environment.get('id')).values_list('id', 'name',
'module')
case_ids = [i.get('id') for i in case]
selected_case = Case.objects.filter(id__in=case_ids).order_by()
# reorder query set
selected_case_reordered = _reorder(selected_case, case_ids)
for c in selected_case_reordered:
if c.case_type == 0: # Single API
_single_api_replay(valid_hosts, c)
elif c.case_type == 1: # APIGroup
_api_group_replay(valid_hosts, c)
return None


def _reorder(query_set, id_list):
new_set = []
try:
for i in id_list:
for q in query_set:
if q.id == int(i):
new_set.append(q)
except Exception:
pass
finally:
return new_set


def _single_api_replay(valid_hosts, case):
# 替换host, 运行参数化,运行setup, 发起request,断言,添加或修改参数,运行teardown,新增replaylog
INVOKE_LEVEL["current"] = INVOKE_LEVEL["from"]
print(INVOKE_LEVEL)
print('invoke _single_api_replay %s %s' % (INVOKE_LEVEL["current"], case.id))


def _api_group_replay(valid_hosts, case):
sub_case_ids = case.invoke_cases.values_list('id')
sub_cases = Case.objects.filter(id__in=sub_case_ids)
id_list = [i[0] for i in sub_case_ids]
sub_cases_reorder = _reorder(sub_cases, id_list)
for c in sub_cases_reorder:
if c.case_type == 0: # Single API
_single_api_replay(valid_hosts, c)
elif c.case_type == 1 and INVOKE_LEVEL["current"] <= INVOKE_LEVEL["to"]: # APIGroup
print('invoke _api_group_replay %s %s' % (INVOKE_LEVEL["current"], c.id))
INVOKE_LEVEL["current"] += 1
_api_group_replay(valid_hosts, c)
else:
print('invoke limited %s %s' % (INVOKE_LEVEL["current"], c.id))
INVOKE_LEVEL["current"] = INVOKE_LEVEL["from"]
continue

# @task()
# def do_request(obj):
#

@shared_task
def add(x, y):
# import time
# time.sleep(30)
return x + y
return x + y
1 change: 1 addition & 0 deletions smart_QC/apps/test_api/tests.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from __future__ import unicode_literals
from django.test import TestCase

# Create your tests here.
1 change: 1 addition & 0 deletions smart_QC/apps/test_api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from __future__ import unicode_literals
from django.conf.urls import url

import views
Expand Down
1 change: 1 addition & 0 deletions smart_QC/apps/test_api/views.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from __future__ import unicode_literals
from django.shortcuts import render
from django.http import HttpResponse

Expand Down
4 changes: 4 additions & 0 deletions smart_QC/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,5 +228,9 @@

# CELERY_ALWAYS_EAGER = True
CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler'

# 限制api group调用其他用例的层数,避免相互调用产生死循环
SMART_QC_INVOKE_LEVEL_FROM = 1
SMART_QC_INVOKE_LEVEL_TO = 3
# 针对不同环境引入不同的配置
# from settings_for_envs.dev import *
16 changes: 7 additions & 9 deletions smart_QC/templates/test_api/run_case_selected_confirm.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,9 @@
</div>
<div class="control" style="clear:both">
<h4 style="color:#447e9b;background:lightblue;padding: 5px;width:auto;float: left;clear:both">{% blocktrans %}
Click header to sort, or drag and pull rows, or edit the arguments directly!
directly!{% endblocktrans %}</h4>
Click table header to sort, drag and pull rows, or edit the arguments directly!{% endblocktrans %}</h4>
<div style="clear:both;width: 49%;float:left">
<label>Case</label>
<label>Cases</label>
<table id="id_case" class="tablesorter table table-bordered table-striped table-hover">
<thead>
<tr>
Expand All @@ -72,22 +71,21 @@ <h4 style="color:#447e9b;background:lightblue;padding: 5px;width:auto;float: lef
</tbody>
</table>
</div>

<div class="controls" style="width:49%;float: right">
<label>Arguments</label>
<textarea id="id_arguments" style="width: 100%;height: 500px"></textarea>
</div>
</div>
<form action="" method="post">{% csrf_token %}
<div>
{% for obj in queryset %}
<input type="hidden" name="{{ action_checkbox_name }}" value="{{ obj.pk|unlocalize }}"/>
{% endfor %}
<div class="controls" style="width:49%;float: right">
<label>Arguments</label>
<textarea id="id_arguments" name="arguments" style="width: 100%;height: 500px"></textarea>
</div>
<input type="hidden" name="action" value="run_selected"/>
<input type="hidden" name="post" value="yes"/>
{% view_block 'form_fields' %}
<div class="form-actions well well-sm fixed">
<input class="btn btn-danger btn-lg" type="submit" value="{% trans "Run an one-time task!" %}"/>
<input class="btn btn-danger btn-lg" type="submit" value="{% trans "Run only once!" %}"/>
<a class="btn btn-default pull-right" onclick="javascript:history.back();">{% trans 'Cancel' %}</a>
</div>
</div>
Expand Down
113 changes: 0 additions & 113 deletions smart_QC/templates/test_api/run_case_selected_confirm1.html
Original file line number Diff line number Diff line change
@@ -1,113 +0,0 @@
{% extends base_template %}
{% load i18n l10n %}
{% load staticfiles %}
{% block extrastyle %}{{ block.super }}
<style>
.controls {
background-color: white;
padding: 0 !important;
}
.form-control{
width:90%
}
.fl{float:left}
</style>
<link type="text/css" rel="stylesheet" href="{% static "vendor/jquery-ui/css/jquery-ui.css" %}" />
<link type="text/css" rel="stylesheet" href="{% static "xadmin/css/xadmin.form.css" %}" />
<script type="text/javascript" src="{% static "xadmin/vendor/jquery/jquery.js" %}"></script>
<script type="text/javascript" src="{% static "common/js/common.js" %}"></script>
<script type="text/javascript" src="{% static "test_api/js/run-case.js" %}"></script>
{% endblock %}
{% load xadmin_tags %}

{% block breadcrumbs %}
<ul class="breadcrumb">
<li><a href="{% url 'xadmin:index' %}">{% trans 'Home' %}</a></li>
<li><a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a></li>
<li>{% trans 'Run Selected ' %} {{ objects_name|capfirst }}</li>
</ul>
{% endblock %}S
{% block nav_title %}{{ title }}{% endblock %}

{% block content %}
<div class="alert alert-warning">{% blocktrans %}You can run selected cases in below ways:</br>
1. As an one-time task</br>
2. Copy the arguments and add a periodic task in Djcelery{% endblocktrans %}</div>
<div class="form-group col-sm-4">
<label class="control-label fl" style="line-height: 40px">Test Environment</label><span class="asteriskField fl" style="color: red;line-height: 40px;margin:0 5px 0 5px"> *</span>
<div class="controls fl" style="width:75%;">
<div class="control-wrap" style="float:left;width:100%">
<select id="id_test_environment" name="test_environment" class="input-md form-control fl" style="width:80%;margin:5px;">
<option value="0"> ------ </option>
{% for test_environment in test_environments %}
<option value="{{ test_environment.id }}">{{ test_environment.name }}</option>
{% endfor %}
</select>
<a href="/test_api/testenvironment/add/" title="Create New Test Environment"
class="btn btn-primary btn-sm btn-ajax pull-right"
target="_blank"><i
class="fa fa-plus"></i></a>
</div>
</div>
</div>
<div class="control" style="clear:both">
<h4 style="color:#447e9b;background:lightblue;padding: 5px;width:auto;float: left;clear:both">{% blocktrans %}
Drag and pull rows to adjust order!{% endblocktrans %}</h4>
<table id="id_case" class="table table-bordered table-striped table-hover">
{# <caption>Drag and pull rows to adjust order!</caption>#}
<thead>
<tr>
<th scope="col" class="sortable">
<div class="dropdown pull-left">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
ID
</a>
<ul class="dropdown-menu" role="menu">
<li><a href="?o=id" class="active"><i class="fa fa-caret-up"></i> Sort ASC</a></li>
<li><a href="?o=-id" class="active"><i class="fa fa-caret-down"></i> Sort DESC</a></li>
</ul>
</div>
</th>
{# <th>ID</th>#}
<th scope="col" class="sortable">
<div class="dropdown pull-left">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
Name
</a>
<ul class="dropdown-menu" role="menu">
<li><a href="?o=id" class="active"><i class="fa fa-caret-up"></i> Sort ASC</a></li>
<li><a href="?o=-id" class="active"><i class="fa fa-caret-down"></i> Sort DESC</a></li>
</ul>
</div>
</th>
</tr>
</thead>
<tbody>
{% for obj in queryset %}
<tr>
<td>{{ obj.id }}</td>
<td>{{ obj.name }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<form action="" method="post">{% csrf_token %}
<div>
{% for obj in queryset %}
<input type="hidden" name="{{ action_checkbox_name }}" value="{{ obj.pk|unlocalize }}"/>
{% endfor %}
<input type="hidden" name="action" value="run_selected"/>
<input type="hidden" name="post" value="yes"/>
{% view_block 'form_fields' %}
<div class="form-actions well well-sm fixed">
<input class="btn btn-danger btn-lg" type="submit" value="{% trans "Yes, run only once!" %}"/>
<input class="btn btn-danger btn-lg" type="button" onclick="getAguments('keyword');"
value="{% trans 'Copy arguments' %}"/>
<input class="btn btn-danger btn-lg" type="button" onclick="javascript:history.back();"
value="{% trans 'Copy keyword arguments' %}"/>
<a class="btn btn-default pull-right" onclick="javascript:history.back();">{% trans 'Cancel' %}</a>
</div>
</div>
</form>
{% endblock %}

0 comments on commit 9738ac6

Please sign in to comment.