Some checks failed
CI/CD Pipeline / Test (push) Failing after 22m19s
CI/CD Pipeline / Security Scan (push) Failing after 5m57s
CI/CD Pipeline / Build (amd64, darwin) (push) Has been skipped
CI/CD Pipeline / Build (amd64, linux) (push) Has been skipped
CI/CD Pipeline / Build (amd64, windows) (push) Has been skipped
CI/CD Pipeline / Build (arm64, darwin) (push) Has been skipped
CI/CD Pipeline / Build (arm64, linux) (push) Has been skipped
CI/CD Pipeline / Build Docker Image (push) Has been skipped
CI/CD Pipeline / Create Release (push) Has been skipped
798 lines
21 KiB
Go
798 lines
21 KiB
Go
package testing
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"time"
|
||
)
|
||
|
||
// TestStatus 定义测试状态
|
||
type TestStatus int
|
||
|
||
const (
|
||
PENDING TestStatus = iota
|
||
RUNNING
|
||
PASSED
|
||
FAILED
|
||
SKIPPED
|
||
TIMEOUT
|
||
)
|
||
|
||
// TestType 定义测试类型
|
||
type TestType int
|
||
|
||
const (
|
||
UNIT TestType = iota
|
||
INTEGRATION
|
||
CONTRACT
|
||
PERFORMANCE
|
||
SECURITY
|
||
LOAD
|
||
)
|
||
|
||
// TestPriority 定义测试优先级
|
||
type TestPriority int
|
||
|
||
const (
|
||
LOW TestPriority = iota
|
||
MEDIUM
|
||
HIGH
|
||
CRITICAL
|
||
)
|
||
|
||
// TestCase 表示测试用例的结构
|
||
// 该结构体包含测试用例的所有信息,包括输入、期望输出、执行状态等
|
||
type TestCase struct {
|
||
// 基本信息字段
|
||
ID string `json:"id" yaml:"id"`
|
||
Name string `json:"name" yaml:"name"`
|
||
Description string `json:"description" yaml:"description"`
|
||
Type TestType `json:"type" yaml:"type"`
|
||
Priority TestPriority `json:"priority" yaml:"priority"`
|
||
Category string `json:"category" yaml:"category"`
|
||
Subsystem string `json:"subsystem" yaml:"subsystem"`
|
||
Tags []string `json:"tags" yaml:"tags"`
|
||
|
||
// 测试数据字段
|
||
Input interface{} `json:"input" yaml:"input"`
|
||
Expectation interface{} `json:"expectation" yaml:"expectation"`
|
||
Config interface{} `json:"config" yaml:"config"`
|
||
Preconditions []string `json:"preconditions" yaml:"preconditions"`
|
||
Postconditions []string `json:"postconditions" yaml:"postconditions"`
|
||
|
||
// 执行信息字段
|
||
Status TestStatus `json:"status" yaml:"status"`
|
||
StartedAt time.Time `json:"started_at" yaml:"started_at"`
|
||
CompletedAt time.Time `json:"completed_at" yaml:"completed_at"`
|
||
Duration time.Duration `json:"duration" yaml:"duration"`
|
||
Attempts int `json:"attempts" yaml:"attempts"`
|
||
MaxAttempts int `json:"max_attempts" yaml:"max_attempts"`
|
||
Timeout time.Duration `json:"timeout" yaml:"timeout"`
|
||
|
||
// 结果字段
|
||
ActualResult interface{} `json:"actual_result" yaml:"actual_result"`
|
||
Error error `json:"error" yaml:"error"`
|
||
ErrorType string `json:"error_type" yaml:"error_type"`
|
||
ErrorDetail string `json:"error_detail" yaml:"error_detail"`
|
||
ErrorMessage string `json:"error_message" yaml:"error_message"`
|
||
|
||
// 依赖和排除字段
|
||
Dependencies []string `json:"dependencies" yaml:"dependencies"`
|
||
Exclusions []string `json:"exclusions" yaml:"exclusions"`
|
||
RunIf string `json:"run_if" yaml:"run_if"`
|
||
SkipIf string `json:"skip_if" yaml:"skip_if"`
|
||
|
||
// 性能指标字段
|
||
PerformanceMetrics map[string]interface{} `json:"performance_metrics" yaml:"performance_metrics"`
|
||
MemoryUsage int64 `json:"memory_usage" yaml:"memory_usage"`
|
||
CPUUsage float64 `json:"cpu_usage" yaml:"cpu_usage"`
|
||
Throughput float64 `json:"throughput" yaml:"throughput"`
|
||
|
||
// 元数据字段
|
||
CreatedBy string `json:"created_by" yaml:"created_by"`
|
||
CreatedAt time.Time `json:"created_at" yaml:"created_at"`
|
||
UpdatedAt time.Time `json:"updated_at" yaml:"updated_at"`
|
||
Version string `json:"version" yaml:"version"`
|
||
Documentation string `json:"documentation" yaml:"documentation"`
|
||
|
||
// 自定义字段
|
||
Custom map[string]interface{} `json:"custom,omitempty" yaml:"custom,omitempty"`
|
||
Attachments []TestAttachment `json:"attachments,omitempty" yaml:"attachments,omitempty"`
|
||
Parameters map[string]interface{} `json:"parameters,omitempty" yaml:"parameters,omitempty"`
|
||
}
|
||
|
||
// TestAttachment 测试附件
|
||
type TestAttachment struct {
|
||
Name string `json:"name" yaml:"name"`
|
||
Type string `json:"type" yaml:"type"`
|
||
Path string `json:"path" yaml:"path"`
|
||
Size int64 `json:"size" yaml:"size"`
|
||
Description string `json:"description" yaml:"description"`
|
||
}
|
||
|
||
// NewTestCase 创建新的测试用例
|
||
// 返回包含基本信息的TestCase结构体
|
||
func NewTestCase(id, name string, testType TestType) *TestCase {
|
||
now := time.Now()
|
||
return &TestCase{
|
||
ID: id,
|
||
Name: name,
|
||
Type: testType,
|
||
Priority: MEDIUM,
|
||
Status: PENDING,
|
||
Tags: make([]string, 0),
|
||
Preconditions: make([]string, 0),
|
||
Postconditions: make([]string, 0),
|
||
Dependencies: make([]string, 0),
|
||
Exclusions: make([]string, 0),
|
||
Attachments: make([]TestAttachment, 0),
|
||
MaxAttempts: 1,
|
||
CreatedAt: now,
|
||
UpdatedAt: now,
|
||
PerformanceMetrics: make(map[string]interface{}),
|
||
Custom: make(map[string]interface{}),
|
||
Parameters: make(map[string]interface{}),
|
||
}
|
||
}
|
||
|
||
// NewUnitTest 创建单元测试用例
|
||
// 返回配置好的单元测试用例实例
|
||
func NewUnitTest(id, name string) *TestCase {
|
||
return NewTestCase(id, name, UNIT).
|
||
SetCategory("unit").
|
||
SetSubsystem("core").
|
||
SetTimeout(30 * time.Second)
|
||
}
|
||
|
||
// NewIntegrationTest 创建集成测试用例
|
||
// 返回配置好的集成测试用例实例
|
||
func NewIntegrationTest(id, name string) *TestCase {
|
||
return NewTestCase(id, name, INTEGRATION).
|
||
SetCategory("integration").
|
||
SetSubsystem("system").
|
||
SetTimeout(120 * time.Second).
|
||
SetMaxAttempts(3)
|
||
}
|
||
|
||
// NewContractTest 创建契约测试用例
|
||
// 返回配置好的契约测试用例实例
|
||
func NewContractTest(id, name string) *TestCase {
|
||
return NewTestCase(id, name, CONTRACT).
|
||
SetCategory("contract").
|
||
SetSubsystem("api").
|
||
SetTimeout(60 * time.Second)
|
||
}
|
||
|
||
// NewPerformanceTest 创建性能测试用例
|
||
// 返回配置好的性能测试用例实例
|
||
func NewPerformanceTest(id, name string) *TestCase {
|
||
return NewTestCase(id, name, PERFORMANCE).
|
||
SetCategory("performance").
|
||
SetSubsystem("performance").
|
||
SetTimeout(300 * time.Second).
|
||
AddPerformanceMetric("max_response_time", 1000.0).
|
||
AddPerformanceMetric("max_memory_usage", 100*1024*1024) // 100MB
|
||
}
|
||
|
||
// SetInput 设置测试输入数据
|
||
// 返回更新后的TestCase实例
|
||
func (tc *TestCase) SetInput(input interface{}) *TestCase {
|
||
tc.Input = input
|
||
tc.UpdatedAt = time.Now()
|
||
return tc
|
||
}
|
||
|
||
// SetExpectation 设置测试期望结果
|
||
// 返回更新后的TestCase实例
|
||
func (tc *TestCase) SetExpectation(expectation interface{}) *TestCase {
|
||
tc.Expectation = expectation
|
||
tc.UpdatedAt = time.Now()
|
||
return tc
|
||
}
|
||
|
||
// SetConfig 设置测试配置
|
||
// 返回更新后的TestCase实例
|
||
func (tc *TestCase) SetConfig(config interface{}) *TestCase {
|
||
tc.Config = config
|
||
tc.UpdatedAt = time.Now()
|
||
return tc
|
||
}
|
||
|
||
// AddPrecondition 添加前置条件
|
||
// 返回更新后的TestCase实例
|
||
func (tc *TestCase) AddPrecondition(condition string) *TestCase {
|
||
tc.Preconditions = append(tc.Preconditions, condition)
|
||
tc.UpdatedAt = time.Now()
|
||
return tc
|
||
}
|
||
|
||
// AddPostcondition 添加后置条件
|
||
// 返回更新后的TestCase实例
|
||
func (tc *TestCase) AddPostcondition(condition string) *TestCase {
|
||
tc.Postconditions = append(tc.Postconditions, condition)
|
||
tc.UpdatedAt = time.Now()
|
||
return tc
|
||
}
|
||
|
||
// AddTag 添加标签
|
||
// 返回更新后的TestCase实例
|
||
func (tc *TestCase) AddTag(tag string) *TestCase {
|
||
tc.Tags = append(tc.Tags, tag)
|
||
tc.UpdatedAt = time.Now()
|
||
return tc
|
||
}
|
||
|
||
// AddTags 添加多个标签
|
||
// 返回更新后的TestCase实例
|
||
func (tc *TestCase) AddTags(tags ...string) *TestCase {
|
||
tc.Tags = append(tc.Tags, tags...)
|
||
tc.UpdatedAt = time.Now()
|
||
return tc
|
||
}
|
||
|
||
// AddDependency 添加依赖测试
|
||
// 返回更新后的TestCase实例
|
||
func (tc *TestCase) AddDependency(dependency string) *TestCase {
|
||
tc.Dependencies = append(tc.Dependencies, dependency)
|
||
tc.UpdatedAt = time.Now()
|
||
return tc
|
||
}
|
||
|
||
// AddExclusion 添加排除条件
|
||
// 返回更新后的TestCase实例
|
||
func (tc *TestCase) AddExclusion(exclusion string) *TestCase {
|
||
tc.Exclusions = append(tc.Exclusions, exclusion)
|
||
tc.UpdatedAt = time.Now()
|
||
return tc
|
||
}
|
||
|
||
// SetPriority 设置优先级
|
||
// 返回更新后的TestCase实例
|
||
func (tc *TestCase) SetPriority(priority TestPriority) *TestCase {
|
||
tc.Priority = priority
|
||
tc.UpdatedAt = time.Now()
|
||
return tc
|
||
}
|
||
|
||
// SetTimeout 设置超时时间
|
||
// 返回更新后的TestCase实例
|
||
func (tc *TestCase) SetTimeout(timeout time.Duration) *TestCase {
|
||
tc.Timeout = timeout
|
||
tc.UpdatedAt = time.Now()
|
||
return tc
|
||
}
|
||
|
||
// SetMaxAttempts 设置最大重试次数
|
||
// 返回更新后的TestCase实例
|
||
func (tc *TestCase) SetMaxAttempts(maxAttempts int) *TestCase {
|
||
tc.MaxAttempts = maxAttempts
|
||
tc.UpdatedAt = time.Now()
|
||
return tc
|
||
}
|
||
|
||
// SetCategory 设置分类
|
||
// 返回更新后的TestCase实例
|
||
func (tc *TestCase) SetCategory(category string) *TestCase {
|
||
tc.Category = category
|
||
tc.UpdatedAt = time.Now()
|
||
return tc
|
||
}
|
||
|
||
// SetSubsystem 设置子系统
|
||
// 返回更新后的TestCase实例
|
||
func (tc *TestCase) SetSubsystem(subsystem string) *TestCase {
|
||
tc.Subsystem = subsystem
|
||
tc.UpdatedAt = time.Now()
|
||
return tc
|
||
}
|
||
|
||
// SetDescription 设置描述
|
||
// 返回更新后的TestCase实例
|
||
func (tc *TestCase) SetDescription(description string) *TestCase {
|
||
tc.Description = description
|
||
tc.UpdatedAt = time.Now()
|
||
return tc
|
||
}
|
||
|
||
// SetRunIf 设置运行条件
|
||
// 返回更新后的TestCase实例
|
||
func (tc *TestCase) SetRunIf(runIf string) *TestCase {
|
||
tc.RunIf = runIf
|
||
tc.UpdatedAt = time.Now()
|
||
return tc
|
||
}
|
||
|
||
// SetSkipIf 设置跳过条件
|
||
// 返回更新后的TestCase实例
|
||
func (tc *TestCase) SetSkipIf(skipIf string) *TestCase {
|
||
tc.SkipIf = skipIf
|
||
tc.UpdatedAt = time.Now()
|
||
return tc
|
||
}
|
||
|
||
// AddParameter 添加参数
|
||
// 返回更新后的TestCase实例
|
||
func (tc *TestCase) AddParameter(key string, value interface{}) *TestCase {
|
||
if tc.Parameters == nil {
|
||
tc.Parameters = make(map[string]interface{})
|
||
}
|
||
tc.Parameters[key] = value
|
||
tc.UpdatedAt = time.Now()
|
||
return tc
|
||
}
|
||
|
||
// AddPerformanceMetric 添加性能指标
|
||
// 返回更新后的TestCase实例
|
||
func (tc *TestCase) AddPerformanceMetric(key string, value interface{}) *TestCase {
|
||
if tc.PerformanceMetrics == nil {
|
||
tc.PerformanceMetrics = make(map[string]interface{})
|
||
}
|
||
tc.PerformanceMetrics[key] = value
|
||
tc.UpdatedAt = time.Now()
|
||
return tc
|
||
}
|
||
|
||
// AddCustom 添加自定义字段
|
||
// 返回更新后的TestCase实例
|
||
func (tc *TestCase) AddCustom(key string, value interface{}) *TestCase {
|
||
if tc.Custom == nil {
|
||
tc.Custom = make(map[string]interface{})
|
||
}
|
||
tc.Custom[key] = value
|
||
tc.UpdatedAt = time.Now()
|
||
return tc
|
||
}
|
||
|
||
// AddAttachment 添加附件
|
||
// 返回更新后的TestCase实例
|
||
func (tc *TestCase) AddAttachment(name, attachmentType, path string, size int64, description string) *TestCase {
|
||
tc.Attachments = append(tc.Attachments, TestAttachment{
|
||
Name: name,
|
||
Type: attachmentType,
|
||
Path: path,
|
||
Size: size,
|
||
Description: description,
|
||
})
|
||
tc.UpdatedAt = time.Now()
|
||
return tc
|
||
}
|
||
|
||
// Start 开始执行测试
|
||
// 标记测试为运行状态,记录开始时间
|
||
func (tc *TestCase) Start() {
|
||
tc.Status = RUNNING
|
||
tc.StartedAt = time.Now()
|
||
tc.Attempts++
|
||
tc.UpdatedAt = time.Now()
|
||
}
|
||
|
||
// Complete 完成测试执行
|
||
// 设置测试结果状态,记录完成时间和持续时间
|
||
func (tc *TestCase) Complete(success bool, actualResult interface{}, err error) {
|
||
tc.Status = PASSED
|
||
if !success {
|
||
tc.Status = FAILED
|
||
}
|
||
tc.CompletedAt = time.Now()
|
||
tc.Duration = tc.CompletedAt.Sub(tc.StartedAt)
|
||
tc.ActualResult = actualResult
|
||
tc.Error = err
|
||
if err != nil {
|
||
tc.ErrorType = fmt.Sprintf("%T", err)
|
||
tc.ErrorDetail = err.Error()
|
||
tc.ErrorMessage = err.Error()
|
||
}
|
||
tc.UpdatedAt = time.Now()
|
||
}
|
||
|
||
// Skip 跳过测试
|
||
// 标记测试为跳过状态,记录跳过原因
|
||
func (tc *TestCase) Skip(reason string) {
|
||
tc.Status = SKIPPED
|
||
tc.ErrorMessage = reason
|
||
tc.UpdatedAt = time.Now()
|
||
}
|
||
|
||
// MarkAsTimeout 测试超时
|
||
// 标记测试为超时状态
|
||
func (tc *TestCase) MarkAsTimeout() {
|
||
tc.Status = TIMEOUT
|
||
tc.CompletedAt = time.Now()
|
||
tc.Duration = tc.CompletedAt.Sub(tc.StartedAt)
|
||
tc.ErrorMessage = "Test execution timeout"
|
||
tc.UpdatedAt = time.Now()
|
||
}
|
||
|
||
// Validate 验证测试用例的有效性
|
||
// 返回error如果测试用例无效,nil表示有效
|
||
func (tc *TestCase) Validate() error {
|
||
if tc.ID == "" {
|
||
return fmt.Errorf("test case ID cannot be empty")
|
||
}
|
||
|
||
if tc.Name == "" {
|
||
return fmt.Errorf("test case name cannot be empty")
|
||
}
|
||
|
||
if tc.Type < UNIT || tc.Type > LOAD {
|
||
return fmt.Errorf("invalid test type: %d", tc.Type)
|
||
}
|
||
|
||
if tc.Priority < LOW || tc.Priority > CRITICAL {
|
||
return fmt.Errorf("invalid test priority: %d", tc.Priority)
|
||
}
|
||
|
||
if tc.Timeout <= 0 {
|
||
return fmt.Errorf("timeout must be positive, got: %v", tc.Timeout)
|
||
}
|
||
|
||
if tc.MaxAttempts <= 0 {
|
||
return fmt.Errorf("max attempts must be positive, got: %d", tc.MaxAttempts)
|
||
}
|
||
|
||
if tc.Input == nil {
|
||
return fmt.Errorf("test input cannot be nil")
|
||
}
|
||
|
||
if tc.Expectation == nil {
|
||
return fmt.Errorf("test expectation cannot be nil")
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
// ShouldRun 判断是否应该运行测试
|
||
// 根据运行条件和跳过条件判断
|
||
func (tc *TestCase) ShouldRun() bool {
|
||
// 如果已经有最终状态,不再运行
|
||
if tc.Status == PASSED || tc.Status == FAILED || tc.Status == SKIPPED || tc.Status == TIMEOUT {
|
||
return false
|
||
}
|
||
|
||
// 如果超过最大尝试次数,不再运行
|
||
if tc.Attempts >= tc.MaxAttempts {
|
||
return false
|
||
}
|
||
|
||
// 这里可以实现更复杂的条件判断逻辑
|
||
// 例如:RunIf 和 SkipIf 条件的表达式解析
|
||
|
||
return true
|
||
}
|
||
|
||
// IsReady 检查测试是否准备好运行
|
||
// 检查所有前置条件是否满足
|
||
func (tc *TestCase) IsReady() bool {
|
||
// 这里可以实现前置条件检查逻辑
|
||
// 例如:检查依赖项是否完成,环境是否准备就绪等
|
||
|
||
return true
|
||
}
|
||
|
||
// HasDependency 检查是否有指定依赖
|
||
// 返回true如果包含指定依赖
|
||
func (tc *TestCase) HasDependency(dependency string) bool {
|
||
for _, dep := range tc.Dependencies {
|
||
if dep == dependency {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
// HasTag 检查是否有指定标签
|
||
// 返回true如果包含指定标签
|
||
func (tc *TestCase) HasTag(tag string) bool {
|
||
for _, t := range tc.Tags {
|
||
if t == tag {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
}
|
||
|
||
// IsSuccessful 检查测试是否成功
|
||
// 返回true如果测试成功通过
|
||
func (tc *TestCase) IsSuccessful() bool {
|
||
return tc.Status == PASSED
|
||
}
|
||
|
||
// IsFailed 检查测试是否失败
|
||
// 返回true如果测试执行失败
|
||
func (tc *TestCase) IsFailed() bool {
|
||
return tc.Status == FAILED
|
||
}
|
||
|
||
// IsSkipped 检查测试是否跳过
|
||
// 返回true如果测试被跳过
|
||
func (tc *TestCase) IsSkipped() bool {
|
||
return tc.Status == SKIPPED
|
||
}
|
||
|
||
// IsTimeout 检查测试是否超时
|
||
// 返回true如果测试执行超时
|
||
func (tc *TestCase) IsTimeout() bool {
|
||
return tc.Status == TIMEOUT
|
||
}
|
||
|
||
// IsRunning 检查测试是否正在运行
|
||
// 返回true如果测试正在执行
|
||
func (tc *TestCase) IsRunning() bool {
|
||
return tc.Status == RUNNING
|
||
}
|
||
|
||
// GetDuration 获取执行持续时间
|
||
// 返回测试执行的持续时间
|
||
func (tc *TestCase) GetDuration() time.Duration {
|
||
if tc.StartedAt.IsZero() {
|
||
return 0
|
||
}
|
||
if tc.CompletedAt.IsZero() {
|
||
return time.Since(tc.StartedAt)
|
||
}
|
||
return tc.Duration
|
||
}
|
||
|
||
// GetPerformanceMetric 获取性能指标
|
||
// 返回指定指标的值和是否存在
|
||
func (tc *TestCase) GetPerformanceMetric(key string) (interface{}, bool) {
|
||
value, exists := tc.PerformanceMetrics[key]
|
||
return value, exists
|
||
}
|
||
|
||
// GetParameter 获取参数值
|
||
// 返回指定参数的值和是否存在
|
||
func (tc *TestCase) GetParameter(key string) (interface{}, bool) {
|
||
value, exists := tc.Parameters[key]
|
||
return value, exists
|
||
}
|
||
|
||
// GetCustom 获取自定义字段值
|
||
// 返回指定自定义字段的值和是否存在
|
||
func (tc *TestCase) GetCustom(key string) (interface{}, bool) {
|
||
value, exists := tc.Custom[key]
|
||
return value, exists
|
||
}
|
||
|
||
// Clone 创建测试用例的副本
|
||
// 返回新的TestCase实例,深拷贝所有字段
|
||
func (tc *TestCase) Clone() *TestCase {
|
||
clone := &TestCase{
|
||
ID: tc.ID + "_clone",
|
||
Name: tc.Name,
|
||
Description: tc.Description,
|
||
Type: tc.Type,
|
||
Priority: tc.Priority,
|
||
Category: tc.Category,
|
||
Subsystem: tc.Subsystem,
|
||
Status: PENDING,
|
||
MaxAttempts: tc.MaxAttempts,
|
||
Timeout: tc.Timeout,
|
||
Input: tc.Input,
|
||
Expectation: tc.Expectation,
|
||
Config: tc.Config,
|
||
RunIf: tc.RunIf,
|
||
SkipIf: tc.SkipIf,
|
||
CreatedBy: tc.CreatedBy,
|
||
CreatedAt: time.Now(),
|
||
UpdatedAt: time.Now(),
|
||
Version: tc.Version,
|
||
Documentation: tc.Documentation,
|
||
}
|
||
|
||
// 深拷贝切片
|
||
if len(tc.Tags) > 0 {
|
||
clone.Tags = make([]string, len(tc.Tags))
|
||
copy(clone.Tags, tc.Tags)
|
||
}
|
||
|
||
if len(tc.Preconditions) > 0 {
|
||
clone.Preconditions = make([]string, len(tc.Preconditions))
|
||
copy(clone.Preconditions, tc.Preconditions)
|
||
}
|
||
|
||
if len(tc.Postconditions) > 0 {
|
||
clone.Postconditions = make([]string, len(tc.Postconditions))
|
||
copy(clone.Postconditions, tc.Postconditions)
|
||
}
|
||
|
||
if len(tc.Dependencies) > 0 {
|
||
clone.Dependencies = make([]string, len(tc.Dependencies))
|
||
copy(clone.Dependencies, tc.Dependencies)
|
||
}
|
||
|
||
if len(tc.Exclusions) > 0 {
|
||
clone.Exclusions = make([]string, len(tc.Exclusions))
|
||
copy(clone.Exclusions, tc.Exclusions)
|
||
}
|
||
|
||
if len(tc.Attachments) > 0 {
|
||
clone.Attachments = make([]TestAttachment, len(tc.Attachments))
|
||
copy(clone.Attachments, tc.Attachments)
|
||
}
|
||
|
||
// 深拷贝映射
|
||
if len(tc.PerformanceMetrics) > 0 {
|
||
clone.PerformanceMetrics = make(map[string]interface{})
|
||
for k, v := range tc.PerformanceMetrics {
|
||
clone.PerformanceMetrics[k] = v
|
||
}
|
||
}
|
||
|
||
if len(tc.Parameters) > 0 {
|
||
clone.Parameters = make(map[string]interface{})
|
||
for k, v := range tc.Parameters {
|
||
clone.Parameters[k] = v
|
||
}
|
||
}
|
||
|
||
if len(tc.Custom) > 0 {
|
||
clone.Custom = make(map[string]interface{})
|
||
for k, v := range tc.Custom {
|
||
clone.Custom[k] = v
|
||
}
|
||
}
|
||
|
||
return clone
|
||
}
|
||
|
||
// ToJSON 将测试用例转换为JSON格式
|
||
// 返回JSON格式的测试用例字符串
|
||
func (tc *TestCase) ToJSON() (string, error) {
|
||
if err := tc.Validate(); err != nil {
|
||
return "", fmt.Errorf("test case validation failed: %v", err)
|
||
}
|
||
|
||
data, err := json.Marshal(tc)
|
||
if err != nil {
|
||
return "", fmt.Errorf("failed to marshal test case: %v", err)
|
||
}
|
||
|
||
return string(data), nil
|
||
}
|
||
|
||
// ToJSONBytes 将测试用例转换为JSON字节数组
|
||
// 返回JSON格式的测试用例字节数组
|
||
func (tc *TestCase) ToJSONBytes() ([]byte, error) {
|
||
if err := tc.Validate(); err != nil {
|
||
return nil, fmt.Errorf("test case validation failed: %v", err)
|
||
}
|
||
|
||
return json.Marshal(tc)
|
||
}
|
||
|
||
// FromJSON 从JSON字符串解析测试用例
|
||
// 解析JSON字符串到TestCase
|
||
func (tc *TestCase) FromJSON(jsonStr string) error {
|
||
return json.Unmarshal([]byte(jsonStr), tc)
|
||
}
|
||
|
||
// FromJSONBytes 从JSON字节数组解析测试用例
|
||
// 解析JSON字节数组到TestCase
|
||
func (tc *TestCase) FromJSONBytes(data []byte) error {
|
||
return json.Unmarshal(data, tc)
|
||
}
|
||
|
||
// ToYAML 将测试用例转换为YAML格式
|
||
// 返回YAML格式的测试用例字符串
|
||
func (tc *TestCase) ToYAML() (string, error) {
|
||
if err := tc.Validate(); err != nil {
|
||
return "", fmt.Errorf("test case validation failed: %v", err)
|
||
}
|
||
|
||
// 这里可以使用 yaml.Marshal,但为了保持简单,暂时使用JSON格式
|
||
// 在实际项目中,应该引入 yaml 包
|
||
return tc.ToJSON()
|
||
}
|
||
|
||
// String 返回测试用例的字符串表示
|
||
// 实现Stringer接口
|
||
func (tc *TestCase) String() string {
|
||
return fmt.Sprintf("TestCase[%s:%s] - %s", tc.ID, tc.GetTypeString(), tc.Name)
|
||
}
|
||
|
||
// GetTypeString 获取测试类型的字符串表示
|
||
// 返回测试类型的字符串
|
||
func (tc *TestCase) GetTypeString() string {
|
||
switch tc.Type {
|
||
case UNIT:
|
||
return "UNIT"
|
||
case INTEGRATION:
|
||
return "INTEGRATION"
|
||
case CONTRACT:
|
||
return "CONTRACT"
|
||
case PERFORMANCE:
|
||
return "PERFORMANCE"
|
||
case SECURITY:
|
||
return "SECURITY"
|
||
case LOAD:
|
||
return "LOAD"
|
||
default:
|
||
return "UNKNOWN"
|
||
}
|
||
}
|
||
|
||
// GetPriorityString 获取优先级的字符串表示
|
||
// 返回优先级的字符串
|
||
func (tc *TestCase) GetPriorityString() string {
|
||
switch tc.Priority {
|
||
case LOW:
|
||
return "LOW"
|
||
case MEDIUM:
|
||
return "MEDIUM"
|
||
case HIGH:
|
||
return "HIGH"
|
||
case CRITICAL:
|
||
return "CRITICAL"
|
||
default:
|
||
return "UNKNOWN"
|
||
}
|
||
}
|
||
|
||
// GetStatusString 获取状态的字符串表示
|
||
// 返回状态的字符串
|
||
func (tc *TestCase) GetStatusString() string {
|
||
switch tc.Status {
|
||
case PENDING:
|
||
return "PENDING"
|
||
case RUNNING:
|
||
return "RUNNING"
|
||
case PASSED:
|
||
return "PASSED"
|
||
case FAILED:
|
||
return "FAILED"
|
||
case SKIPPED:
|
||
return "SKIPPED"
|
||
case TIMEOUT:
|
||
return "TIMEOUT"
|
||
default:
|
||
return "UNKNOWN"
|
||
}
|
||
}
|
||
|
||
// Reset 重置测试用例状态
|
||
// 重置执行相关的字段,保留配置信息
|
||
func (tc *TestCase) Reset() {
|
||
tc.Status = PENDING
|
||
tc.StartedAt = time.Time{}
|
||
tc.CompletedAt = time.Time{}
|
||
tc.Duration = 0
|
||
tc.Attempts = 0
|
||
tc.ActualResult = nil
|
||
tc.Error = nil
|
||
tc.ErrorType = ""
|
||
tc.ErrorDetail = ""
|
||
tc.ErrorMessage = ""
|
||
tc.MemoryUsage = 0
|
||
tc.CPUUsage = 0
|
||
tc.Throughput = 0
|
||
tc.UpdatedAt = time.Now()
|
||
}
|
||
|
||
// MarkAsPassed 标记测试为通过
|
||
// 快速标记测试为成功状态
|
||
func (tc *TestCase) MarkAsPassed() {
|
||
tc.Status = PASSED
|
||
tc.CompletedAt = time.Now()
|
||
if !tc.StartedAt.IsZero() {
|
||
tc.Duration = tc.CompletedAt.Sub(tc.StartedAt)
|
||
}
|
||
tc.UpdatedAt = time.Now()
|
||
}
|
||
|
||
// MarkAsFailed 标记测试为失败
|
||
// 快速标记测试为失败状态,可指定错误信息
|
||
func (tc *TestCase) MarkAsFailed(err error) {
|
||
tc.Status = FAILED
|
||
tc.Error = err
|
||
if err != nil {
|
||
tc.ErrorType = fmt.Sprintf("%T", err)
|
||
tc.ErrorDetail = err.Error()
|
||
tc.ErrorMessage = err.Error()
|
||
}
|
||
tc.CompletedAt = time.Now()
|
||
if !tc.StartedAt.IsZero() {
|
||
tc.Duration = tc.CompletedAt.Sub(tc.StartedAt)
|
||
}
|
||
tc.UpdatedAt = time.Now()
|
||
} |