first commit
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

This commit is contained in:
Rogee
2025-09-28 10:05:07 +08:00
commit 7fcabe0225
481 changed files with 125127 additions and 0 deletions

View File

@@ -0,0 +1,798 @@
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()
}