feat(接口定义): 完成JDBC快捷调试
This commit is contained in:
parent
948fcdb3b8
commit
2ba69e9a32
|
@ -14,7 +14,6 @@ import org.apache.jmeter.protocol.jdbc.sampler.JDBCSampler;
|
|||
import org.apache.jmeter.save.SaveService;
|
||||
import org.apache.jmeter.testelement.TestElement;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
import org.apache.jorphan.collections.ListedHashTree;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
@ -40,10 +39,9 @@ public class MsJDBCSampler extends MsTestElement {
|
|||
private String environmentId;
|
||||
|
||||
public void toHashTree(HashTree tree, List<MsTestElement> hashTree) {
|
||||
final HashTree samplerHashTree = new ListedHashTree();
|
||||
samplerHashTree.add(jdbcDataSource());
|
||||
samplerHashTree.add(arguments(this.getName() + " Variables", this.getVariables()));
|
||||
tree.set(jdbcSampler(), samplerHashTree);
|
||||
final HashTree samplerHashTree = tree.add(jdbcSampler());
|
||||
tree.add(jdbcDataSource());
|
||||
tree.add(arguments(this.getName() + " Variables", this.getVariables()));
|
||||
if (CollectionUtils.isNotEmpty(hashTree)) {
|
||||
hashTree.forEach(el -> {
|
||||
el.toHashTree(samplerHashTree, el.getHashTree());
|
||||
|
@ -53,6 +51,7 @@ public class MsJDBCSampler extends MsTestElement {
|
|||
|
||||
private Arguments arguments(String name, List<KeyValue> variables) {
|
||||
Arguments arguments = new Arguments();
|
||||
if (!variables.isEmpty()) {
|
||||
arguments.setEnabled(true);
|
||||
arguments.setName(name);
|
||||
arguments.setProperty(TestElement.TEST_CLASS, Arguments.class.getName());
|
||||
|
@ -60,6 +59,7 @@ public class MsJDBCSampler extends MsTestElement {
|
|||
variables.stream().filter(KeyValue::isValid).filter(KeyValue::isEnable).forEach(keyValue ->
|
||||
arguments.addArgument(keyValue.getName(), keyValue.getValue(), "=")
|
||||
);
|
||||
}
|
||||
return arguments;
|
||||
}
|
||||
|
||||
|
@ -69,13 +69,13 @@ public class MsJDBCSampler extends MsTestElement {
|
|||
sampler.setProperty(TestElement.TEST_CLASS, JDBCSampler.class.getName());
|
||||
sampler.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TestBeanGUI"));
|
||||
// request.getDataSource() 是ID,需要转换为Name
|
||||
sampler.setDataSource(this.dataSource.getName());
|
||||
sampler.setQuery(this.getQuery());
|
||||
sampler.setQueryTimeout(String.valueOf(this.getQueryTimeout()));
|
||||
sampler.setResultVariable(this.getResultVariable());
|
||||
sampler.setVariableNames(this.getVariableNames());
|
||||
sampler.setResultSetHandler("Store as String");
|
||||
sampler.setQueryType("Callable Statement");
|
||||
sampler.setProperty("dataSource", this.dataSource.getName());
|
||||
sampler.setProperty("query", this.getQuery());
|
||||
sampler.setProperty("queryTimeout", String.valueOf(this.getQueryTimeout()));
|
||||
sampler.setProperty("resultVariable", this.getResultVariable());
|
||||
sampler.setProperty("variableNames", this.getVariableNames());
|
||||
sampler.setProperty("resultSetHandler", "Store as String");
|
||||
sampler.setProperty("queryType", "Callable Statement");
|
||||
return sampler;
|
||||
}
|
||||
|
||||
|
@ -85,19 +85,19 @@ public class MsJDBCSampler extends MsTestElement {
|
|||
dataSourceElement.setName(this.getName() + " JDBCDataSource");
|
||||
dataSourceElement.setProperty(TestElement.TEST_CLASS, DataSourceElement.class.getName());
|
||||
dataSourceElement.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass("TestBeanGUI"));
|
||||
dataSourceElement.setAutocommit(true);
|
||||
dataSourceElement.setKeepAlive(true);
|
||||
dataSourceElement.setPreinit(true);
|
||||
dataSourceElement.setDataSource(dataSource.getName());
|
||||
dataSourceElement.setDbUrl(dataSource.getDbUrl());
|
||||
dataSourceElement.setDriver(dataSource.getDriver());
|
||||
dataSourceElement.setUsername(dataSource.getUsername());
|
||||
dataSourceElement.setPassword(dataSource.getPassword());
|
||||
dataSourceElement.setPoolMax(String.valueOf(dataSource.getPoolMax()));
|
||||
dataSourceElement.setTimeout(String.valueOf(dataSource.getTimeout()));
|
||||
dataSourceElement.setConnectionAge("5000");
|
||||
dataSourceElement.setTrimInterval("60000");
|
||||
dataSourceElement.setTransactionIsolation("DEFAULT");
|
||||
dataSourceElement.setProperty("autocommit", true);
|
||||
dataSourceElement.setProperty("keepAlive", true);
|
||||
dataSourceElement.setProperty("preinit", false);
|
||||
dataSourceElement.setProperty("dataSource", dataSource.getName());
|
||||
dataSourceElement.setProperty("dbUrl", dataSource.getDbUrl());
|
||||
dataSourceElement.setProperty("driver", dataSource.getDriver());
|
||||
dataSourceElement.setProperty("username", dataSource.getUsername());
|
||||
dataSourceElement.setProperty("password", dataSource.getPassword());
|
||||
dataSourceElement.setProperty("poolMax", dataSource.getPoolMax());
|
||||
dataSourceElement.setProperty("timeout", String.valueOf(dataSource.getTimeout()));
|
||||
dataSourceElement.setProperty("connectionAge", 5000);
|
||||
dataSourceElement.setProperty("trimInterval", 6000);
|
||||
dataSourceElement.setProperty("transactionIsolation", "DEFAULT");
|
||||
return dataSourceElement;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,7 +96,6 @@
|
|||
this.runData.forEach(item => {
|
||||
threadGroup.hashTree.push(item);
|
||||
})
|
||||
console.log(testPlan)
|
||||
let reqObj = {id: this.reportId, testElement: testPlan};
|
||||
let bodyFiles = this.getBodyUploadFiles(reqObj);
|
||||
let url = "";
|
||||
|
|
|
@ -12,12 +12,12 @@
|
|||
|
||||
<p class="tip">{{$t('api_test.definition.request.req_param')}} </p>
|
||||
<!-- HTTP 请求参数 -->
|
||||
<ms-basis-parameters :request="request" :currentProject="currentProject"/>
|
||||
<ms-basis-parameters :request="request" @callback="runDebug" :currentProject="currentProject" ref="requestForm"/>
|
||||
|
||||
|
||||
<!-- HTTP 请求返回数据 -->
|
||||
<p class="tip">{{$t('api_test.definition.request.res_param')}} </p>
|
||||
<ms-request-result-tail :response="responseData" ref="debugResult"/>
|
||||
<ms-request-result-tail :response="responseData" :currentProtocol="currentProtocol" ref="debugResult"/>
|
||||
|
||||
<!-- 执行组件 -->
|
||||
<ms-run :debug="true" :reportId="reportId" :run-data="runData" @runRefresh="runRefresh" ref="runTest"/>
|
||||
|
@ -64,20 +64,7 @@
|
|||
}
|
||||
},
|
||||
created() {
|
||||
switch (this.currentProtocol) {
|
||||
case Request.TYPES.SQL:
|
||||
this.request = createComponent("JDBCSampler");
|
||||
break;
|
||||
case Request.TYPES.DUBBO:
|
||||
this.request = createComponent("JDBCSampler");
|
||||
break;
|
||||
case Request.TYPES.TCP:
|
||||
this.request = createComponent("TCPSampler");
|
||||
break;
|
||||
default:
|
||||
this.createHttp();
|
||||
break;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
debugResultId() {
|
||||
|
@ -89,14 +76,10 @@
|
|||
if (e === "save_as") {
|
||||
this.saveAs();
|
||||
} else {
|
||||
this.runDebug();
|
||||
this.$refs['requestForm'].validate();
|
||||
}
|
||||
},
|
||||
createHttp() {
|
||||
let header = createComponent("HeaderManager");
|
||||
this.request = createComponent("HTTPSamplerProxy");
|
||||
this.request.hashTree = [header];
|
||||
},
|
||||
|
||||
runDebug() {
|
||||
this.loading = true;
|
||||
this.request.name = getUUID().substring(0, 8);
|
||||
|
@ -111,18 +94,8 @@
|
|||
this.$refs.debugResult.reload();
|
||||
},
|
||||
saveAs() {
|
||||
this.$refs['debugForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.debugForm.request = JSON.stringify(this.request);
|
||||
this.debugForm.userId = getCurrentUser().id;
|
||||
this.debugForm.status = "Underway";
|
||||
this.debugForm.protocol = this.currentProtocol;
|
||||
this.$emit('saveAs', this.debugForm);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
let obj = {request: JSON.stringify(this.request)};
|
||||
this.$emit('saveAs', obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<el-row>
|
||||
<el-col :span="21" style="padding-bottom: 50px">
|
||||
<div style="border:1px #DCDFE6 solid; height: 100%;border-radius: 4px ;width: 100% ;margin: 20px">
|
||||
<el-form :model="request" ref="request" label-width="100px" :disabled="isReadOnly" style="margin: 20px">
|
||||
<el-form :model="request" :rules="rules" ref="request" label-width="100px" :disabled="isReadOnly" style="margin: 20px">
|
||||
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
|
@ -131,6 +131,10 @@
|
|||
databaseConfigsOptions: [],
|
||||
isReloadData: false,
|
||||
activeName: "variables",
|
||||
rules: {
|
||||
environmentId: [{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}],
|
||||
dataSource: [{required: true, message: this.$t('api_test.request.sql.dataSource'), trigger: 'change'}],
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
@ -168,12 +172,16 @@
|
|||
this.isReloadData = false
|
||||
})
|
||||
},
|
||||
validateApi() {
|
||||
validate() {
|
||||
if (this.currentProject === null) {
|
||||
this.$error(this.$t('api_test.select_project'), 2000);
|
||||
return;
|
||||
}
|
||||
this.$refs['basicForm'].validate();
|
||||
this.$refs['request'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.$emit('callback');
|
||||
}
|
||||
})
|
||||
},
|
||||
saveApi() {
|
||||
this.basisData.method = this.basisData.protocol;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="request-result">
|
||||
<ms-request-metric :response="response"/>
|
||||
<ms-response-result :response="response"/>
|
||||
<ms-response-result :currentProtocol="currentProtocol" :response="response"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
|||
components: {MsRequestMetric, MsResponseResult},
|
||||
props: {
|
||||
response: Object,
|
||||
currentProtocol: String,
|
||||
},
|
||||
|
||||
data() {
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
<pre>{{ response.responseResult.headers }}</pre>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('api_test.definition.request.response_body')" name="body" class="pane">
|
||||
<ms-code-edit :mode="mode" :read-only="true" :modes="modes" :data.sync="response.responseResult.body" ref="codeEdit"/>
|
||||
<ms-sql-result-table v-if="isSqlType" :body="response.responseResult.body"/>
|
||||
<ms-code-edit v-if="!isSqlType" :mode="mode" :read-only="true" :modes="modes" :data.sync="response.responseResult.body" ref="codeEdit"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="Cookie" name="cookie" class="pane cookie">
|
||||
<pre>{{response.cookies}}</pre>
|
||||
|
@ -27,7 +28,9 @@
|
|||
|
||||
<el-tab-pane v-if="activeName == 'body'" :disabled="true" name="mode" class="pane cookie">
|
||||
<template v-slot:label>
|
||||
<ms-dropdown :commands="modes" :default-command="mode" @command="modeChange"/>
|
||||
<ms-dropdown v-if="currentProtocol==='SQL'" :commands="sqlModes" :default-command="mode" @command="sqlModeChange"/>
|
||||
<ms-dropdown v-else :commands="modes" :default-command="mode" @command="modeChange"/>
|
||||
|
||||
</template>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
@ -39,6 +42,7 @@
|
|||
import MsCodeEdit from "../MsCodeEdit";
|
||||
import MsDropdown from "../../../../common/components/MsDropdown";
|
||||
import {BODY_FORMAT} from "../../model/ApiTestModel";
|
||||
import MsSqlResultTable from "./SqlResultTable";
|
||||
|
||||
export default {
|
||||
name: "MsResponseResult",
|
||||
|
@ -47,10 +51,12 @@
|
|||
MsDropdown,
|
||||
MsCodeEdit,
|
||||
MsAssertionResults,
|
||||
MsSqlResultTable
|
||||
},
|
||||
|
||||
props: {
|
||||
response: Object,
|
||||
currentProtocol: String,
|
||||
},
|
||||
|
||||
data() {
|
||||
|
@ -58,12 +64,16 @@
|
|||
isActive: true,
|
||||
activeName: "headers",
|
||||
modes: ['text', 'json', 'xml', 'html'],
|
||||
sqlModes: ['text', 'table'],
|
||||
mode: BODY_FORMAT.TEXT
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
modeChange(mode) {
|
||||
this.mode = mode;
|
||||
},
|
||||
sqlModeChange(mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
@ -73,6 +83,11 @@
|
|||
if (this.response.headers.indexOf("Content-Type: application/json") > 0) {
|
||||
this.mode = BODY_FORMAT.JSON;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isSqlType() {
|
||||
return (this.currentProtocol === "SQL" && this.response.responseResult.responseCode === '200' && this.mode ==='table');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-table
|
||||
v-for="(table, index) in tables"
|
||||
:key="index"
|
||||
:data="table.tableData"
|
||||
border
|
||||
size="mini"
|
||||
highlight-current-row>
|
||||
<el-table-column v-for="(title, index) in table.titles" :key="index" :label="title" min-width="150px">
|
||||
<template v-slot:default="scope">
|
||||
<el-popover
|
||||
placement="top"
|
||||
trigger="click">
|
||||
<el-container>
|
||||
<div>{{ scope.row[title] }}</div>
|
||||
</el-container>
|
||||
<span class="table-content" slot="reference">{{ scope.row[title] }}</span>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "MsSqlResultTable",
|
||||
data() {
|
||||
return {
|
||||
tables: [],
|
||||
titles: []
|
||||
}
|
||||
},
|
||||
props: {
|
||||
body: String
|
||||
},
|
||||
created() {
|
||||
if (!this.body) {
|
||||
return;
|
||||
}
|
||||
let rowArry = this.body.split("\n");
|
||||
this.getTableData(rowArry);
|
||||
if (this.tables.length > 1) {
|
||||
for (let i = 0; i < this.tables.length; i++) {
|
||||
if (this.tables[i].titles.length === 1 && i < this.tables.length - 1) {
|
||||
this.tables[i].tableData.splice(this.tables[i].tableData.length - 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
let lastTable = this.tables[this.tables.length - 1];
|
||||
if (lastTable.titles.length === 1) {
|
||||
if (lastTable.tableData.length > 4) {
|
||||
lastTable.tableData.splice(lastTable.tableData.length - 4, 4);
|
||||
} else {
|
||||
this.tables.splice(this.tables.length - 1, 1);
|
||||
}
|
||||
} else {
|
||||
this.tables.splice(this.tables.length - 1, 1);
|
||||
}
|
||||
} else {
|
||||
let table = this.tables[0];
|
||||
table.tableData.splice(table.tableData.length - 4, 4);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getTableData(rowArry) {
|
||||
let titles;
|
||||
let result = [];
|
||||
for (let i = 0; i < rowArry.length; i++) {
|
||||
let colArray = rowArry[i].split("\t");
|
||||
if (i === 0) {
|
||||
titles = colArray;
|
||||
} else {
|
||||
if (colArray.length != titles.length) {
|
||||
// 创建新的表
|
||||
if (colArray.length === 1 && colArray[0] === '') {
|
||||
this.getTableData(rowArry.slice(i + 1));
|
||||
} else {
|
||||
this.getTableData(rowArry.slice(i));
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
let item = {};
|
||||
for (let j = 0; j < colArray.length; j++) {
|
||||
item[titles[j]] = (colArray[j] ? colArray[j] : "");
|
||||
}
|
||||
result.push(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.tables.splice(0, 0, {
|
||||
titles: titles,
|
||||
tableData: result
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.el-table {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.el-table >>> .cell {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.table-content {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.el-container {
|
||||
overflow:auto;
|
||||
max-height: 500px;
|
||||
}
|
||||
|
||||
</style>
|
Loading…
Reference in New Issue