Files
akmon/uni_modules/ak-ai-news/test/integration-test.uts
2026-01-20 08:04:15 +08:00

746 lines
22 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// AI News System Integration Test Suite
// Comprehensive integration testing with real AI service APIs
import {
AIServiceManager,
type AIServiceConfig,
type ContentInfo,
type AIResponse,
type TranslationResult,
type ContentAnalysisResult
} from '../index.uts'
/**
* Integration test configuration
*/
type IntegrationTestConfig = {
enableRealAPIs: boolean
apiKeys: {
openai?: string
google?: string
baidu?: {
appId: string
secretKey: string
}
}
testTimeout: number
retryAttempts: number
costLimits: {
maxCostPerTest: number
dailyLimit: number
}
}
/**
* Test metrics and results
*/
type TestMetrics = {
testName: string
startTime: number
endTime: number
duration: number
success: boolean
error?: string
metrics?: {
tokensUsed?: number
costUSD?: number
latencyMs?: number
throughput?: number
}
}
/**
* 综合集成测试类
*/
export class AINewsIntegrationTest {
private config: IntegrationTestConfig
private serviceManager: AIServiceManager
private testResults: TestMetrics[] = []
private totalCost: number = 0
constructor(config: IntegrationTestConfig) {
this.config = config
this.initializeServices()
}
private initializeServices(): void {
const aiConfig: AIServiceConfig = {
openai: {
apiKey: this.config.apiKeys.openai || 'test-key',
model: 'gpt-3.5-turbo',
maxTokens: 1500,
temperature: 0.7
},
google: {
apiKey: this.config.apiKeys.google || 'test-key',
projectId: 'test-project'
},
baidu: {
appId: this.config.apiKeys.baidu?.appId || 'test-app-id',
secretKey: this.config.apiKeys.baidu?.secretKey || 'test-secret',
model: 'ernie-bot'
},
costLimits: {
dailyUSD: this.config.costLimits.dailyLimit,
monthlyUSD: this.config.costLimits.dailyLimit * 30,
perRequestUSD: this.config.costLimits.maxCostPerTest
},
qualityThresholds: {
translation: 0.8,
sentiment: 0.7,
credibility: 0.6
}
}
this.serviceManager = new AIServiceManager(aiConfig)
}
/**
* 集成测试1: 多提供商翻译服务测试
*/
async testMultiProviderTranslation(): Promise<TestMetrics> {
const testName = 'Multi-Provider Translation Test'
const startTime = Date.now()
try {
console.log(`🧪 Starting ${testName}...`)
const translationService = this.serviceManager.getTranslationService()
const testTexts = [
{
text: "Artificial intelligence is revolutionizing the news industry with automated content generation and smart recommendations.",
from: 'en',
to: 'zh-CN'
},
{
text: "人工智能正在通过自动化内容生成和智能推荐革命性地改变新闻行业。",
from: 'zh-CN',
to: 'en'
},
{
text: "L'intelligence artificielle révolutionne l'industrie de l'information avec la génération de contenu automatisée.",
from: 'fr',
to: 'zh-CN'
}
]
let totalTokens = 0
let totalCost = 0
const results: TranslationResult[] = []
// Test each provider
const providers = ['openai', 'google', 'baidu'] as const
for (const provider of providers) {
console.log(` Testing provider: ${provider}`)
for (const testCase of testTexts) {
const result = await translationService.translateText(
testCase.text,
testCase.to,
testCase.from,
{
provider,
culturalAdaptation: true,
preserveFormatting: true
}
)
if (result.success && result.data) {
results.push(result.data)
totalTokens += result.data.tokensUsed || 0
totalCost += result.data.costUSD || 0
console.log(` ✅ ${testCase.from} → ${testCase.to}: ${result.data.translatedText.substring(0, 50)}...`)
} else {
console.log(` ❌ Translation failed: ${result.error}`)
}
}
}
const endTime = Date.now()
const duration = endTime - startTime
const metrics: TestMetrics = {
testName,
startTime,
endTime,
duration,
success: results.length > 0,
metrics: {
tokensUsed: totalTokens,
costUSD: totalCost,
latencyMs: duration / results.length,
throughput: results.length / (duration / 1000)
}
}
this.totalCost += totalCost
console.log(`✅ ${testName} completed in ${duration}ms`)
return metrics
} catch (error) {
const endTime = Date.now()
return {
testName,
startTime,
endTime,
duration: endTime - startTime,
success: false,
error: error instanceof Error ? error.message : String(error)
}
}
}
/**
* 集成测试2: 内容分析端到端测试
*/
async testContentAnalysisEndToEnd(): Promise<TestMetrics> {
const testName = 'Content Analysis End-to-End Test'
const startTime = Date.now()
try {
console.log(`🧪 Starting ${testName}...`)
const analysisService = this.serviceManager.getAnalysisService()
const testArticles = [
{
title: "科技巨头发布突破性AI技术",
content: "今日多家科技公司宣布了他们在人工智能领域的最新突破。这些技术预计将在未来几年内改变我们的生活方式。专家表示这标志着AI发展的新里程碑。",
language: 'zh-CN'
},
{
title: "Global Economic Outlook Shows Mixed Signals",
content: "Economic analysts are divided on the global economic forecast for next year. While some indicators point to recovery, others suggest continued volatility in key markets.",
language: 'en'
},
{
title: "Climate Change Impact on Agriculture",
content: "Recent studies show that climate change is significantly affecting crop yields worldwide. Farmers are adapting new techniques to cope with changing weather patterns.",
language: 'en'
}
]
let totalTokens = 0
let totalCost = 0
const results: ContentAnalysisResult[] = []
for (const article of testArticles) {
console.log(` Analyzing: ${article.title}`)
const analysisResult = await analysisService.analyzeContent(
article.content,
{
types: ['sentiment', 'entities', 'keywords', 'topics', 'quality', 'toxicity'],
language: article.language,
enableCaching: true
}
)
if (analysisResult.success && analysisResult.data) {
results.push(analysisResult.data)
totalTokens += analysisResult.data.tokensUsed || 0
totalCost += analysisResult.data.costUSD || 0
console.log(` ✅ Sentiment: ${analysisResult.data.sentimentLabel} (${analysisResult.data.sentimentScore.toFixed(2)})`)
console.log(` ✅ Entities: ${analysisResult.data.entities?.length || 0} found`)
console.log(` ✅ Keywords: ${analysisResult.data.keywords?.length || 0} extracted`)
console.log(` ✅ Quality: ${analysisResult.data.qualityScore?.toFixed(2) || 'N/A'}`)
} else {
console.log(` ❌ Analysis failed: ${analysisResult.error}`)
}
}
const endTime = Date.now()
const duration = endTime - startTime
const metrics: TestMetrics = {
testName,
startTime,
endTime,
duration,
success: results.length > 0,
metrics: {
tokensUsed: totalTokens,
costUSD: totalCost,
latencyMs: duration / results.length,
throughput: results.length / (duration / 1000)
}
}
this.totalCost += totalCost
console.log(`✅ ${testName} completed in ${duration}ms`)
return metrics
} catch (error) {
const endTime = Date.now()
return {
testName,
startTime,
endTime,
duration: endTime - startTime,
success: false,
error: error instanceof Error ? error.message : String(error)
}
}
}
/**
* 集成测试3: 智能对话会话测试
*/
async testChatSessionFlow(): Promise<TestMetrics> {
const testName = 'Chat Session Flow Test'
const startTime = Date.now()
try {
console.log(`🧪 Starting ${testName}...`)
const chatService = this.serviceManager.getChatService()
const testConversations = [
{
language: 'zh-CN',
messages: [
'你好,我想了解今天的重要新闻',
'请推荐一些科技新闻',
'能否分析一下AI对新闻行业的影响'
]
},
{
language: 'en',
messages: [
'Hello, what are the top news stories today?',
'Can you translate this Chinese news for me?',
'What do you think about the latest AI developments?'
]
}
]
let totalCost = 0
let sessionsCreated = 0
let messagesProcessed = 0
for (const conversation of testConversations) {
console.log(` Testing conversation in ${conversation.language}`)
// Create session
const sessionResult = await chatService.createChatSession(
`test-user-${Date.now()}`,
conversation.language
)
if (!sessionResult.success || !sessionResult.data) {
console.log(` ❌ Failed to create session: ${sessionResult.error}`)
continue
}
sessionsCreated++
const sessionId = sessionResult.data.id
// Process conversation
for (const message of conversation.messages) {
const response = await chatService.sendMessage(
sessionId,
message,
{
provider: 'openai',
temperature: 0.7,
contextWindow: 5
}
)
if (response.success && response.data) {
messagesProcessed++
totalCost += response.data.costUSD || 0
console.log(` ✅ Message processed: ${response.data.content.substring(0, 50)}...`)
} else {
console.log(` ❌ Message failed: ${response.error}`)
}
}
// Test session cleanup
await chatService.endChatSession(sessionId)
}
const endTime = Date.now()
const duration = endTime - startTime
const metrics: TestMetrics = {
testName,
startTime,
endTime,
duration,
success: messagesProcessed > 0,
metrics: {
costUSD: totalCost,
latencyMs: duration / messagesProcessed,
throughput: messagesProcessed / (duration / 1000)
}
}
this.totalCost += totalCost
console.log(`✅ ${testName} completed: ${sessionsCreated} sessions, ${messagesProcessed} messages`)
return metrics
} catch (error) {
const endTime = Date.now()
return {
testName,
startTime,
endTime,
duration: endTime - startTime,
success: false,
error: error instanceof Error ? error.message : String(error)
}
}
}
/**
* 集成测试4: 推荐系统性能测试
*/
async testRecommendationPerformance(): Promise<TestMetrics> {
const testName = 'Recommendation Performance Test'
const startTime = Date.now()
try {
console.log(`🧪 Starting ${testName}...`)
const recommendationService = this.serviceManager.getRecommendationService()
// Create test news content
const testNews: ContentInfo[] = Array.from({ length: 100 }, (_, i) => ({
id: `news-${i}`,
title: `Test News Article ${i}`,
content: `This is test content for news article ${i}. It contains various topics and keywords for testing recommendation algorithms.`,
originalLanguage: 'en',
publishedAt: Date.now() - Math.random() * 86400000, // Random time in last 24h
tags: [`tag-${i % 10}`, `category-${i % 5}`],
keywords: [`keyword-${i % 20}`, `topic-${i % 15}`],
quality: Math.random(),
viewCount: Math.floor(Math.random() * 1000),
likeCount: Math.floor(Math.random() * 100),
shareCount: Math.floor(Math.random() * 50),
status: 'published',
categoryId: `category-${i % 5}`
}))
const testUsers = Array.from({ length: 10 }, (_, i) => `test-user-${i}`)
let recommendationsGenerated = 0
// Test different recommendation algorithms
const algorithms = ['collaborative', 'content_based', 'hybrid'] as const
for (const algorithm of algorithms) {
console.log(` Testing ${algorithm} algorithm`)
for (const userId of testUsers) {
// Record some user behavior first
await recommendationService.recordUserBehavior({
userId,
contentId: testNews[Math.floor(Math.random() * testNews.length)].id,
actionType: 'view',
timestamp: Date.now(),
duration: Math.random() * 300 + 30
})
// Get recommendations
const recommendations = await recommendationService.getPersonalizedRecommendations(
userId,
testNews,
{
algorithm,
maxResults: 5,
diversityWeight: 0.3,
freshnessWeight: 0.4,
personalizedWeight: 0.3
}
)
if (recommendations.success && recommendations.data) {
recommendationsGenerated += recommendations.data.length
}
}
}
const endTime = Date.now()
const duration = endTime - startTime
const metrics: TestMetrics = {
testName,
startTime,
endTime,
duration,
success: recommendationsGenerated > 0,
metrics: {
latencyMs: duration / recommendationsGenerated,
throughput: recommendationsGenerated / (duration / 1000)
}
}
console.log(`✅ ${testName} completed: ${recommendationsGenerated} recommendations generated`)
return metrics
} catch (error) {
const endTime = Date.now()
return {
testName,
startTime,
endTime,
duration: endTime - startTime,
success: false,
error: error instanceof Error ? error.message : String(error)
}
}
}
/**
* 集成测试5: 内容处理管道压力测试
*/
async testContentPipelineStress(): Promise<TestMetrics> {
const testName = 'Content Pipeline Stress Test'
const startTime = Date.now()
try {
console.log(`🧪 Starting ${testName}...`)
const pipeline = this.serviceManager.getProcessingPipeline()
// Create large batch of test content
const testContent: ContentInfo[] = Array.from({ length: 50 }, (_, i) => ({
id: `stress-test-${i}`,
title: `Stress Test Article ${i}`,
content: `This is a stress test article number ${i}. It contains enough content to trigger AI processing steps including translation, analysis, and quality assessment. The content discusses various topics like technology, economics, and social issues to test the system's ability to handle diverse content types.`,
originalLanguage: 'en',
publishedAt: Date.now(),
tags: [`stress-${i}`, `test-${i % 10}`],
keywords: [],
quality: 0,
viewCount: 0,
likeCount: 0,
shareCount: 0,
status: 'draft'
}))
let processedCount = 0
let totalCost = 0
// Process in batches
const batchResult = await pipeline.processBatch(
testContent,
{
batchSize: 10,
concurrency: 3,
enableCaching: true,
onProgress: (completed, total) => {
console.log(` Progress: ${completed}/${total} items processed`)
},
onError: (error, item) => {
console.log(` Error processing ${item.id}: ${error}`)
}
}
)
if (batchResult.success && batchResult.data) {
processedCount = batchResult.data.length
totalCost = batchResult.data.reduce((sum, result) =>
sum + (result.costUSD || 0), 0
)
}
const endTime = Date.now()
const duration = endTime - startTime
const metrics: TestMetrics = {
testName,
startTime,
endTime,
duration,
success: processedCount > 0,
metrics: {
costUSD: totalCost,
latencyMs: duration / processedCount,
throughput: processedCount / (duration / 1000)
}
}
this.totalCost += totalCost
console.log(`✅ ${testName} completed: ${processedCount}/${testContent.length} items processed`)
return metrics
} catch (error) {
const endTime = Date.now()
return {
testName,
startTime,
endTime,
duration: endTime - startTime,
success: false,
error: error instanceof Error ? error.message : String(error)
}
}
}
/**
* 运行所有集成测试
*/
async runAllIntegrationTests(): Promise<{
success: boolean
results: TestMetrics[]
summary: {
totalTests: number
passedTests: number
failedTests: number
totalDuration: number
totalCost: number
averageLatency: number
totalThroughput: number
}
}> {
console.log('🚀 Starting AI News System Integration Tests...')
console.log('==============================================')
const startTime = Date.now()
try {
// Initialize service manager
const initResult = await this.serviceManager.initialize()
if (!initResult.success) {
throw new Error(`Failed to initialize services: ${initResult.error}`)
}
// Run all integration tests
const tests = [
() => this.testMultiProviderTranslation(),
() => this.testContentAnalysisEndToEnd(),
() => this.testChatSessionFlow(),
() => this.testRecommendationPerformance(),
() => this.testContentPipelineStress()
]
this.testResults = []
for (const testFn of tests) {
const result = await testFn()
this.testResults.push(result)
// Check cost limits
if (this.totalCost > this.config.costLimits.maxCostPerTest * tests.length) {
console.log('⚠️ Cost limit reached, stopping tests')
break
}
}
const endTime = Date.now()
const totalDuration = endTime - startTime
// Calculate summary statistics
const passedTests = this.testResults.filter(r => r.success).length
const failedTests = this.testResults.length - passedTests
const averageLatency = this.testResults.reduce((sum, r) =>
sum + (r.metrics?.latencyMs || 0), 0
) / this.testResults.length
const totalThroughput = this.testResults.reduce((sum, r) =>
sum + (r.metrics?.throughput || 0), 0
)
const summary = {
totalTests: this.testResults.length,
passedTests,
failedTests,
totalDuration,
totalCost: this.totalCost,
averageLatency,
totalThroughput
}
// Print results
this.printTestResults(summary)
return {
success: failedTests === 0,
results: this.testResults,
summary
}
} catch (error) {
console.error('💥 Integration test execution failed:', error)
return {
success: false,
results: this.testResults,
summary: {
totalTests: 0,
passedTests: 0,
failedTests: 1,
totalDuration: Date.now() - startTime,
totalCost: this.totalCost,
averageLatency: 0,
totalThroughput: 0
}
}
} finally {
// Cleanup
await this.serviceManager.shutdown()
}
}
/**
* 打印测试结果
*/
private printTestResults(summary: any): void {
console.log('\n📊 Integration Test Results:')
console.log('============================')
this.testResults.forEach(result => {
const status = result.success ? '✅' : '❌'
const duration = result.duration.toLocaleString()
const cost = result.metrics?.costUSD?.toFixed(4) || '0.0000'
const latency = result.metrics?.latencyMs?.toFixed(0) || 'N/A'
console.log(`${status} ${result.testName}`)
console.log(` Duration: ${duration}ms | Cost: $${cost} | Latency: ${latency}ms`)
if (!result.success && result.error) {
console.log(` Error: ${result.error}`)
}
})
console.log('\n📈 Summary Statistics:')
console.log('======================')
console.log(`✅ Passed: ${summary.passedTests}`)
console.log(`❌ Failed: ${summary.failedTests}`)
console.log(`📊 Success Rate: ${((summary.passedTests / summary.totalTests) * 100).toFixed(1)}%`)
console.log(`⏱️ Total Duration: ${summary.totalDuration.toLocaleString()}ms`)
console.log(`💰 Total Cost: $${summary.totalCost.toFixed(4)}`)
console.log(`📡 Average Latency: ${summary.averageLatency.toFixed(0)}ms`)
console.log(`🚀 Total Throughput: ${summary.totalThroughput.toFixed(2)} ops/sec`)
if (summary.failedTests === 0) {
console.log('\n🎉 All integration tests passed! The AI News System is production-ready.')
} else {
console.log('\n💥 Some integration tests failed. Please review the errors and fix the issues.')
}
}
}
// Export test runner function
export async function runIntegrationTests(config: IntegrationTestConfig): Promise<boolean> {
const testRunner = new AINewsIntegrationTest(config)
const result = await testRunner.runAllIntegrationTests()
return result.success
}
// Default configuration for running tests
export const defaultIntegrationConfig: IntegrationTestConfig = {
enableRealAPIs: false, // Set to true for real API testing
apiKeys: {
// Add your real API keys here for production testing
// openai: 'your-openai-api-key',
// google: 'your-google-api-key',
// baidu: { appId: 'your-baidu-app-id', secretKey: 'your-baidu-secret' }
},
testTimeout: 30000, // 30 seconds per test
retryAttempts: 3,
costLimits: {
maxCostPerTest: 5.0, // $5 per test
dailyLimit: 50.0 // $50 per day
}
}