Commit c35a8ca4 authored by 王英豪's avatar 王英豪

提交项目

parent ee2416d2
Pipeline #1823 failed with stages

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="FacetManager">
<facet type="django" name="Django">
<configuration>
<option name="rootFolder" value="$MODULE_DIR$" />
<option name="settingsModule" value="AutomatedTestPlatform/settings.py" />
<option name="manageScript" value="$MODULE_DIR$/manage.py" />
<option name="environment" value="&lt;map/&gt;" />
<option name="doNotUseTestRunner" value="false" />
<option name="trackFilePattern" value="migrations" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/tutorial-env" />
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="jdk" jdkName="Python 3.7" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Django Lib" level="project" />
</component>
<component name="PyDocumentationSettings">
<option name="format" value="PLAIN" />
<option name="myDocStringFormat" value="Plain" />
<option name="renderExternalDocumentation" value="true" />
</component>
<component name="TemplatesService">
<option name="TEMPLATE_CONFIGURATION" value="Django" />
</component>
<component name="TestRunnerService">
<option name="PROJECT_TEST_RUNNER" value="py.test" />
</component>
</module>
\ No newline at end of file
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>
\ No newline at end of file
<component name="libraryTable">
<library name="Django Lib">
<CLASSES>
<root url="file://$PROJECT_DIR$/venv/Lib/site-packages" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7" project-jdk-type="Python SDK" />
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/AutomatedTestPlatform.iml" filepath="$PROJECT_DIR$/.idea/AutomatedTestPlatform.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PySciProjectComponent">
<option name="PY_SCI_VIEW" value="true" />
<option name="PY_SCI_VIEW_SUGGESTED" value="true" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
import pymysql
pymysql.version_info = (1, 4, 13, "final", 0)
pymysql.install_as_MySQLdb()
"""
ASGI config for AutomatedTestPlatform project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/3.1/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
from AutomatedTestPlatform.urls import websocket_urlpatterns
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'AutomatedTestPlatform.settings')
# application = get_asgi_application()
application = ProtocolTypeRouter({
# Explicitly set 'http' key using Django's ASGI application.
"http": get_asgi_application(),
'websocket': AuthMiddlewareStack(
URLRouter(
websocket_urlpatterns
)
),
})
This diff is collapsed.
"""AutomatedTestPlatform URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URConf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.urls import path
from django.conf.urls import url, include
from django.conf import settings
from django.views.static import serve
from automated_main.view.web_socket.socket import ChatConsumer
urlpatterns = [
# path('admin/', admin.site.urls),
# 用户接口
path('', include("automated_main.url.user_url.user_url")),
# 系统首页
path('', include("automated_main.url.system_home_page_url.system_home_page_url")),
# UI项目接口
path('', include("automated_main.url.ui_automation_url.ui_project_url")),
# UI页面接口
path('', include("automated_main.url.ui_automation_url.ui_page_url")),
# UI页面元素
path('', include("automated_main.url.ui_automation_url.ui_page_element_url")),
# UI定位操作
path('', include("automated_main.url.ui_automation_url.ui_positioning_url")),
# UI元素操作
path('', include("automated_main.url.ui_automation_url.ui_element_operation_url")),
# UI测试用例
path('', include("automated_main.url.ui_automation_url.ui_test_case_url")),
# UI任务管理
path('', include("automated_main.url.ui_automation_url.ui_test_task_url")),
# API项目
# path('', include("automated_main.url.api_automation_url.api_project_url")),
# API模块
# path('', include("automated_main.url.api_automation_url.api_module_url")),
# 获取api环境列表
path('', include("automated_main.url.api_automation_url.api_environment_url")),
# # API测试用例
# path('', include("automated_main.url.api_automation_url.api_test_case_url")),
# API业务测试
# path('', include("automated_main.url.api_automation_url.api_business_test_url")),
# API数据库
path('', include("automated_main.url.api_automation_url.api_database_url")),
# # API任务管理
# path('', include("automated_main.url.api_automation_url.api_test_task_url")),
# API接口管理
path('', include("automated_main.url.api_automation_url.api_management_url")),
# API场景用例
path('', include("automated_main.url.api_automation_url.api_scenarios_case_url")),
# API测试计划
path('', include("automated_main.url.api_automation_url.api_plan_url")),
# 性能测试-性能项目
path('', include("automated_main.url.performance_test_url.performance_project_url")),
# 性能测试-测试脚本
path('', include("automated_main.url.performance_test_url.performance_script_url")),
# 上传文件地址 media配置——配合settings中的MEDIA_ROOT的配置,就可以在浏览器的地址栏访问media文件夹及里面的文件了
url(r'api/jmeter_script/(?P<path>.*)', serve, {'document_root': settings.JMETER_ROOT}),
# 上传文件地址 media配置——配合settings中的MEDIA_ROOT的配置,就可以在浏览器的地址栏访问media文件夹及里面的文件了
url(r'api/jmeter_script_data_set/(?P<path>.*)', serve, {'document_root': settings.JMETER_DATA_SET_ROOT}),
# 性能测试报告地址
url(r'api/jmeter_report/Report/(?P<path>.*)', serve, {'document_root': settings.JMETER_REPORT}),
# API回放
path('', include("automated_main.url.api_querrydiff.api_querrydiff_url")),
]
websocket_urlpatterns = [
# 前端请求websocket连接
path('wx/', ChatConsumer.as_asgi()),
]
"""
WSGI config for AutomatedTestPlatform project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/3.1/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'AutomatedTestPlatform.settings')
application = get_wsgi_application()
# TestPlatformDjango
先添加系统的环境变量 ENV=1 用来区别本地环境以及线上环境
测试环境:ENV=1
生产环境:ENV=SERVER
# 根据数据库迁移文件生成对应SQL语句并执行
python manage.py migrate
# 初次执行时为了先把默认Django需要的数据库创建出来,创建数据库迁移文件
python manage.py makemigrations
# 启动Django
python manage.py runserver 0.0.0.0:8081
#项目介绍
![img13.png](img/img13.png)
#首页
![img.png](img/img11.png)
#Web自动化
页面元素管理
![img_2.png](img/img_2.png)
测试报告
![img_1.png](img/img_1.png)
测试报告详情
![img_3.png](img/img_3.png)
UI定位
![img_4.png](img/img_4.png)
UI元素操作
![img_5.png](img/img_5.png)
#接口自动化
API测试用例
![img.png](img/img6.png)
API测试用例-发送请求
![img_6.png](img/img_6.png)
API业务测试用例
![img_7.png](img/img_7.png)
API测试报告
![img_8.png](img/img_8.png)
API测试报告详情
![img_9.png](img/img_9.png)
#性能测试
性能测试脚本页面
![img_10.png](img/img_10.png)
性能测试脚本
![img_11.png](img/img_11.png)
This source diff could not be displayed because it is too large. You can view the blob instead.
import os
ENV_PROFILE = os.getenv("ENV")
if ENV_PROFILE == "1":
pass
else:
# default_app_config = 'automated_main.apps.InterfaceMainConfig'
pass
# from django.contrib import admin
# Register your models here.
from django.apps import AppConfig
# from automated_main.utils.publish_consumer import MQListenerThread
"""
自定义配置类, 通过重写ready方法, 实现服务启动, 进行mq消息监听
"""
class InterfaceMainConfig(AppConfig):
name = 'automated_main'
def ready(self):
"""
Override this method in subclasses to run code when Django starts.
避免执行两次, 启动命令使用: python manage.py runserver --noreload
"""
# rocket_consumer = MQListenerThread(self.models)
# rocket_consumer.setDaemon(True)
# rocket_consumer.start()
pass
# -*- coding: utf-8 -*-
# @Time : 2020/11/10 22:15
# @Author : wangyinghao
# @FileName: __init__.py.py
# @Software: PyCharm
# -*- coding: utf-8 -*-
# @Time : 2020/11/10 22:15
# @Author : wangyinghao
# @FileName: my_exception.py
# @Software: PyCharm
class ErrorCode:
SYSTEM = 10000
DB = 20000
COMMON = 30000
UNKNOWN = 40000
class MyException(Exception):
def __init__(self, code=ErrorCode.COMMON, message='参数错误'):
self.message = message
self.code = code
def __str__(self):
return self.message
# -*- coding: utf-8 -*-
# @Time : 2020/11/12 11:27
# @Author : wangyinghao
# @FileName: __init__.py.py
# @Software: PyCharm
# -*- coding: utf-8 -*-
# @Time : 2021/4/15 18:14
# @Author : wangyinghao
# @FileName: api_business_test.py
# @Software: PyCharm
from django import forms
class ApiBusinessTestForm(forms.Form):
api_business_test_name = forms.CharField(max_length=50,
min_length=2,
required=True,
error_messages={'required': "Api业务测试名称不能为空"})
api_project_id = forms.CharField(required=False)
api_business_test_describe = forms.CharField(max_length=2000,
min_length=0,
required=False,
error_messages={'required': "描述超过2000字符"})
# -*- coding: utf-8 -*-
# @Time : 2021/10/21 17:15
# @Author : wangyinghao
# @Site :
# @File : api_database.py
# @Software: PyCharm
from django import forms
class ApiDatabaseForm(forms.Form):
api_database_title = forms.CharField(max_length=50,
min_length=2,
required=True,
error_messages={'required': "数据库名称不能为空"})
api_host = forms.CharField(max_length=2000,
min_length=2,
required=False,
error_messages={'required': "host超过2000字符"})
api_port = forms.CharField(max_length=2000,
min_length=2,
required=False,
error_messages={'required': "端口号超过2000字符"})
user = forms.CharField(max_length=2000,
min_length=2,
required=False,
error_messages={'required': "用户名称超过2000字符"})
password = forms.CharField(max_length=2000,
min_length=2,
required=False,
error_messages={'required': "密码超过2000字符"})
database = forms.CharField(max_length=2000,
min_length=2,
required=False,
error_messages={'required': "数据库表名超过2000字符"})
# -*- coding: utf-8 -*-
# @Time : 2021/3/25 16:57
# @Author : wangyinghao
# @FileName: api_environment.py
# @Software: PyCharm
from django import forms
class ApiEnvironmentForm(forms.Form):
api_environment_name = forms.CharField(max_length=200,
min_length=2,
required=True,
error_messages={'required': "API环境名称不能为空"})
api_title = forms.CharField(max_length=200,
min_length=2,
required=True,
error_messages={'required': "API环境标题不能为空"})
api_environment_describe = forms.CharField(max_length=200,
min_length=2,
required=False,
error_messages={'required': "描述超过2000字符"})
# -*- coding: utf-8 -*-
# @Time : 2022/7/15 17:09
# @Author : wangyinghao
# @Site :
# @File : api_interfaces_case.py
# @Software: PyCharm
from django import forms
class ApiInterfacesCaseForm(forms.Form):
api_interfaces_case_name = forms.CharField(max_length=50,
min_length=2,
required=True,
error_messages={'required': "API测试用例名称不能为空",
'max_length': "API测试用例名称不能超过50个字符",
'min_length': "API测试用例名称不能少于2个字符",
}
)
api_documentation = forms.CharField(required=False)
api_management_id = forms.CharField(required=False)
api_environment_id = forms.CharField(required=False)
api_method = forms.CharField(required=False)
api_url = forms.CharField(required=False)
api_parameter_types = forms.CharField(required=False)
api_headers = forms.CharField(required=False)
api_parameter_body = forms.CharField(required=False)
api_assert_type = forms.CharField(required=False)
api_assert_text = forms.CharField(required=False)
dataBase_id = forms.CharField(required=False)
database_sql = forms.CharField(required=False)
# -*- coding: utf-8 -*-
# @Time : 2022/5/24 21:23
# @Author : wangyinghao
# @Site :
# @File : api_management.py
# @Software: PyCharm
from django import forms
class ApiManagementForm(forms.Form):
name = forms.CharField(max_length=200, min_length=1, required=True)
description = forms.CharField(min_length=1, required=False)
parent = forms.IntegerField(required=True)
# -*- coding: utf-8 -*-
# @Time : 2021/3/3 11:03
# @Author : wangyinghao
# @FileName: api_module.py
# @Software: PyCharm
from django import forms
class ApiModuleForm(forms.Form):
api_module_name = forms.CharField(max_length=50,
min_length=2,
required=True,
error_messages={'required': "API模块名称不能为空"})
api_module_describe = forms.CharField(max_length=2000,
min_length=2,
required=False,
error_messages={'required': "描述超过2000字符"})
api_project_id = forms.CharField(required=False)
# -*- coding: utf-8 -*-
# @Time : 2021/3/2 18:46
# @Author : wangyinghao
# @FileName: api_project.py
# @Software: PyCharm
from django import forms
class ApiProjectForm(forms.Form):
api_project_name = forms.CharField(max_length=50,
min_length=2,
required=True,
error_messages={'required': "API项目名称不能为空"})
describe = forms.CharField(max_length=2000,
min_length=2,
required=False,
error_messages={'required': "描述超过2000字符"})
# -*- coding: utf-8 -*-
# @Time : 2022/7/20 10:34
# @Author : wangyinghao
# @File : api_scenarios_case.py
# @Software: PyCharm
from django import forms
class ApiScenariosCaseForm(forms.Form):
api_scenarios_case_name = forms.CharField(max_length=50,
min_length=2,
required=True,
error_messages={'required': "Api场景测试名称不能为空"})
api_management_id = forms.CharField(required=False)
api_scenarios_case_describe = forms.CharField(max_length=2000,
min_length=0,
required=False,
error_messages={'required': "Api场景描述超过2000字符"})
# -*- coding: utf-8 -*-
# @Time : 2021/4/1 11:24
# @Author : wangyinghao
# @FileName: api_test_case.py
# @Software: PyCharm
from django import forms
class ApiTestCaseForm(forms.Form):
api_test_case_name = forms.CharField(max_length=50,
min_length=2,
required=True,
error_messages={'required': "API测试用例名称不能为空",
'max_length': "API测试用例名称不能超过50个字符",
'min_length': "API测试用例名称不能少于2个字符",
}
)
api_documentation = forms.CharField(required=False)
api_module_id = forms.CharField(required=False)
api_environment_id = forms.CharField(required=False)
api_method = forms.CharField(required=False)
api_url = forms.CharField(required=False)
api_parameter_types = forms.CharField(required=False)
api_headers = forms.CharField(required=False)
api_parameter_body = forms.CharField(required=False)
api_assert_type = forms.CharField(required=False)
api_assert_text = forms.CharField(required=False)
dataBase_id = forms.CharField(required=False)
database_sql = forms.CharField(required=False)
# -*- coding: utf-8 -*-
# @Time : 2022/7/21 15:28
# @Author : wangyinghao
# @File : api_test_plan.py
# @Software: PyCharm
from django import forms
class ApiTestPlanForm(forms.Form):
api_test_plan_name = forms.CharField(max_length=100,
min_length=2,
required=True,
error_messages={'required': "API测试计划名称不能为空"})
api_test_plan_describe = forms.CharField(required=False)
cases = forms.CharField(required=False)
api_management_id = forms.CharField(required=False)
api_send_email = forms.CharField(required=False)
api_send_enterprise_wechat = forms.CharField(required=False)
api_environment_id = forms.CharField(required=False)
database_id = forms.CharField(required=False)
timing_task_status = forms.CharField(required=False)
end_time = forms.CharField(required=False)
starting_time = forms.CharField(required=False)
time_interval_day = forms.CharField(required=False)
time_interval_minutes = forms.CharField(required=False)
time_interval_hours = forms.CharField(required=False)
time_interval_seconds = forms.CharField(required=False)
# -*- coding: utf-8 -*-
# @Time : 2021/4/20 18:30
# @Author : wangyinghao
# @FileName: api_test_task.py
# @Software: PyCharm
from django import forms
class ApiTestTaskForm(forms.Form):
api_test_task_name = forms.CharField(max_length=100,
min_length=2,
required=True,
error_messages={'required': "API测试任务名称不能为空"})
describe = forms.CharField(required=False)
cases = forms.CharField(required=False)
api_project_id = forms.CharField(required=False)
api_send_email = forms.CharField(required=False)
api_send_enterprise_wechat = forms.CharField(required=False)
api_environment_id = forms.CharField(required=False)
database_id = forms.CharField(required=False)
timing_task_status = forms.CharField(required=False)
end_time = forms.CharField(required=False)
starting_time = forms.CharField(required=False)
time_interval_day = forms.CharField(required=False)
time_interval_minutes = forms.CharField(required=False)
time_interval_hours = forms.CharField(required=False)
time_interval_seconds = forms.CharField(required=False)
# -*- coding: utf-8 -*-
"""
@Time : 2021/5/27 14:49
@Auth : WangYingHao
@File :performance_project.py
@IDE :PyCharm
"""
from django import forms
class PerformanceProjectForm(forms.Form):
performance_project_name = forms.CharField(max_length=50,
min_length=2,
required=True,
error_messages={'required': "性能测试项目名称不能为空"})
describe = forms.CharField(max_length=2000,
min_length=2,
required=False,
error_messages={'required': "描述超过2000字符"})
# -*- coding: utf-8 -*-
"""
@Time : 2021/5/27 18:02
@Auth : WangYingHao
@File :performance_script.py
@IDE :PyCharm
"""
from django import forms
class PerformanceScriptForm(forms.Form):
performance_script_name = forms.CharField(max_length=50,
min_length=1,
required=True,
error_messages={'required': "性能脚本名称不能为空"})
performance_script = forms.CharField(max_length=5000,
min_length=1,
required=True,
error_messages={'required': "性能脚本不能为空"})
performance_project_id = forms.CharField(required=False)
performance_threads = forms.CharField(max_length=5000,
min_length=1,
required=True,
error_messages={'required': "线程数不能为空"})
performance_ramp_up_time_seconds = forms.CharField(required=True,
error_messages={'required': "Ramp-Up时间(秒)不能为空"})
performance_loop_count = forms.CharField(max_length=5000,
min_length=1,
required=False,
error_messages={'required': "循环次数不能为空"})
performance_scheduler = forms.CharField(max_length=5000,
min_length=1,
required=True,
error_messages={'required': "调度器不能为空"})
performance_duration = forms.CharField(max_length=5000,
min_length=1,
required=False,
error_messages={'required': "持续时间不能为空"})
loop_count_forever = forms.CharField(max_length=5000,
min_length=1,
required=False,
error_messages={'required': "超过5000字符"})
data_set = forms.CharField(max_length=5000,
min_length=1,
required=False,
error_messages={'required': "超过5000字符"})
performance_data_script = forms.CharField(max_length=5000,
min_length=1,
required=False,
error_messages={'required': "超过5000字符"})
# -*- coding: utf-8 -*-
# @Time : 2020/12/19 11:33
# @Author : wangyinghao
# @FileName: ui_element_operation.py
# @Software: PyCharm
from django import forms
class UIElementsOperationForm(forms.Form):
elements_operation_name = forms.CharField(max_length=500,
min_length=2,
required=True,
error_messages={'required': "元素操作名称不能为空"})
elements_operation_title = forms.CharField(max_length=500,
min_length=2,
required=False,
error_messages={'required': "元素操作标题不能为空"})
elements_operation_describe = forms.CharField(max_length=2000,
min_length=2,
required=False,
error_messages={'required': "描述超过2000字符"})
elements_operation_associated_interface = forms.CharField(max_length=200,
min_length=2,
required=False,
error_messages={'required': "描述超过2000字符"})
elements_operation_api_url = forms.CharField(max_length=2000,
min_length=2,
required=False,
error_messages={'required': "描述超过2000字符"})
# -*- coding: utf-8 -*-
# @Time : 2020/12/18 18:33
# @Author : wangyinghao
# @FileName: ui_positioning.py
# @Software: PyCharm
from django import forms
class UiPositioningForm(forms.Form):
positioning_name = forms.CharField(max_length=50,
min_length=2,
required=True,
error_messages={'required': "定位名称不能为空"})
locating_method = forms.CharField(max_length=2000,
min_length=2,
required=False,
error_messages={'required': "定位方法不能为空"})
describe = forms.CharField(max_length=2000,
min_length=2,
required=False,
error_messages={'required': "描述超过2000字符"})
# -*- coding: utf-8 -*-
# @Time : 2020/12/15 18:39
# @Author : wangyinghao
# @FileName: ui_page.py
# @Software: PyCharm
from django import forms
class UiPageForm(forms.Form):
ui_page_name = forms.CharField(max_length=50,
min_length=2,
required=True,
error_messages={'required': "UI页面名称不能为空"})
ui_page_describe = forms.CharField(max_length=2000,
min_length=2,
required=False,
error_messages={'required': "描述超过2000字符"})
ui_project_id = forms.CharField(required=False)
# -*- coding: utf-8 -*-
# @Time : 2020/12/19 16:10
# @Author : wangyinghao
# @FileName: ui_page_element.py
# @Software: PyCharm
from django import forms
class UiPageElementForm(forms.Form):
# ui_page_element_name = forms.CharField(max_length=50,
# min_length=2,
# required=True,
# error_messages={'required': "UI页面元素名称不能为空"})
ui_page_element = forms.CharField(max_length=2000,
min_length=2,
required=False,
error_messages={'required': "页面元素超过2000字符"})
ui_project_id = forms.CharField(required=False)
# ui_page_id = forms.CharField(required=False)
ui_element_positioning_id = forms.CharField(required=False)
# -*- coding: utf-8 -*-
# @Time : 2020/12/9 14:42
# @Author : wangyinghao
# @FileName: ui_project.py
# @Software: PyCharm
from django import forms
class UiProjectForm(forms.Form):
ui_project_name = forms.CharField(max_length=50,
min_length=2,
required=True,
error_messages={'required': "项目名称不能为空"})
describe = forms.CharField(max_length=2000,
min_length=2,
required=False,
error_messages={'required': "描述超过2000字符"})
# -*- coding: utf-8 -*-
# @Time : 2020/12/24 19:04
# @Author : wangyinghao
# @FileName: ui_test_case.py
# @Software: PyCharm
from django import forms
class UiTestCaseForm(forms.Form):
ui_test_case_name = forms.CharField(max_length=50,
min_length=2,
required=True,
error_messages={'required': "测试用例名称不能为空"})
ui_project_id = forms.CharField(required=False)
# -*- coding: utf-8 -*-
# @Time : 2021/1/7 10:31
# @Author : wangyinghao
# @FileName: ui_test_task.py
# @Software: PyCharm
from django import forms
class UiTestTaskForm(forms.Form):
ui_test_task_name = forms.CharField(max_length=100,
min_length=2,
required=True,
error_messages={'required': "UI测试任务名称不能为空"})
describe = forms.CharField(required=False)
cases = forms.CharField(required=False)
ui_project_id = forms.CharField(required=False)
# -*- coding: utf-8 -*-
# @Time : 2020/11/12 11:27
# @Author : wangyinghao
# @FileName: user.py
# @Software: PyCharm
from django import forms
class UserForm(forms.Form):
username = forms.CharField(max_length=50,
min_length=2,
required=True,
error_messages={'required': "用户名不能为空"})
password = forms.CharField(max_length=50,
min_length=2,
required=True,
error_messages={'required': "密码不能为空"})
2021-11-18 20:42:39,467 INFO o.a.j.u.JMeterUtils: Setting Locale to en_EN
2021-11-18 20:42:39,476 INFO o.a.j.JMeter: Loading user properties from: D:\apache-jmeter-5.4.1\bin\user.properties
2021-11-18 20:42:39,477 INFO o.a.j.JMeter: Loading system properties from: D:\apache-jmeter-5.4.1\bin\system.properties
2021-11-18 20:42:39,483 INFO o.a.j.JMeter: Copyright (c) 1998-2021 The Apache Software Foundation
2021-11-18 20:42:39,483 INFO o.a.j.JMeter: Version 5.4.1
2021-11-18 20:42:39,483 INFO o.a.j.JMeter: java.version=1.8.0_311
2021-11-18 20:42:39,483 INFO o.a.j.JMeter: java.vm.name=Java HotSpot(TM) 64-Bit Server VM
2021-11-18 20:42:39,483 INFO o.a.j.JMeter: os.name=Windows 10
2021-11-18 20:42:39,483 INFO o.a.j.JMeter: os.arch=amd64
2021-11-18 20:42:39,483 INFO o.a.j.JMeter: os.version=10.0
2021-11-18 20:42:39,483 INFO o.a.j.JMeter: file.encoding=GBK
2021-11-18 20:42:39,484 INFO o.a.j.JMeter: java.awt.headless=true
2021-11-18 20:42:39,484 INFO o.a.j.JMeter: Max memory =1073741824
2021-11-18 20:42:39,484 INFO o.a.j.JMeter: Available Processors =8
2021-11-18 20:42:39,487 INFO o.a.j.JMeter: Default Locale=English (EN)
2021-11-18 20:42:39,487 INFO o.a.j.JMeter: JMeter Locale=English (EN)
2021-11-18 20:42:39,487 INFO o.a.j.JMeter: JMeterHome=D:\apache-jmeter-5.4.1
2021-11-18 20:42:39,487 INFO o.a.j.JMeter: user.dir =E:\AutomatedTestPlatform\automated_main
2021-11-18 20:42:39,487 INFO o.a.j.JMeter: PWD =E:\AutomatedTestPlatform\automated_main
2021-11-18 20:42:39,488 INFO o.a.j.JMeter: IP: 10.0.18.183 Name: WINDOWS-H7FSB0K FullName: WINDOWS-H7FSB0K
2021-11-18 20:42:39,491 ERROR o.a.j.JMeter: An error occurred:
java.lang.IllegalArgumentException: Cannot write to 'E:\AutomatedTestPlatform\automated_main\result\20211118204238-2s-2qps-2threads-2loops-htmlreport' as folder does not exist and parent folder is not writable
at org.apache.jorphan.util.JOrphanUtils.canSafelyWriteToFolder(JOrphanUtils.java:671) ~[jorphan.jar:5.4.1]
at org.apache.jorphan.util.JOrphanUtils.canSafelyWriteToFolder(JOrphanUtils.java:619) ~[jorphan.jar:5.4.1]
at org.apache.jmeter.JMeter.extractAndSetReportOutputFolder(JMeter.java:609) ~[ApacheJMeter_core.jar:5.4.1]
at org.apache.jmeter.JMeter.start(JMeter.java:563) [ApacheJMeter_core.jar:5.4.1]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_311]
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_311]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_311]
at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_311]
at org.apache.jmeter.NewDriver.main(NewDriver.java:254) [ApacheJMeter.jar:5.4.1]
# creater for yanfuchang
\ No newline at end of file
# creater for yanfuchang
\ No newline at end of file
import time, json
from django.core.management import BaseCommand
from rocketmq.client import PushConsumer, ConsumeStatus
from concurrent.futures import ThreadPoolExecutor
from automated_main.models.api_automation.api_test_task import APITestTask
from automated_main.view.api_automation.api_test_task.extend.new_task_thread import TaskThread
pool = ThreadPoolExecutor(5, 'publish')
"""
以扩展命令的方式执行方法, 进行监听消息
python manage.py init_data
"""
class Command(BaseCommand):
"""
The actual logic of the command. Subclasses must implement
this method.
"""
def handle(self, *args, **options):
print(" ---- 启动发布消息监听 ---- ")
consumer = PushConsumer(group_id='GID_test_automated_group', message_model=1)
consumer.set_name_server_address('rocketmq-dev.rd.com:9876')
consumer.subscribe('test_publish_topic', callback)
consumer.start()
while True:
time.sleep(60 * 60 * 24) # 一睡就是一天
"""
监听到消息之后, 执行的回调方法
"""
def callback(msg):
try:
msg_body_str = str(msg.body, "utf-8")
body = json.loads(msg_body_str)
if not isinstance(body, dict):
print(" 非发布消息格式, 暂不处理! ")
else:
# 将消息丢到异步线程处理
task = pool.submit(do_consumer, body)
# 如果需要拿到消息结果, 则使用task.result()拿结果
# all_task.append(task)
except Exception:
return ConsumeStatus.CONSUME_SUCCESS
return ConsumeStatus.CONSUME_SUCCESS
def do_consumer(param):
# 消息内容{"projectName":"sms-base-service","moduleName":"sms-base-starter","env":"prod","branch":"master-27839-1654070365-tag","channel":"QIKE","mode":2,"defaultBranch":"prod","emailToUserList":"yanfuchang@qike366.com,chentaolian@qike366.com","publishId":4812,"publishUserName":"liubo"}
# 提取消息中的项目名称
project_name = param.get('projectName', None)
if project_name is None or project_name == '':
print(" --- 消息内容不完整, 不处理 --- ")
return
print(project_name)
task = APITestTask.objects.filter(api_test_task_name=project_name).first()
print("查询到的任务: ", json.dumps(task))
if task.status == 1:
print("当前该任务正在执行!")
return
else:
task.status = 1
task.save()
# 通过多线程运行测试任务
TaskThread(task.id).run()
print("任务开始执行!")
return
# -*- coding: utf-8 -*-
# @Time : 2020/11/10 18:30
# @Author : wangyinghao
# @FileName: __init__.py.py
# @Software: PyCharm
# -*- coding: utf-8 -*-
# @Time : 2020/11/10 18:30
# @Author : wangyinghao
# @FileName: my_middle_ware.py
# @Software: PyCharm
import traceback
from django.db import DatabaseError
from django.utils.deprecation import MiddlewareMixin
from automated_main.utils.http_format import response_failed
from automated_main.exception.my_exception import MyException, ErrorCode
# ALLOW_PATHS = ["/api/backend/users/info/", "/api/backend/users/", "/api/backend/ui_project/list/",
# "/api/backend/ui_project/", "api/backend/ui_project/<int:ui_project_id>/"]
ALLOW_PATHS = []
class MyMiddleWare(MiddlewareMixin):
def process_request(self, request): # 会捕捉所有得请求
# print('请求进来了')
current_path = request.path
if current_path not in ALLOW_PATHS:
pass
else:
user = request.user
if user.is_authenticated:
pass
else:
raise response_failed(ErrorCode.UNKNOWN, '未知错误')
pass
def process_response(self, request, response): # 会捕捉所有得响应
response["Access-Control-Allow-Origin"] = "*"
if request.method == "OPTIONS":
response["Access-Control-Allow-Headers"] = "Content-Type"
response["Access-Control-Allow-Methods"] = "DELETE, PUT, POST"
return response
def process_exception(self, request, exception): # 会捕捉到所有异常
print('捕捉异常')
print(traceback.print_exc())
if isinstance(exception, MyException):
print("这是我的错误")
code = exception.code
message = exception.message
return response_failed(code, message)
elif isinstance(exception, DatabaseError):
print('数据库错误')
return response_failed(ErrorCode.DB, '数据库错误')
else:
print('未知错误')
return response_failed(ErrorCode.UNKNOWN, '未知错误')
This diff is collapsed.
# Generated by Django 3.1.3 on 2022-08-22 10:47
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('automated_main', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='apitestplanresultassociated',
name='abnormal',
field=models.TextField(blank=True, max_length=50000, null=True, verbose_name='异常'),
),
migrations.AlterField(
model_name='apitestplanresultassociated',
name='api_body',
field=models.TextField(blank=True, max_length=500000, null=True, verbose_name='body'),
),
migrations.AlterField(
model_name='apitestplanresultassociated',
name='api_business_test_name',
field=models.TextField(blank=True, max_length=50000, null=True, verbose_name='API业务测试名称'),
),
migrations.AlterField(
model_name='apitestplanresultassociated',
name='api_header',
field=models.TextField(blank=True, max_length=50000, null=True, verbose_name='header'),
),
migrations.AlterField(
model_name='apitestplanresultassociated',
name='api_test_case_name',
field=models.CharField(default='', max_length=1000, verbose_name='api测试用例名称'),
),
migrations.AlterField(
model_name='apitestplanresultassociated',
name='api_url',
field=models.TextField(blank=True, max_length=50000, null=True, verbose_name='请求地址'),
),
migrations.AlterField(
model_name='apitestplanresultassociated',
name='api_variable_results',
field=models.TextField(blank=True, max_length=50000, null=True, verbose_name='参数提取'),
),
]
# Generated by Django 3.1.3 on 2022-08-23 19:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('automated_main', '0002_auto_20220822_1047'),
]
operations = [
migrations.AddField(
model_name='apimanagement',
name='yapi_id',
field=models.CharField(blank=True, max_length=2000, null=True, verbose_name='YAPIID'),
),
]
# -*- coding: utf-8 -*-
# @Time : 2020/12/9 14:05
# @Author : wangyinghao
# @FileName: __init__.py.py
# @Software: PyCharm
from automated_main.models.ui_automation.ui_project import UIProject
from automated_main.models.ui_automation.ui_page import UIPage
from automated_main.models.ui_automation.ui_element_positioning import UIPositioning
from automated_main.models.ui_automation.ui_element_operation import UIElementsOperation
from automated_main.models.ui_automation.ui_page_element import UIPageElement
from automated_main.models.ui_automation.ui_test_case import UITestCase, UITestCaseAssociated
from automated_main.models.ui_automation.ui_test_task import UITestTask, UITestResult
"""
8.19 弃用
"""
# from automated_main.models.api_automation.api_project import APIProject
# from automated_main.models.api_automation.api_module import APIModule
from automated_main.models.api_automation.api_environment import APIEnvironment
"""
8.19 弃用
"""
# from automated_main.models.api_automation.api_test_case import ApiTestCase
# from automated_main.models.api_automation.api_business_test import ApiBusinessTest, ApiBusinessTestAssociated
# from automated_main.models.api_automation.api_test_task import APITestTask, APITestResultAssociated, APITestResult
from automated_main.models.performance_test.performance_project import PerformanceProject
from automated_main.models.performance_test.performance_script import PerformanceScript
from automated_main.models.performance_test.performance_report import PerformanceReport
from automated_main.models.api_automation.api_database import APIDatabase
from automated_main.models.api_automation.api_management import ApiManagement
from automated_main.models.api_automation.api_interfaces_case import ApiInterfacesCase
from automated_main.models.api_automation.api_scenarios_case import ApiScenariosCaseAssociated, ApiScenariosCaseAssociated
from automated_main.models.api_automation.api_test_plan import ApiTestPlan
# -*- coding: utf-8 -*-
# @Time : 2021/3/2 18:44
# @Author : wangyinghao
# @FileName: __init__.py.py
# @Software: PyCharm
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment