demo 账号:admin,密码:123456
我们可以在 Go 语言中如何设置config
。从response_test.go
文件中的assertRunTestCases
函数中,我们可以看到一种设置方法:
- 首先,我们通过
NewConfig
函数创建一个config
对象。 - 使用
SetWeight
方法来设置负载测试中的权重,这将影响测试用例的执行频率。 - 通过
SetTimeout
方法设置请求的超时时间,确保在指定时间内完成请求。 - 使用
SetHeaders
方法来设置请求头,这可以为请求添加所需的头部信息。
通过这些步骤,我们可以对config
进行设置,以适应不同的测试需求。这种设计模式使得配置测试用例变得非常直观和灵活,可以根据具体的场景来调整参数,从而实现更加精确的测试。深入理解这些设置方法,将帮助我们在编写测试用例时更加得心应手。
func assertRunTestCases(t *testing.T) {
testcase2 := &TestCase{
Config: NewConfig("TestCase2").SetWeight(3),
}
testcase3 := &TestCase{
Config: NewConfig("TestCase3").SetWeight(3).SetTimeout(10).SetHeaders(map[string]string{"project":"扬帆"}),
}
}
上述的写法属于链式调用,这种写法允许在同一个对象上连续调用多个方法,每个方法的返回值是对象本身的地址引用,从而可以在后续调用中继续使用其他方法。这样的设计使得代码更加简洁和易读。除了config
,在测试步骤的Step
中也广泛使用了链式调用。
为了更好地理解链式调用,我们可以通过一个简单的例子来说明。假设我们有一个名为IntList
的结构体,它具有Add
、Double
和Print
等方法,同时每个方法都返回 IntList 对象的地址引用。
当我们调用IntList.Add(1).Add(2).Add(3).Double().Print()
时,实际上是在同一个IntList
对象上连续调用了三个方法。每个方法的返回值都是该对象的地址引用,所以我们可以在每个方法调用后继续调用下一个方法。
这种设计方式在代码编写和阅读时都非常方便,能够使代码更加紧凑、易读,也减少了临时变量的使用。理解链式调用的核心是每个方法都返回对象本身的地址引用,使得后续方法可以继续在同一个对象上调用。
package main
import (
"fmt"
)
// IntList 表示一个整数切片。
type IntList struct {
data []int
}
// Add 向 IntList 中添加一个新元素。
func (l *IntList) Add(num int) *IntList {
l.data = append(l.data, num)
return l
}
// Double 将 IntList 中所有元素乘以 2。
func (l *IntList) Double() *IntList {
for i := range l.data {
l.data[i] *= 2
}
return l
}
// Print 打印 IntList 中的元素。
func (l *IntList) Print() *IntList {
fmt.Println(l.data)
return l
}
func main() {
// 创建 IntList 并进行链式调用。
IntList := &IntList{}
IntList.Add(1).Add(2).Add(3).Double().Print()
}
在上述例子中,我们实现了链式调用,其中关键之处在于每个方法的返回值都是当前对象的指针。在配置中,以及用例的编写中,我们同样使用了链式调用的方式。这种方式在直接编写用例时非常方便,能够让代码更易于理解和编写。
如果我们在平台化的环境中操作,可以根据具体情况决定是否采用链式调用。在用例内部,数据可以被转换成用例格式,因此链式调用并非必须。然而,如果我们进行二次开发,也可以根据具体方案来灵活实现链式调用的需求。
在理解了链式调用方法后,我们可以进一步审视配置的内容。基本上,公共配置是相同的,而不同类型的用例(如http
、websocket
、ui
等)的特定配置存放在配置中。在未来,我们还可以考虑将MQTT
协议的发布者和订阅者实例放置在这个位置。这种统一的配置方式有助于管理和维护各种不同类型的用例,使得整个框架更加灵活和可扩展。
-
Name string
: 测试用例的名称,必需字段。 -
Verify bool
:https
证书验证参数,可选字段。 -
BaseURL string
: 基础 URL,在v4.1
版本已废弃,已被移动到Environs
字段中,可选字段。 -
Headers map[string]string
: 公共请求头信息,键值对形式的字符串映射,可选字段。 -
Environs map[string]string
: 环境变量,键值对形式的字符串映射,可选字段。 -
Variables map[string]interface{}
: 全局变量,键值对形式的任意类型映射,可选字段。 -
Parameters map[string]interface{}
: 参数,键值对形式的任意类型映射,可选字段。 -
ParametersSetting *TParamsConfig
: 参数设置,一个指向TParamsConfig
类型的指针,可选字段。 -
ThinkTimeSetting *ThinkTimeConfig
: 思考时间设置,一个指向ThinkTimeConfig
类型的指针,可选字段。 -
WebSocketSetting *WebSocketConfig
:WebSocket
设置,一个指向WebSocketConfig
类型的指针,可选字段。 -
IOS []*uixt.IOSDevice
:iOS
设备配置,一个uixt.IOSDevice
类型的切片,可选字段。 -
Android []*uixt.AndroidDevice
:Android
设备配置,一个uixt.AndroidDevice
类型的切片,可选字段。 -
Timeout float64
: 全局超时时间(单位:秒),可选字段。 -
Export []string
: 导出配置,一个字符串切片,可选字段。 -
Weight int
: 权重,一个整数,可选字段。 -
Path string
: 测试用例文件路径,可选字段。 -
PluginSetting *PluginConfig
: 插件配置,一个指向PluginConfig
类型的指针,可选字段。
// TConfig represents config data structure for testcase.
// Each testcase should contain one config part.
type TConfig struct {
Name string `json:"name" yaml:"name"` // required
Verify bool `json:"verify,omitempty" yaml:"verify,omitempty"`
BaseURL string `json:"base_url,omitempty" yaml:"base_url,omitempty"` // deprecated in v4.1, moved to env
Headers map[string]string `json:"headers,omitempty" yaml:"headers,omitempty"` // public request headers
Environs map[string]string `json:"environs,omitempty" yaml:"environs,omitempty"` // environment variables
Variables map[string]interface{} `json:"variables,omitempty" yaml:"variables,omitempty"` // global variables
Parameters map[string]interface{} `json:"parameters,omitempty" yaml:"parameters,omitempty"`
ParametersSetting *TParamsConfig `json:"parameters_setting,omitempty" yaml:"parameters_setting,omitempty"`
ThinkTimeSetting *ThinkTimeConfig `json:"think_time,omitempty" yaml:"think_time,omitempty"`
WebSocketSetting *WebSocketConfig `json:"websocket,omitempty" yaml:"websocket,omitempty"`
IOS []*uixt.IOSDevice `json:"ios,omitempty" yaml:"ios,omitempty"`
Android []*uixt.AndroidDevice `json:"android,omitempty" yaml:"android,omitempty"`
Timeout float64 `json:"timeout,omitempty" yaml:"timeout,omitempty"` // global timeout in seconds
Export []string `json:"export,omitempty" yaml:"export,omitempty"`
Weight int `json:"weight,omitempty" yaml:"weight,omitempty"`
Path string `json:"path,omitempty" yaml:"path,omitempty"` // testcase file path
PluginSetting *PluginConfig `json:"plugin,omitempty" yaml:"plugin,omitempty"` // plugin config
}
配置的实现相对简单,我们可以定义一个结构体,并将需要在后续调用中使用的内容存储在配置中。通过使用链式调用的方法,我们可以为配置中的每个字段进行赋值。
在这种设计下,如果未来我们要增加MQTT
协议的支持,只需要在配置中增加与MQTT
相关的数据即可。
这种统一的配置方式使得我们可以更加灵活地管理不同类型的用例,而且通过链式调用的方式为配置赋值,使得代码更加清晰、易读,也方便后续的拓展和修改。这种设计模式在使得整个框架更加模块化和可扩展的同时,也为后续的功能添加提供了更加便捷的方式。