Files
digital_person/app/src/androidTest/java/com/digitalperson/question/QuestionGenerationAgentTest.kt
gcw_4spBpAfv 4e33063a98 add photo
2026-04-23 15:21:24 +08:00

205 lines
7.3 KiB
Kotlin
Raw 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.

package com.digitalperson.question
import android.content.Context
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.digitalperson.data.AppDatabase
import com.digitalperson.data.entity.Question
import com.digitalperson.interaction.UserMemoryStore
import kotlinx.coroutines.runBlocking
import org.json.JSONObject
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import java.io.InputStream
/**
* 题目生成智能体测试
* 可以在模拟器或本地运行,不需要完整启动应用
*/
@RunWith(AndroidJUnit4::class)
class QuestionGenerationAgentTest {
private lateinit var context: Context
private lateinit var database: AppDatabase
private lateinit var userMemoryStore: UserMemoryStore
@Before
fun setUp() {
context = ApplicationProvider.getApplicationContext()
database = AppDatabase.getInstance(context)
userMemoryStore = UserMemoryStore(context)
}
@After
fun tearDown() {
// 清理测试数据
// database.clearAllTables()
}
@Test
fun testLoadPromptPoolFromJson() {
// 测试JSON提示词池加载
val inputStream: InputStream = context.assets.open("question_prompts.json")
val jsonString = inputStream.bufferedReader().use { it.readText() }
val jsonArray = org.json.JSONArray(jsonString)
println("✅ Loaded ${jsonArray.length()} prompts from JSON")
// 验证每个提示词的格式
for (i in 0 until jsonArray.length()) {
val json = jsonArray.getJSONObject(i)
assert(json.has("subject")) { "Missing subject in prompt $i" }
assert(json.has("grade")) { "Missing grade in prompt $i" }
assert(json.has("topic")) { "Missing topic in prompt $i" }
assert(json.has("difficulty")) { "Missing difficulty in prompt $i" }
assert(json.has("promptTemplate")) { "Missing promptTemplate in prompt $i" }
println(" - Prompt $i: ${json.getString("subject")} / ${json.getString("topic")}")
}
assert(jsonArray.length() > 0) { "Should have at least 1 prompt" }
}
@Test
fun testQuestionDatabaseOperations() = runBlocking {
// 测试数据库操作
val questionDao = database.questionDao()
// 插入测试题目
val testQuestion = Question(
id = 0,
content = "测试题目:苹果和香蕉哪个大?",
answer = "香蕉",
subject = "生活数学",
grade = 1,
difficulty = 1,
createdAt = System.currentTimeMillis()
)
val questionId = questionDao.insert(testQuestion)
println("✅ Inserted question with ID: $questionId")
// 查询题目
val retrievedQuestion = questionDao.getQuestionById(questionId)
assert(retrievedQuestion != null) { "Should retrieve inserted question" }
assert(retrievedQuestion?.content == testQuestion.content) { "Content should match" }
println("✅ Retrieved question: ${retrievedQuestion?.content}")
// 测试未答题计数
val userId = "test_user_001"
val count = questionDao.countUnansweredQuestions(userId)
println("✅ Unanswered questions count: $count")
// 测试获取随机未答题
val randomQuestion = questionDao.getRandomUnansweredQuestion(userId)
println("✅ Random unanswered question: ${randomQuestion?.content?.take(20)}...")
}
@Test
fun testJsonResponseParsing() {
// 测试LLM JSON响应解析
val testResponses = listOf(
"""{"content": "苹果和香蕉哪个大?", "answer": "香蕉", "explanation": "香蕉通常比苹果大"}""",
"""
{
"content": "2个苹果和5个苹果比谁多",
"answer": "5个苹果多",
"explanation": "5大于2"
}
""",
"""Some text before {"content": "测试题目", "answer": "答案"} some text after"""
)
testResponses.forEachIndexed { index, response ->
val json = extractJsonFromResponse(response)
if (json != null) {
println("✅ Test $index: Parsed successfully")
println(" Content: ${json.getString("content")}")
println(" Answer: ${json.getString("answer")}")
} else {
println("❌ Test $index: Failed to parse JSON")
}
}
}
@Test
fun testUserMemoryOperations() = runBlocking {
// 测试用户记忆操作
val userId = "test_user_001"
// 创建或更新用户
userMemoryStore.upsertUserSeen(userId, "测试小朋友")
println("✅ Created/updated user: $userId")
// 获取用户信息
val memory = userMemoryStore.getMemory(userId)
println("✅ User memory: displayName=${memory?.displayName}")
// 测试未答题计数
val unansweredCount = userMemoryStore.countUnansweredQuestions(userId)
println("✅ Unanswered questions for $userId: $unansweredCount")
}
@Test
fun testPromptTemplateBuilding() = runBlocking {
// 测试提示词模板构建
val userProfile = userMemoryStore.getMemory("test_user_001")
val promptTemplate = """
你是一个专门为特殊教育儿童设计题目的教育专家。请根据以下要求生成一个题目:
用户信息:
${userProfile?.displayName?.let { "姓名:$it" } ?: ""}
${userProfile?.age?.let { "年龄:$it" } ?: ""}
学科:生活数学
年级1
主题:比大小
难度1
具体要求:
基于以下学习目标针对一年级小学生出1道题目
1. 初步感知物品的大小
2. 会比较2个物品的大小
通用要求:
1. 题目要贴近生活,适合智力障碍儿童理解
2. 语言简单明了,避免复杂句式
3. 题目内容积极向上
4. 提供标准答案
5. 确保题目没有重复
6. 题目要有趣味性,能吸引学生注意力
请以JSON格式返回格式如下
{
"content": "题目内容",
"answer": "标准答案",
"explanation": "题目解析(可选)"
}
只返回JSON不要其他内容。
""".trimIndent()
println("✅ Generated prompt template:")
println(promptTemplate)
println("\n✅ Prompt length: ${promptTemplate.length} characters")
}
/**
* 从响应中提取JSON
*/
private fun extractJsonFromResponse(response: String): JSONObject? {
val trimmed = response.trim()
val start = trimmed.indexOf('{')
val end = trimmed.lastIndexOf('}')
if (start >= 0 && end > start) {
val jsonStr = trimmed.substring(start, end + 1)
return JSONObject(jsonStr)
}
return null
}
}