mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-12 02:21:29 +08:00
286 lines
7.1 KiB
Go
286 lines
7.1 KiB
Go
package uixt
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/httprunner/httprunner/v5/uixt/option"
|
|
)
|
|
|
|
func TestToolSleep_ConvertActionToCallToolRequest(t *testing.T) {
|
|
tool := &ToolSleep{}
|
|
|
|
tests := []struct {
|
|
name string
|
|
action option.MobileAction
|
|
expectedArgs map[string]any
|
|
shouldError bool
|
|
}{
|
|
{
|
|
name: "json.Number parameter",
|
|
action: option.MobileAction{
|
|
Method: option.ACTION_Sleep,
|
|
Params: json.Number("3.5"),
|
|
},
|
|
expectedArgs: map[string]any{"seconds": float64(3.5)},
|
|
shouldError: false,
|
|
},
|
|
{
|
|
name: "float64 parameter",
|
|
action: option.MobileAction{
|
|
Method: option.ACTION_Sleep,
|
|
Params: float64(5.2),
|
|
},
|
|
expectedArgs: map[string]any{"seconds": float64(5.2)},
|
|
shouldError: false,
|
|
},
|
|
{
|
|
name: "int64 parameter",
|
|
action: option.MobileAction{
|
|
Method: option.ACTION_Sleep,
|
|
Params: int64(5),
|
|
},
|
|
expectedArgs: map[string]any{"seconds": float64(5)},
|
|
shouldError: false,
|
|
},
|
|
{
|
|
name: "SleepConfig with startTime",
|
|
action: option.MobileAction{
|
|
Method: option.ACTION_Sleep,
|
|
Params: SleepConfig{
|
|
StartTime: time.UnixMilli(1691234567890),
|
|
Seconds: 2.5,
|
|
},
|
|
},
|
|
expectedArgs: map[string]any{
|
|
"seconds": 2.5,
|
|
"start_time_ms": int64(1691234567890),
|
|
},
|
|
shouldError: false,
|
|
},
|
|
{
|
|
name: "invalid parameter type",
|
|
action: option.MobileAction{
|
|
Method: option.ACTION_Sleep,
|
|
Params: "invalid",
|
|
},
|
|
expectedArgs: nil,
|
|
shouldError: true,
|
|
},
|
|
{
|
|
name: "json.Number with integer value",
|
|
action: option.MobileAction{
|
|
Method: option.ACTION_Sleep,
|
|
Params: json.Number("10"),
|
|
},
|
|
expectedArgs: map[string]any{"seconds": float64(10)},
|
|
shouldError: false,
|
|
},
|
|
{
|
|
name: "json.Number with decimal value",
|
|
action: option.MobileAction{
|
|
Method: option.ACTION_Sleep,
|
|
Params: json.Number("1.25"),
|
|
},
|
|
expectedArgs: map[string]any{"seconds": float64(1.25)},
|
|
shouldError: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
request, err := tool.ConvertActionToCallToolRequest(tt.action)
|
|
|
|
if tt.shouldError {
|
|
assert.Error(t, err)
|
|
} else {
|
|
require.NoError(t, err)
|
|
args := request.GetArguments()
|
|
for key, expectedValue := range tt.expectedArgs {
|
|
assert.Equal(t, expectedValue, args[key], "Argument %s mismatch", key)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestToolSleepMS_ConvertActionToCallToolRequest(t *testing.T) {
|
|
tool := &ToolSleepMS{}
|
|
|
|
tests := []struct {
|
|
name string
|
|
action option.MobileAction
|
|
expectedArgs map[string]any
|
|
shouldError bool
|
|
}{
|
|
{
|
|
name: "json.Number parameter",
|
|
action: option.MobileAction{
|
|
Method: option.ACTION_SleepMS,
|
|
Params: json.Number("1500"),
|
|
},
|
|
expectedArgs: map[string]any{"milliseconds": int64(1500)},
|
|
shouldError: false,
|
|
},
|
|
{
|
|
name: "int64 parameter",
|
|
action: option.MobileAction{
|
|
Method: option.ACTION_SleepMS,
|
|
Params: int64(2000),
|
|
},
|
|
expectedArgs: map[string]any{"milliseconds": int64(2000)},
|
|
shouldError: false,
|
|
},
|
|
{
|
|
name: "float64 parameter",
|
|
action: option.MobileAction{
|
|
Method: option.ACTION_SleepMS,
|
|
Params: float64(2500.7),
|
|
},
|
|
expectedArgs: map[string]any{"milliseconds": int64(2500)},
|
|
shouldError: false,
|
|
},
|
|
{
|
|
name: "SleepConfig with startTime",
|
|
action: option.MobileAction{
|
|
Method: option.ACTION_SleepMS,
|
|
Params: SleepConfig{
|
|
StartTime: time.UnixMilli(1691234567890),
|
|
Milliseconds: 3000,
|
|
},
|
|
},
|
|
expectedArgs: map[string]any{
|
|
"milliseconds": int64(3000),
|
|
"start_time_ms": int64(1691234567890),
|
|
},
|
|
shouldError: false,
|
|
},
|
|
{
|
|
name: "json.Number with decimal value",
|
|
action: option.MobileAction{
|
|
Method: option.ACTION_SleepMS,
|
|
Params: json.Number("1234.56"),
|
|
},
|
|
expectedArgs: map[string]any{"milliseconds": int64(1234)},
|
|
shouldError: false,
|
|
},
|
|
{
|
|
name: "invalid parameter type",
|
|
action: option.MobileAction{
|
|
Method: option.ACTION_SleepMS,
|
|
Params: "invalid",
|
|
},
|
|
expectedArgs: nil,
|
|
shouldError: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
request, err := tool.ConvertActionToCallToolRequest(tt.action)
|
|
|
|
if tt.shouldError {
|
|
assert.Error(t, err)
|
|
} else {
|
|
require.NoError(t, err)
|
|
args := request.GetArguments()
|
|
for key, expectedValue := range tt.expectedArgs {
|
|
assert.Equal(t, expectedValue, args[key], "Argument %s mismatch", key)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSleepStrictTiming(t *testing.T) {
|
|
// Test that strict sleep properly adjusts for elapsed time
|
|
startTime := time.Now()
|
|
|
|
// Simulate some processing time
|
|
time.Sleep(50 * time.Millisecond)
|
|
|
|
ctx := context.Background()
|
|
|
|
// Test sleepStrict with the start time
|
|
testStart := time.Now()
|
|
sleepStrict(ctx, startTime, 200) // 200ms total duration
|
|
actualElapsed := time.Since(testStart)
|
|
|
|
// Should sleep approximately 150ms (200ms - 50ms already elapsed)
|
|
// Allow some tolerance for timing variations
|
|
expectedSleep := 150 * time.Millisecond
|
|
assert.Greater(t, actualElapsed, expectedSleep/2, "Sleep too short")
|
|
assert.Less(t, actualElapsed, expectedSleep*2, "Sleep too long")
|
|
}
|
|
|
|
func TestSleepCancellation(t *testing.T) {
|
|
// Test that sleep respects context cancellation
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
// Cancel after 50ms
|
|
go func() {
|
|
time.Sleep(50 * time.Millisecond)
|
|
cancel()
|
|
}()
|
|
|
|
start := time.Now()
|
|
sleepStrict(ctx, time.Time{}, 500) // Try to sleep 500ms
|
|
elapsed := time.Since(start)
|
|
|
|
// Should be cancelled after ~50ms, not sleep full 500ms
|
|
assert.Less(t, elapsed, 200*time.Millisecond, "Sleep was not properly cancelled")
|
|
}
|
|
|
|
func TestSleepStrictWithZeroTime(t *testing.T) {
|
|
// Test sleepStrict behaves like normal sleep when startTime is zero
|
|
ctx := context.Background()
|
|
|
|
start := time.Now()
|
|
sleepStrict(ctx, time.Time{}, 100) // 100ms, no start time
|
|
elapsed := time.Since(start)
|
|
|
|
// Should sleep full duration
|
|
expectedSleep := 100 * time.Millisecond
|
|
assert.Greater(t, elapsed, expectedSleep/2, "Sleep too short")
|
|
assert.Less(t, elapsed, expectedSleep*2, "Sleep too long")
|
|
}
|
|
|
|
func TestSleepStrictWithPastStartTime(t *testing.T) {
|
|
// Test sleepStrict skips sleep when elapsed time exceeds duration
|
|
startTime := time.Now().Add(-300 * time.Millisecond) // 300ms ago
|
|
ctx := context.Background()
|
|
|
|
start := time.Now()
|
|
sleepStrict(ctx, startTime, 200) // Want 200ms total, but 300ms already elapsed
|
|
elapsed := time.Since(start)
|
|
|
|
// Should skip sleep entirely
|
|
assert.Less(t, elapsed, 50*time.Millisecond, "Should have skipped sleep")
|
|
}
|
|
|
|
func TestJsonNumberHandling(t *testing.T) {
|
|
// Test that json.Number is correctly handled in different scenarios
|
|
|
|
// Test float json.Number
|
|
floatNumber := json.Number("3.14")
|
|
floatVal, err := floatNumber.Float64()
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 3.14, floatVal)
|
|
|
|
// Test int json.Number
|
|
intNumber := json.Number("1500")
|
|
intVal, err := intNumber.Int64()
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, int64(1500), intVal)
|
|
|
|
// Test invalid json.Number
|
|
invalidNumber := json.Number("invalid")
|
|
_, err = invalidNumber.Float64()
|
|
assert.Error(t, err)
|
|
}
|