mirror of
https://github.com/httprunner/httprunner.git
synced 2026-07-12 16:01:27 +08:00
fix: get resultsPath
This commit is contained in:
@@ -20,7 +20,6 @@ const (
|
|||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
RootDir string
|
RootDir string
|
||||||
ResultsDir string
|
|
||||||
resultsPath string
|
resultsPath string
|
||||||
downloadsPath string
|
downloadsPath string
|
||||||
screenShotsPath string
|
screenShotsPath string
|
||||||
@@ -48,11 +47,11 @@ func GetConfig() *Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
startTimeStr := cfg.StartTime.Format("20060102150405")
|
startTimeStr := cfg.StartTime.Format("20060102150405")
|
||||||
cfg.ResultsDir = filepath.Join(ResultsDirName, startTimeStr)
|
resultsDir := filepath.Join(ResultsDirName, startTimeStr)
|
||||||
cfg.resultsPath = filepath.Join(cfg.RootDir, cfg.ResultsDir)
|
cfg.resultsPath = filepath.Join(cfg.RootDir, resultsDir)
|
||||||
cfg.downloadsPath = filepath.Join(cfg.RootDir, filepath.Join(DownloadsDirName, startTimeStr))
|
cfg.downloadsPath = filepath.Join(cfg.RootDir, filepath.Join(DownloadsDirName, startTimeStr))
|
||||||
cfg.screenShotsPath = filepath.Join(cfg.resultsPath, ScreenshotsDirName)
|
cfg.screenShotsPath = filepath.Join(cfg.resultsPath, ScreenshotsDirName)
|
||||||
cfg.ActionLogFilePath = filepath.Join(cfg.ResultsDir, ActionLogDirName)
|
cfg.ActionLogFilePath = filepath.Join(resultsDir, ActionLogDirName)
|
||||||
cfg.DeviceActionLogFilePath = "/sdcard/Android/data/io.appium.uiautomator2.server/files/hodor"
|
cfg.DeviceActionLogFilePath = "/sdcard/Android/data/io.appium.uiautomator2.server/files/hodor"
|
||||||
|
|
||||||
globalConfig = cfg
|
globalConfig = cfg
|
||||||
@@ -71,7 +70,7 @@ func (c *Config) ResultsPath() string {
|
|||||||
if err := builtin.EnsureFolderExists(c.resultsPath); err != nil {
|
if err := builtin.EnsureFolderExists(c.resultsPath); err != nil {
|
||||||
log.Error().Err(err).Str("path", c.resultsPath).Msg("failed to create results directory")
|
log.Error().Err(err).Str("path", c.resultsPath).Msg("failed to create results directory")
|
||||||
} else {
|
} else {
|
||||||
log.Info().Str("path", c.resultsPath).Msg("create folder")
|
log.Info().Str("path", c.resultsPath).Msg("created results folder")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return c.resultsPath
|
return c.resultsPath
|
||||||
@@ -86,6 +85,8 @@ func (c *Config) DownloadsPath() string {
|
|||||||
if _, err := os.Stat(c.downloadsPath); os.IsNotExist(err) {
|
if _, err := os.Stat(c.downloadsPath); os.IsNotExist(err) {
|
||||||
if err := builtin.EnsureFolderExists(c.downloadsPath); err != nil {
|
if err := builtin.EnsureFolderExists(c.downloadsPath); err != nil {
|
||||||
log.Error().Err(err).Str("path", c.downloadsPath).Msg("failed to create downloads directory")
|
log.Error().Err(err).Str("path", c.downloadsPath).Msg("failed to create downloads directory")
|
||||||
|
} else {
|
||||||
|
log.Info().Str("path", c.downloadsPath).Msg("created downloads folder")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return c.downloadsPath
|
return c.downloadsPath
|
||||||
@@ -100,6 +101,8 @@ func (c *Config) ScreenShotsPath() string {
|
|||||||
if _, err := os.Stat(c.screenShotsPath); os.IsNotExist(err) {
|
if _, err := os.Stat(c.screenShotsPath); os.IsNotExist(err) {
|
||||||
if err := builtin.EnsureFolderExists(c.screenShotsPath); err != nil {
|
if err := builtin.EnsureFolderExists(c.screenShotsPath); err != nil {
|
||||||
log.Error().Err(err).Str("path", c.screenShotsPath).Msg("failed to create screenshots directory")
|
log.Error().Err(err).Str("path", c.screenShotsPath).Msg("failed to create screenshots directory")
|
||||||
|
} else {
|
||||||
|
log.Info().Str("path", c.screenShotsPath).Msg("created screenshots folder")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return c.screenShotsPath
|
return c.screenShotsPath
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
v5.0.0-beta-2506111457
|
v5.0.0-beta-2506121451
|
||||||
|
|||||||
20
summary.go
20
summary.go
@@ -76,20 +76,8 @@ func (s *Summary) AddCaseSummary(caseSummary *TestCaseSummary) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Summary) SetupDirPath() (path string, err error) {
|
|
||||||
dirPath := filepath.Join(s.rootDir, config.GetConfig().ResultsDir)
|
|
||||||
err = builtin.EnsureFolderExists(dirPath)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return dirPath, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Summary) GenHTMLReport() error {
|
func (s *Summary) GenHTMLReport() error {
|
||||||
reportsDir, err := s.SetupDirPath()
|
reportsDir := config.GetConfig().ResultsPath()
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find summary.json and hrp.log files
|
// Find summary.json and hrp.log files
|
||||||
summaryPath := filepath.Join(reportsDir, "summary.json")
|
summaryPath := filepath.Join(reportsDir, "summary.json")
|
||||||
@@ -107,11 +95,7 @@ func (s *Summary) GenHTMLReport() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Summary) GenSummary() (path string, err error) {
|
func (s *Summary) GenSummary() (path string, err error) {
|
||||||
reportsDir, err := s.SetupDirPath()
|
reportsDir := config.GetConfig().ResultsPath()
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
path = filepath.Join(reportsDir, "summary.json")
|
path = filepath.Join(reportsDir, "summary.json")
|
||||||
err = builtin.Dump2JSON(s, path)
|
err = builtin.Dump2JSON(s, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package ai
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -16,12 +17,12 @@ import (
|
|||||||
|
|
||||||
// GameInfo represents basic game information for testing
|
// GameInfo represents basic game information for testing
|
||||||
type GameInfo struct {
|
type GameInfo struct {
|
||||||
Content string `json:"content"` // Description
|
Content string `json:"content"` // Description
|
||||||
Thought string `json:"thought"` // Reasoning
|
Thought string `json:"thought"` // Reasoning
|
||||||
Rows int `json:"rows"` // Number of rows
|
Rows int `json:"rows"` // Number of rows
|
||||||
Cols int `json:"cols"` // Number of columns
|
Cols int `json:"cols"` // Number of columns
|
||||||
Icons []string `json:"icons"` // List of icon types
|
Icons []string `json:"icons"` // List of icon types
|
||||||
TotalIcons int `json:"totalIcons"` // Total number of icons
|
TotalIcons int `json:"totalNumber"` // Total number of icons
|
||||||
}
|
}
|
||||||
|
|
||||||
// GameAnalysisResult represents comprehensive game analysis for testing
|
// GameAnalysisResult represents comprehensive game analysis for testing
|
||||||
@@ -72,15 +73,15 @@ type TypeCount struct {
|
|||||||
|
|
||||||
func setupTestQuerier(t *testing.T) *Querier {
|
func setupTestQuerier(t *testing.T) *Querier {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
modelConfig, err := GetModelConfig(option.OPENAI_GPT_4O)
|
modelConfig, err := GetModelConfig(option.DOUBAO_SEED_1_6_250615)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
querier, err := NewQuerier(ctx, modelConfig)
|
querier, err := NewQuerier(ctx, modelConfig)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return querier
|
return querier
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadTestImage(t *testing.T) (string, types.Size) {
|
func loadTestImage(t *testing.T, path string) (string, types.Size) {
|
||||||
screenshot, size, err := builtin.LoadImage("testdata/llk_1.png")
|
screenshot, size, err := builtin.LoadImage(path)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
return screenshot, size
|
return screenshot, size
|
||||||
}
|
}
|
||||||
@@ -140,10 +141,86 @@ func TestParseQueryResult(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestModel(t *testing.T) {
|
||||||
|
// Test different models
|
||||||
|
models := []option.LLMServiceType{
|
||||||
|
option.DOUBAO_SEED_1_6_250615,
|
||||||
|
option.DOUBAO_1_5_THINKING_VISION_PRO_250428,
|
||||||
|
option.DOUBAO_1_5_UI_TARS_250328,
|
||||||
|
option.OPENAI_GPT_4O,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, path := range []string{"testdata/llk_1.png", "testdata/llk_4.png"} {
|
||||||
|
for _, modelType := range models {
|
||||||
|
t.Run(string(modelType), func(t *testing.T) {
|
||||||
|
modelConfig, err := GetModelConfig(modelType)
|
||||||
|
require.NoError(t, err)
|
||||||
|
querier, err := NewQuerier(context.Background(), modelConfig)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Load test image
|
||||||
|
screenshot, size := loadTestImage(t, path)
|
||||||
|
|
||||||
|
// Test query
|
||||||
|
opts := &QueryOptions{
|
||||||
|
Query: "请分析这个连连看游戏界面,告诉我有多少行多少列,有哪些不同类型的图案,图案总数是多少",
|
||||||
|
Screenshot: screenshot,
|
||||||
|
Size: size,
|
||||||
|
OutputSchema: GameInfo{},
|
||||||
|
}
|
||||||
|
|
||||||
|
result1, err := querier.Query(context.Background(), opts)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
gameInfo, ok := result1.Data.(*GameInfo)
|
||||||
|
assert.True(t, ok)
|
||||||
|
jsonData1, _ := json.Marshal(gameInfo)
|
||||||
|
fmt.Printf("modelType: %v, gameInfo: %s\n", modelType, string(jsonData1))
|
||||||
|
|
||||||
|
opts2 := &QueryOptions{
|
||||||
|
Query: `Analyze this game interface and provide structured information about:
|
||||||
|
1. The type of game
|
||||||
|
2. Grid dimensions (rows and columns)
|
||||||
|
3. All game elements with their positions and types
|
||||||
|
4. Statistics about element distribution`,
|
||||||
|
Screenshot: screenshot,
|
||||||
|
Size: size,
|
||||||
|
OutputSchema: GameAnalysisResult{},
|
||||||
|
}
|
||||||
|
|
||||||
|
result2, err := querier.Query(context.Background(), opts2)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// Verify structured data
|
||||||
|
gameAnalysisResult, ok := result2.Data.(*GameAnalysisResult)
|
||||||
|
assert.True(t, ok)
|
||||||
|
jsonData2, _ := json.Marshal(gameAnalysisResult)
|
||||||
|
fmt.Printf("modelType: %v, gameAnalysisResult: %s\n", modelType, string(jsonData2))
|
||||||
|
|
||||||
|
opts3 := &QueryOptions{
|
||||||
|
Query: "给出第一个苹果的坐标",
|
||||||
|
Screenshot: screenshot,
|
||||||
|
Size: size,
|
||||||
|
OutputSchema: BoundingBox{},
|
||||||
|
}
|
||||||
|
|
||||||
|
result3, err := querier.Query(context.Background(), opts3)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
boxInfo, ok := result3.Data.(*BoundingBox)
|
||||||
|
assert.True(t, ok)
|
||||||
|
jsonData3, _ := json.Marshal(boxInfo)
|
||||||
|
fmt.Printf("modelType: %v, thought: %v, boxInfo: %s\n",
|
||||||
|
modelType, result3.Thought, string(jsonData3))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TestQueryFunctionality tests both basic and custom schema query functionality
|
// TestQueryFunctionality tests both basic and custom schema query functionality
|
||||||
func TestQueryFunctionality(t *testing.T) {
|
func TestQueryFunctionality(t *testing.T) {
|
||||||
querier := setupTestQuerier(t)
|
querier := setupTestQuerier(t)
|
||||||
screenshot, size := loadTestImage(t)
|
screenshot, size := loadTestImage(t, "testdata/llk_1.png")
|
||||||
|
|
||||||
t.Run("BasicQuery", func(t *testing.T) {
|
t.Run("BasicQuery", func(t *testing.T) {
|
||||||
opts := &QueryOptions{
|
opts := &QueryOptions{
|
||||||
@@ -172,10 +249,6 @@ func TestQueryFunctionality(t *testing.T) {
|
|||||||
|
|
||||||
result, err := querier.Query(context.Background(), opts)
|
result, err := querier.Query(context.Background(), opts)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, result)
|
|
||||||
assert.NotEmpty(t, result.Content)
|
|
||||||
assert.NotEmpty(t, result.Thought)
|
|
||||||
assert.NotNil(t, result.Data) // Should contain structured data
|
|
||||||
|
|
||||||
// Verify structured data
|
// Verify structured data
|
||||||
gameInfo, ok := result.Data.(*GameInfo)
|
gameInfo, ok := result.Data.(*GameInfo)
|
||||||
@@ -204,11 +277,8 @@ func TestQueryFunctionality(t *testing.T) {
|
|||||||
|
|
||||||
result, err := querier.Query(context.Background(), opts)
|
result, err := querier.Query(context.Background(), opts)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, result)
|
|
||||||
assert.NotEmpty(t, result.Content)
|
|
||||||
assert.NotEmpty(t, result.Thought)
|
|
||||||
assert.NotNil(t, result.Data)
|
|
||||||
|
|
||||||
|
// Verify structured data
|
||||||
gameAnalysisResult, ok := result.Data.(*GameAnalysisResult)
|
gameAnalysisResult, ok := result.Data.(*GameAnalysisResult)
|
||||||
assert.True(t, ok)
|
assert.True(t, ok)
|
||||||
assert.NotNil(t, gameAnalysisResult)
|
assert.NotNil(t, gameAnalysisResult)
|
||||||
@@ -226,7 +296,7 @@ func TestQueryFunctionality(t *testing.T) {
|
|||||||
// TestQueryWithDifferentPrompts tests various types of queries on the same screenshot
|
// TestQueryWithDifferentPrompts tests various types of queries on the same screenshot
|
||||||
func TestQueryWithDifferentPrompts(t *testing.T) {
|
func TestQueryWithDifferentPrompts(t *testing.T) {
|
||||||
querier := setupTestQuerier(t)
|
querier := setupTestQuerier(t)
|
||||||
screenshot, size := loadTestImage(t)
|
screenshot, size := loadTestImage(t, "testdata/llk_1.png")
|
||||||
|
|
||||||
queries := []string{
|
queries := []string{
|
||||||
"请描述这张图片中的内容",
|
"请描述这张图片中的内容",
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ func WithCVService(service CVServiceType) AIServiceOption {
|
|||||||
|
|
||||||
type LLMServiceType string
|
type LLMServiceType string
|
||||||
|
|
||||||
|
// UI-TARS do not support function calling and json response
|
||||||
func IS_UI_TARS(modelType LLMServiceType) bool {
|
func IS_UI_TARS(modelType LLMServiceType) bool {
|
||||||
return modelType == DOUBAO_1_5_UI_TARS_250328 ||
|
return modelType == DOUBAO_1_5_UI_TARS_250328 ||
|
||||||
modelType == DOUBAO_1_5_UI_TARS_250428
|
modelType == DOUBAO_1_5_UI_TARS_250428
|
||||||
@@ -38,8 +39,9 @@ func IS_UI_TARS(modelType LLMServiceType) bool {
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
DOUBAO_1_5_UI_TARS_250328 LLMServiceType = "doubao-1.5-ui-tars-250328"
|
DOUBAO_1_5_UI_TARS_250328 LLMServiceType = "doubao-1.5-ui-tars-250328"
|
||||||
DOUBAO_1_5_UI_TARS_250428 LLMServiceType = "doubao-1.5-ui-tars-250428" // not support function calling and json response
|
DOUBAO_1_5_UI_TARS_250428 LLMServiceType = "doubao-1.5-ui-tars-250428"
|
||||||
DOUBAO_1_5_THINKING_VISION_PRO_250428 LLMServiceType = "doubao-1.5-thinking-vision-pro-250428"
|
DOUBAO_1_5_THINKING_VISION_PRO_250428 LLMServiceType = "doubao-1.5-thinking-vision-pro-250428"
|
||||||
|
DOUBAO_SEED_1_6_250615 LLMServiceType = "doubao-seed-1.6-250615"
|
||||||
OPENAI_GPT_4O LLMServiceType = "openai/gpt-4o"
|
OPENAI_GPT_4O LLMServiceType = "openai/gpt-4o"
|
||||||
DEEPSEEK_R1_250528 LLMServiceType = "deepseek-r1-250528"
|
DEEPSEEK_R1_250528 LLMServiceType = "deepseek-r1-250528"
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user