Skip to content

Commit 81c1a61

Browse files
authored
Add run_test prompt (#9292)
* Add initial MCP prompt for running automated tests * Fix typos
1 parent c318b06 commit 81c1a61

File tree

3 files changed

+127
-1
lines changed

3 files changed

+127
-1
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { isEnabled } from "../../../experiments";
2+
import { runTest } from "./run_test";
3+
import type { ServerPrompt } from "../../prompt";
4+
5+
export const apptestingPrompts: ServerPrompt[] = [];
6+
7+
if (isEnabled("mcpalpha")) {
8+
apptestingPrompts.push(runTest);
9+
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import { prompt } from "../../prompt";
2+
3+
export const runTest = prompt(
4+
{
5+
name: "run_test",
6+
description: "Run a test with the Firebase App Testing agent",
7+
omitPrefix: false,
8+
arguments: [
9+
{
10+
name: "testDescription",
11+
description:
12+
"Description of the test you want to run. The agent will use the description to generate a test case that will be used as input for the AI-guided test",
13+
required: false,
14+
},
15+
],
16+
annotations: {
17+
title: "Run an App Testing AI-guided test",
18+
},
19+
},
20+
async ({ testDescription }, { accountEmail, projectId }) => {
21+
return [
22+
{
23+
role: "user" as const,
24+
content: {
25+
type: "text",
26+
text: `
27+
You are going to help a developer run a test for their mobile app
28+
using the Firebase App Testing agent.
29+
30+
Active user: ${accountEmail || "<NONE>"}
31+
Project ID: ${projectId || "<NONE>"}
32+
33+
## Prerequisites
34+
35+
Here are a list of prerequisite steps that must be completed before running a test.
36+
37+
1. **Make sure this is an Android app**. The App Testing agent only works with Android apps. If
38+
this is not an Android app, instruct the user that this command can't be used with this app.
39+
40+
2. **Make sure the user is logged in. No App Testing tools will work if the user is not logged in.**
41+
a. Use the \`firebase_get_environment\` tool to verify that the user is logged in.
42+
b. If the Firebase 'Active user' is set to <NONE>, instruct the user to run \`firebase login\`
43+
before continuing. Ignore other fields that are set to <NONE>. We are just making sure the
44+
user is logged in.
45+
46+
3. **Get the Firebase app ID.**
47+
48+
The \`firebase_get_environment\` tool should return a list of detected app IDs, where the app
49+
ID contains four colon (":") delimited parts: a version number (typically "1"), a project
50+
number, a platform type ("android", "ios", or "web"). Ask the user confirm if there is only
51+
a single app ID, or to choose one if there are multiple app IDs.
52+
53+
If the tool does not return a list of detected apps, just ask the user for it.
54+
55+
4. **Confirm that the application ID of the app matches the bundle ID of the Firebase app**
56+
57+
The \`firebase_get_environment\` tool returns a list of detected app IDs mapped to their corresponding
58+
bundle IDs. If the developer selected an app ID from the the list of detected app IDs, this already
59+
confirms that the bundle ID matches the app ID. If not, get the application IDs of all the variants of
60+
the app. Then get the bundle ID of the Firebase app by calling the \`firebase_list_apps\` tool and
61+
confirming that the \`namespace\` field of the app with the selected app ID matches one of the application
62+
IDs of the variants.
63+
64+
## Test Case Generation
65+
66+
Once you have completed the required steps, you need the help the user generate a "test case", which is the input to the
67+
app testing agent. A test case consists of multiple steps where each step contains the following fields:
68+
69+
* Goal (required): In one sentence or less, describe what you want the agent to do in this step.
70+
* Hint (optional): Provide additional information to help Gemini understand and navigate your app.
71+
* Success Criteria (optional): Your success criteria should be phrased as an observation, such as 'The screen shows a
72+
success message' or 'The checkout page is visible'.
73+
74+
The developer has optionally specified the following description for their test:
75+
* ${testDescription}
76+
77+
Sometimes, test descriptions that developers provide tend to be too vague and lack the necessary details for the
78+
app testing agent to be able to reliably re-run the tests with consistent results. Test cases should follow these
79+
guidelines to ensure that they are structured in a way to make the agent more reliable.
80+
81+
* Prefer multiple steps with smaller, detailed goals. Broader, more open-ended goals can lead to unreliable tests
82+
since the app testing agent can more easily veer of course. It should only take a few actions to accomplish a goal.
83+
For example, if a step has a list in it, it should probably be broken up into multiple steps. Steps do not need
84+
to be too small though. The test case should provide a good balance between strict guidance and flexibility. As a
85+
rule of thumb, each step should require between 2-5 actions.
86+
* Include a hint and success criteria whenever possible. Specifically, try to always include a success criteria to help
87+
the agent determine when the goal has been completed.
88+
* Avoid functionality that the app testing agent struggles with. The app testing agent struggles with the following:
89+
* Journeys that require specific timing (like observing that something should be visible for a certain number of
90+
seconds), interacting with moving or transient elements, etc.
91+
* Playing games or generally interacting with drawn visuals that would require pixel input
92+
* Complex swipe interactions, multi-finger gestures, etc., which aren't supported
93+
94+
First, analyze the code to get an understanding of how the app works. Get all the available screens in the app and the
95+
different actions for each screen. Understand what functionality is and isn't available to the app testing agent.
96+
Only include specific details in the test case if you are certain they will be available to the agent, otherwise the
97+
agent will likely fail if it tries to follow specific guidance that doesn't work (e.g. click the 'Play' button but the
98+
button isn't visible to the app testing agent). Do not include Android resource ids in the test case. Include
99+
explanations that prove that each step includes between 2-5 actions. Using that information as context and the guidelines
100+
above, convert the test description provided by the user to make it easier for the agent to follow so that the tests can
101+
be re-run reliably. Generate an explanation on why you generated the new test case the way you did, and then generate the
102+
new test case, which again is an array of steps where each step contains a goal, hint, and success criteria. Show this
103+
to the user and have them confirm before moving forward.
104+
105+
## Run Test
106+
107+
Use the apptesting_run_test tool to run an automated test with the following as input:
108+
* The generated test case that as been confirmed by the user
109+
* An APK. If there is no APK present, build the app to produce one. Make sure to build the variant of the app
110+
with the same bundle ID as the Firebase app.
111+
`.trim(),
112+
},
113+
},
114+
];
115+
},
116+
);

src/mcp/prompts/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { ServerPrompt } from "../prompt";
33
import { corePrompts } from "./core";
44
import { dataconnectPrompts } from "./dataconnect";
55
import { crashlyticsPrompts } from "./crashlytics";
6+
import { apptestingPrompts } from "./apptesting";
67

78
const prompts: Record<ServerFeature, ServerPrompt[]> = {
89
core: corePrompts,
@@ -14,7 +15,7 @@ const prompts: Record<ServerFeature, ServerPrompt[]> = {
1415
functions: [],
1516
remoteconfig: [],
1617
crashlytics: crashlyticsPrompts,
17-
apptesting: [],
18+
apptesting: apptestingPrompts,
1819
apphosting: [],
1920
database: [],
2021
};

0 commit comments

Comments
 (0)