move claude-marketplace to ai-proj-helper

This commit is contained in:
2026-03-12 21:42:30 +08:00
parent d7b6835e1d
commit 43585b8504
188 changed files with 39510 additions and 0 deletions

View File

@@ -0,0 +1,145 @@
# Android 测试 (JUnit + Espresso)
## 运行测试
```bash
# 单元测试
./gradlew test
# UI 测试
./gradlew connectedAndroidTest
```
## 单元测试 (JUnit)
```kotlin
class TaskViewModelTest {
@get:Rule
val instantTaskRule = InstantTaskExecutorRule()
@get:Rule
val coroutineRule = MainCoroutineRule()
private lateinit var viewModel: TaskViewModel
private lateinit var repository: FakeTaskRepository
@Before
fun setup() {
repository = FakeTaskRepository()
viewModel = TaskViewModel(repository)
}
@Test
fun `fetchTasks updates state`() = runTest {
// Arrange
repository.addTasks(listOf(
Task(1, "Task 1"),
Task(2, "Task 2")
))
// Act
viewModel.fetchTasks()
// Assert
val tasks = viewModel.tasks.first()
assertEquals(2, tasks.size)
}
@Test
fun `createTask adds task`() = runTest {
// Act
viewModel.createTask("New Task")
// Assert
val tasks = viewModel.tasks.first()
assertTrue(tasks.any { it.title == "New Task" })
}
}
```
## UI 测试 (Espresso)
```kotlin
@RunWith(AndroidJUnit4::class)
@LargeTest
class TaskListActivityTest {
@get:Rule
val activityRule = ActivityScenarioRule(TaskListActivity::class.java)
@Test
fun displayTaskList() {
onView(withId(R.id.taskList))
.check(matches(isDisplayed()))
}
@Test
fun clickTask_opensDetail() {
onView(withId(R.id.taskList))
.perform(RecyclerViewActions.actionOnItemAtPosition<TaskViewHolder>(0, click()))
onView(withId(R.id.taskDetail))
.check(matches(isDisplayed()))
}
@Test
fun addTask_showsInList() {
// Click add button
onView(withId(R.id.addButton)).perform(click())
// Enter title
onView(withId(R.id.titleInput))
.perform(typeText("New Task"), closeSoftKeyboard())
// Save
onView(withId(R.id.saveButton)).perform(click())
// Verify in list
onView(withText("New Task"))
.check(matches(isDisplayed()))
}
}
```
## Compose UI 测试
```kotlin
@RunWith(AndroidJUnit4::class)
class TaskListScreenTest {
@get:Rule
val composeRule = createComposeRule()
@Test
fun taskList_displays() {
val tasks = listOf(
Task(1, "Task 1"),
Task(2, "Task 2")
)
composeRule.setContent {
TaskListScreen(tasks = tasks)
}
composeRule.onNodeWithText("Task 1").assertExists()
composeRule.onNodeWithText("Task 2").assertExists()
}
@Test
fun taskClick_callsOnClick() {
var clickedId: Int? = null
val tasks = listOf(Task(1, "Task 1"))
composeRule.setContent {
TaskListScreen(
tasks = tasks,
onTaskClick = { clickedId = it.id }
)
}
composeRule.onNodeWithText("Task 1").performClick()
assertEquals(1, clickedId)
}
}
```