From 6d097f4851774081e8a8501f22aa4e82cf84802c Mon Sep 17 00:00:00 2001 From: Emily Ploszaj Date: Mon, 11 May 2026 16:41:20 -0500 Subject: [PATCH 1/3] Adjust testing for model deprecation --- .../kotlin/com/google/firebase/ai/AIModels.kt | 20 ++++++++++--------- .../ai/ChatTemplateIntegrationTests.kt | 16 +++++++-------- .../firebase/ai/TemplateIntegrationTests.kt | 10 ++++++---- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/AIModels.kt b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/AIModels.kt index 4e6bb018dac..f2f22b6bf6a 100644 --- a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/AIModels.kt +++ b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/AIModels.kt @@ -24,17 +24,14 @@ import com.google.firebase.ai.type.PublicPreviewAPI class AIModels { companion object { - private val API_KEY: String = "" - private val APP_ID: String = "" - private val PROJECT_ID: String = "fireescape-integ-tests" // General purpose models var app: FirebaseApp? = null lateinit var vertexAIFlashModel: GenerativeModel lateinit var vertexAIFlashLiteModel: GenerativeModel lateinit var googleAIFlashModel: GenerativeModel lateinit var googleAIFlashLiteModel: GenerativeModel - lateinit var vertexAITemplateModel: TemplateGenerativeModel - lateinit var googleAITemplateModel: TemplateGenerativeModel + lateinit var vertexAITemplateModel: TemplateModel + lateinit var googleAITemplateModel: TemplateModel /** Returns a list of general purpose models to test */ fun getModels(): List { @@ -50,7 +47,7 @@ class AIModels { } /** Returns a list of template models to test */ - fun getTemplateModels(): List { + fun getTemplateModels(): List { if (app == null) { setup() } @@ -80,7 +77,7 @@ class AIModels { googleAIFlashModel = FirebaseAI.getInstance(app!!, GenerativeBackend.googleAI()) .generativeModel( - modelName = "gemini-2.5-flash", + modelName = "gemini-3-flash-preview", ) googleAIFlashLiteModel = FirebaseAI.getInstance(app!!, GenerativeBackend.googleAI()) @@ -88,9 +85,14 @@ class AIModels { modelName = "gemini-2.5-flash-lite", ) vertexAITemplateModel = - FirebaseAI.getInstance(app!!, GenerativeBackend.vertexAI()).templateGenerativeModel() + TemplateModel("vertex-ai", + FirebaseAI.getInstance(app!!, GenerativeBackend.vertexAI()).templateGenerativeModel()) googleAITemplateModel = - FirebaseAI.getInstance(app!!, GenerativeBackend.googleAI()).templateGenerativeModel() + TemplateModel("google-ai", + FirebaseAI.getInstance(app!!, GenerativeBackend.googleAI()).templateGenerativeModel()) } } } + +@OptIn(PublicPreviewAPI::class) +data class TemplateModel(val backend: String, val model: TemplateGenerativeModel) diff --git a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/ChatTemplateIntegrationTests.kt b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/ChatTemplateIntegrationTests.kt index 2971b5fc32c..6482aebb520 100644 --- a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/ChatTemplateIntegrationTests.kt +++ b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/ChatTemplateIntegrationTests.kt @@ -61,9 +61,9 @@ class ChatTemplateIntegrationTests { @Test fun testTemplateChat_sendMessage() { - for (model in getTemplateModels()) { + for (template in getTemplateModels()) { runBlocking { - val chat = model.startChat(templateId, inputs) + val chat = template.model.startChat("$templateId-${template.backend}", inputs) val response = chat.sendMessage("which number is higher, one or ten?") response.candidates.isNotEmpty() shouldBe true @@ -76,9 +76,9 @@ class ChatTemplateIntegrationTests { @Test fun testTemplateChat_sendMessageStream() { - for (model in getTemplateModels()) { + for (template in getTemplateModels()) { runBlocking { - val chat = model.startChat(templateId, inputs) + val chat = template.model.startChat("$templateId-${template.backend}", inputs) val responses = chat.sendMessageStream("which number is higher, one or ten?").toList() responses.isNotEmpty() shouldBe true responses.joinToString { it.text ?: "" } shouldContainIgnoringCase "ten" @@ -89,22 +89,22 @@ class ChatTemplateIntegrationTests { @Test fun testTemplateChat_withHistory() { - for (model in getTemplateModels()) { + for (template in getTemplateModels()) { runBlocking { val history = listOf( content("user") { text("which number is higher, one or ten?") }, content("model") { text("Ten.") } ) - val chat = model.startChat(templateId, inputs, history) + val chat = template.model.startChat("$templateId-${template.backend}", inputs, history) chat.history.size shouldBe 2 val response = chat.sendMessage( - "Please concatenate them both, first the smaller one, then the bigger one." + "Please concatenate them both, first the smaller one, then the bigger one. Do not use punctuation or spaces." ) response.candidates.isNotEmpty() shouldBe true - response.text shouldContainIgnoringCase "oneten" + response.text?.replace(" ", "") shouldContainIgnoringCase "oneten" chat.history.size shouldBe 4 } diff --git a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/TemplateIntegrationTests.kt b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/TemplateIntegrationTests.kt index 6f9b595aeb9..bc689525409 100644 --- a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/TemplateIntegrationTests.kt +++ b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/TemplateIntegrationTests.kt @@ -53,9 +53,9 @@ class TemplateIntegrationTests { @Test fun testTemplateGenerateContent() { - for (model in getTemplateModels()) { + for (template in getTemplateModels()) { runBlocking { - val response = model.generateContent(templateId, inputs) + val response = template.model.generateContent("$templateId-${template.backend}", inputs) response.candidates.shouldNotBeEmpty() response.text shouldContainIgnoringCase customerName @@ -66,12 +66,14 @@ class TemplateIntegrationTests { @Test fun testTemplateGenerateContentStream() { - for (model in getTemplateModels()) { + for (template in getTemplateModels()) { runBlocking { - val responses = model.generateContentStream(templateId, inputs).toList() + val responses = template.model.generateContentStream("$templateId-${template.backend}", inputs).toList() responses .joinToString { it.text ?: "" } .lowercase() + .replace(",", "") + .replace(" ", " ") // Model sometimes doubles spacing .let { it shouldContainIgnoringCase customerName it shouldContainIgnoringCase topic From b1af1b3676c88adf87fa519a3164d1a9a917dcba Mon Sep 17 00:00:00 2001 From: Emily Ploszaj Date: Mon, 11 May 2026 17:01:05 -0500 Subject: [PATCH 2/3] Format --- .../kotlin/com/google/firebase/ai/AIModels.kt | 12 ++++++++---- .../google/firebase/ai/TemplateIntegrationTests.kt | 3 ++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/AIModels.kt b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/AIModels.kt index f2f22b6bf6a..6005e963caa 100644 --- a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/AIModels.kt +++ b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/AIModels.kt @@ -85,11 +85,15 @@ class AIModels { modelName = "gemini-2.5-flash-lite", ) vertexAITemplateModel = - TemplateModel("vertex-ai", - FirebaseAI.getInstance(app!!, GenerativeBackend.vertexAI()).templateGenerativeModel()) + TemplateModel( + "vertex-ai", + FirebaseAI.getInstance(app!!, GenerativeBackend.vertexAI()).templateGenerativeModel() + ) googleAITemplateModel = - TemplateModel("google-ai", - FirebaseAI.getInstance(app!!, GenerativeBackend.googleAI()).templateGenerativeModel()) + TemplateModel( + "google-ai", + FirebaseAI.getInstance(app!!, GenerativeBackend.googleAI()).templateGenerativeModel() + ) } } } diff --git a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/TemplateIntegrationTests.kt b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/TemplateIntegrationTests.kt index bc689525409..5f3cf2c110c 100644 --- a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/TemplateIntegrationTests.kt +++ b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/TemplateIntegrationTests.kt @@ -68,7 +68,8 @@ class TemplateIntegrationTests { fun testTemplateGenerateContentStream() { for (template in getTemplateModels()) { runBlocking { - val responses = template.model.generateContentStream("$templateId-${template.backend}", inputs).toList() + val responses = + template.model.generateContentStream("$templateId-${template.backend}", inputs).toList() responses .joinToString { it.text ?: "" } .lowercase() From 7a79ff0d0ac545f66447fb8b0b5baef2072745ff Mon Sep 17 00:00:00 2001 From: Emily Ploszaj Date: Fri, 15 May 2026 14:23:39 -0500 Subject: [PATCH 3/3] Adjustments --- .../kotlin/com/google/firebase/ai/AIModels.kt | 24 +--- .../ai/ChatTemplateIntegrationTests.kt | 120 +++++++++++------- .../firebase/ai/TemplateIntegrationTests.kt | 70 ++++++---- 3 files changed, 126 insertions(+), 88 deletions(-) diff --git a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/AIModels.kt b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/AIModels.kt index 6005e963caa..c4df8a889a8 100644 --- a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/AIModels.kt +++ b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/AIModels.kt @@ -30,8 +30,8 @@ class AIModels { lateinit var vertexAIFlashLiteModel: GenerativeModel lateinit var googleAIFlashModel: GenerativeModel lateinit var googleAIFlashLiteModel: GenerativeModel - lateinit var vertexAITemplateModel: TemplateModel - lateinit var googleAITemplateModel: TemplateModel + lateinit var vertexAITemplateModel: TemplateGenerativeModel + lateinit var googleAITemplateModel: TemplateGenerativeModel /** Returns a list of general purpose models to test */ fun getModels(): List { @@ -46,14 +46,6 @@ class AIModels { ) } - /** Returns a list of template models to test */ - fun getTemplateModels(): List { - if (app == null) { - setup() - } - return listOf(vertexAITemplateModel, googleAITemplateModel) - } - fun app(): FirebaseApp { if (app == null) { setup() @@ -77,7 +69,7 @@ class AIModels { googleAIFlashModel = FirebaseAI.getInstance(app!!, GenerativeBackend.googleAI()) .generativeModel( - modelName = "gemini-3-flash-preview", + modelName = "gemini-3.1-flash-lite", ) googleAIFlashLiteModel = FirebaseAI.getInstance(app!!, GenerativeBackend.googleAI()) @@ -85,15 +77,9 @@ class AIModels { modelName = "gemini-2.5-flash-lite", ) vertexAITemplateModel = - TemplateModel( - "vertex-ai", - FirebaseAI.getInstance(app!!, GenerativeBackend.vertexAI()).templateGenerativeModel() - ) + FirebaseAI.getInstance(app!!, GenerativeBackend.vertexAI()).templateGenerativeModel() googleAITemplateModel = - TemplateModel( - "google-ai", - FirebaseAI.getInstance(app!!, GenerativeBackend.googleAI()).templateGenerativeModel() - ) + FirebaseAI.getInstance(app!!, GenerativeBackend.googleAI()).templateGenerativeModel() } } } diff --git a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/ChatTemplateIntegrationTests.kt b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/ChatTemplateIntegrationTests.kt index 6482aebb520..45364afb09f 100644 --- a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/ChatTemplateIntegrationTests.kt +++ b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/ChatTemplateIntegrationTests.kt @@ -16,13 +16,13 @@ package com.google.firebase.ai -import com.google.firebase.ai.AIModels.Companion.getTemplateModels import com.google.firebase.ai.type.PublicPreviewAPI import com.google.firebase.ai.type.content import io.kotest.matchers.shouldBe import io.kotest.matchers.string.shouldContainIgnoringCase import kotlinx.coroutines.flow.toList import kotlinx.coroutines.runBlocking +import org.junit.Before import org.junit.Test @OptIn(PublicPreviewAPI::class) @@ -59,55 +59,87 @@ class ChatTemplateIntegrationTests { private val topic = "Firebase" private val inputs = mapOf("customerName" to customerName, "topic" to topic) + @Before + fun setup() { + AIModels.setup() + } + + @Test + fun testTemplateChat_sendMessage_googleAI(): Unit = runBlocking { + val chat = AIModels.googleAITemplateModel.startChat("$templateId-google-ai", inputs) + val response = chat.sendMessage("which number is higher, one or ten?") + + response.candidates.isNotEmpty() shouldBe true + response.text shouldContainIgnoringCase "ten" + + chat.history.size shouldBe 2 + } + @Test + fun testTemplateChat_sendMessage_vertexAI(): Unit = runBlocking { + val chat = AIModels.vertexAITemplateModel.startChat("$templateId-vertex-ai", inputs) + val response = chat.sendMessage("which number is higher, one or ten?") + + response.candidates.isNotEmpty() shouldBe true + response.text shouldContainIgnoringCase "ten" + + chat.history.size shouldBe 2 + } + @Test - fun testTemplateChat_sendMessage() { - for (template in getTemplateModels()) { - runBlocking { - val chat = template.model.startChat("$templateId-${template.backend}", inputs) - val response = chat.sendMessage("which number is higher, one or ten?") - - response.candidates.isNotEmpty() shouldBe true - response.text shouldContainIgnoringCase "ten" - - chat.history.size shouldBe 2 - } - } + fun testTemplateChat_sendMessageStream_googleAI(): Unit = runBlocking { + val chat = AIModels.googleAITemplateModel.startChat("$templateId-google-ai", inputs) + val responses = chat.sendMessageStream("which number is higher, one or ten?").toList() + responses.isNotEmpty() shouldBe true + responses.joinToString { it.text ?: "" } shouldContainIgnoringCase "ten" + chat.history.size shouldBe 2 } @Test - fun testTemplateChat_sendMessageStream() { - for (template in getTemplateModels()) { - runBlocking { - val chat = template.model.startChat("$templateId-${template.backend}", inputs) - val responses = chat.sendMessageStream("which number is higher, one or ten?").toList() - responses.isNotEmpty() shouldBe true - responses.joinToString { it.text ?: "" } shouldContainIgnoringCase "ten" - chat.history.size shouldBe 2 - } - } + fun testTemplateChat_sendMessageStream_vertexAI(): Unit = runBlocking { + val chat = AIModels.vertexAITemplateModel.startChat("$templateId-vertex-ai", inputs) + val responses = chat.sendMessageStream("which number is higher, one or ten?").toList() + responses.isNotEmpty() shouldBe true + responses.joinToString { it.text ?: "" } shouldContainIgnoringCase "ten" + chat.history.size shouldBe 2 } @Test - fun testTemplateChat_withHistory() { - for (template in getTemplateModels()) { - runBlocking { - val history = - listOf( - content("user") { text("which number is higher, one or ten?") }, - content("model") { text("Ten.") } - ) - val chat = template.model.startChat("$templateId-${template.backend}", inputs, history) - chat.history.size shouldBe 2 - val response = - chat.sendMessage( - "Please concatenate them both, first the smaller one, then the bigger one. Do not use punctuation or spaces." - ) - - response.candidates.isNotEmpty() shouldBe true - response.text?.replace(" ", "") shouldContainIgnoringCase "oneten" - - chat.history.size shouldBe 4 - } - } + fun testTemplateChat_withHistory_googleAI(): Unit = runBlocking { + val history = + listOf( + content("user") { text("which number is higher, one or ten?") }, + content("model") { text("Ten.") } + ) + val chat = AIModels.googleAITemplateModel.startChat("$templateId-google-ai", inputs, history) + chat.history.size shouldBe 2 + val response = + chat.sendMessage( + "Please concatenate them both, first the smaller one, then the bigger one. Do not use punctuation or spaces." + ) + + response.candidates.isNotEmpty() shouldBe true + response.text?.replace(" ", "") shouldContainIgnoringCase "oneten" + + chat.history.size shouldBe 4 + } + + @Test + fun testTemplateChat_withHistory_vertexAI(): Unit = runBlocking { + val history = + listOf( + content("user") { text("which number is higher, one or ten?") }, + content("model") { text("Ten.") } + ) + val chat = AIModels.googleAITemplateModel.startChat("$templateId-google-ai", inputs, history) + chat.history.size shouldBe 2 + val response = + chat.sendMessage( + "Please concatenate them both, first the smaller one, then the bigger one. Do not use punctuation or spaces." + ) + + response.candidates.isNotEmpty() shouldBe true + response.text?.replace(" ", "") shouldContainIgnoringCase "oneten" + + chat.history.size shouldBe 4 } } diff --git a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/TemplateIntegrationTests.kt b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/TemplateIntegrationTests.kt index 5f3cf2c110c..f4a2939ba17 100644 --- a/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/TemplateIntegrationTests.kt +++ b/ai-logic/firebase-ai/src/androidTest/kotlin/com/google/firebase/ai/TemplateIntegrationTests.kt @@ -16,13 +16,12 @@ package com.google.firebase.ai -import com.google.firebase.ai.AIModels.Companion.getTemplateModels import com.google.firebase.ai.type.PublicPreviewAPI import io.kotest.matchers.collections.shouldNotBeEmpty import io.kotest.matchers.string.shouldContainIgnoringCase -import io.kotest.matchers.string.shouldNotBeEmpty import kotlinx.coroutines.flow.toList import kotlinx.coroutines.runBlocking +import org.junit.Before import org.junit.Test @OptIn(PublicPreviewAPI::class) @@ -51,35 +50,56 @@ class TemplateIntegrationTests { private val topic = "Firebase" private val inputs = mapOf("customerName" to customerName, "topic" to topic) + @Before + fun setup() { + AIModels.setup() + } + @Test - fun testTemplateGenerateContent() { - for (template in getTemplateModels()) { - runBlocking { - val response = template.model.generateContent("$templateId-${template.backend}", inputs) + fun testTemplateGenerateContent_googleAI(): Unit = runBlocking { + val response = AIModels.googleAITemplateModel.generateContent("$templateId-google-ai", inputs) - response.candidates.shouldNotBeEmpty() - response.text shouldContainIgnoringCase customerName - response.text shouldContainIgnoringCase topic + response.candidates.shouldNotBeEmpty() + response.text shouldContainIgnoringCase customerName + response.text shouldContainIgnoringCase topic + } + + @Test + fun testTemplateGenerateContent_vertexAI(): Unit = runBlocking { + val response = AIModels.vertexAITemplateModel.generateContent("$templateId-vertex-ai", inputs) + + response.candidates.shouldNotBeEmpty() + response.text shouldContainIgnoringCase customerName + response.text shouldContainIgnoringCase topic + } + + @Test + fun testTemplateGenerateContentStream_googleAI(): Unit = runBlocking { + val responses = + AIModels.googleAITemplateModel.generateContentStream("$templateId-google-ai", inputs).toList() + responses + .joinToString { it.text ?: "" } + .lowercase() + .replace(",", "") + .replace(" ", " ") // Model sometimes doubles spacing + .let { + it shouldContainIgnoringCase customerName + it shouldContainIgnoringCase topic } - } } @Test - fun testTemplateGenerateContentStream() { - for (template in getTemplateModels()) { - runBlocking { - val responses = - template.model.generateContentStream("$templateId-${template.backend}", inputs).toList() - responses - .joinToString { it.text ?: "" } - .lowercase() - .replace(",", "") - .replace(" ", " ") // Model sometimes doubles spacing - .let { - it shouldContainIgnoringCase customerName - it shouldContainIgnoringCase topic - } + fun testTemplateGenerateContentStream_vertexAI(): Unit = runBlocking { + val responses = + AIModels.vertexAITemplateModel.generateContentStream("$templateId-vertex-ai", inputs).toList() + responses + .joinToString { it.text ?: "" } + .lowercase() + .replace(",", "") + .replace(" ", " ") // Model sometimes doubles spacing + .let { + it shouldContainIgnoringCase customerName + it shouldContainIgnoringCase topic } - } } }