Skip to main content

Test Patterns

This guide provides complete, real-world examples for common testing scenarios. Each pattern builds on the test structure and vision concepts from previous guides.

App Startup Testing

describe("App Performance", function()
it("should measure cold start time", function()
-- Cold start test
openAppById(device.currentAppId(), { coldStart = true })
local time, frame = wait.forScreen("Home", { timeout = 30000 })
metric.record("cold_start_time", time)

assert.truthy(time)
end)

it("should measure warm start time", function()
-- Navigate away and back
control.home()
wait(2000)
openAppById(device.currentAppId())

local time, frame = wait.forScreen("Home", { timeout = 15000 })
metric.record("warm_start_time", time)

assert.truthy(time)
end)
end)
describe("Navigation", function()
it("should navigate between screens", function()
-- Ensure we start on home
wait.forScreen("Home", { timeout = 10000 })

-- Navigate to search
control.left()
control.up()
control.ok()

local time, frame = wait.forScreen("Search", { timeout = 10000 })
metric.record("navigate_to_search", time)

assert.truthy(frame)
end)
end)

Device-Specific Testing

Handle platform differences using device information:

describe("Cross-Platform Compatibility", function()
it("should handle device-specific navigation", function()
local device_info = device.info()
-- device_info structure:
-- {
-- make = "Roku" | "Chromecast" | "Samsung" | "LG" | ...,
-- model = "Ultra" | "Stick" | ...,
-- year = "2023" | "2022" | ...,
-- platform = "roku" | "chromecast" | "tizen" | ...
-- }

-- Platform-specific setup
if device_info.make == "Roku" then
wait(4000)
control.up()
control.right()
elseif device_info.make == "Chromecast" then
control.left()
control.down()
control.up() -- Reset cursor position
end

-- Common test logic
control.ok()
local time, frame = wait.forScreen("Expected", { timeout = 10000 })

assert.truthy(time)
print("Navigation completed on " .. device_info.make)
end)
end)

Video Playback Testing

describe("Video Playback", function()
it("should measure video startup time", function()
-- Navigate to a video
wait.forScreen("Home", { timeout = 30000 })
control.right()
control.ok()

-- Start playback
control.ok()

-- Measure loading time
local loadTime, frame = wait.forScreen("Loading", { timeout = 10000 })
metric.record("video_initial_load_time", loadTime)

-- Measure time to first motion
local motionTime, motionFrame = wait.forMotion("start", {
timeout = 10000,
includeAudio = true,
stableFrames = 3
})
metric.record("video_start_time", loadTime + motionTime)

assert.truthy(loadTime)
assert.truthy(motionTime)
end)

describe("Video Tests with Network Constraints", function()
local originalRateLimit

before(function()
-- Save the original rate limit before all tests
originalRateLimit = network.getCurrentRateLimit()
end)

after(function()
-- Restore the original rate limit after all tests
network.setRateLimit(originalRateLimit)
end)

it("should handle network constraints", function()
network.enableRateLimit(1, 1000000) -- 1Mbps down, 1000Mbps up

-- Start playback
control.ok()

-- Check for playback failures
local playbackFailed = wait.forPlaybackFailure({
timeout = 120000,
threshold = 4.2
})

metric.record("playback_failure", playbackFailed and 1 or 0)
assert.falsy(playbackFailed)
end)
end)

Text Input Testing

local keyboard = Keyboard.new()
:addMode("default", [[
a b c d e f
g h i j k l
m n o p q r
s t u v w x
y z 1 2 3 4
5 6 7 8 9 0
::clear:: ::space:: ::backspace::
]])
:setInitialFocus("a")
:setInitialMode("default")
:setAmbiguityRule("left")
end

describe("Search Functionality", function()
it("should enter text and search", function()
-- Navigate to search
wait.forScreen("Home", { timeout = 10000 })
control.left()
control.up()
control.ok()

wait.forScreen("Search", { timeout = 10000 })

-- Enter search query
control.enterText(keyboard, "test query")

-- Wait for results
local time, frame = wait.forMotion("end", {
timeout = 10000,
stableFrames = 15
})
metric.record("search_load_time", time)

assert.truthy(time)
end)
end)

AI-Powered Testing

describe("AI Navigation", function()
it("should find and click login button", function()
-- Use AI to locate and navigate to login
local sequence = ai.navigate("Login button", {
additionalInstructions = "Look for a prominent login or sign-in button"
})

assert.truthy(sequence)
print("AI generated sequence: " .. sequence)
end)

it("should verify screen content", function()
-- Use AI to verify what's visible
local response = ai.prompt("What is the main content on this screen?")

assert.truthy(response)
print("AI response: " .. response)
end)
end)

What's Next?

You now have comprehensive patterns for testing TV applications! These examples cover the most common scenarios you'll encounter. Mix and match these patterns to create robust test suites that work across all TV platforms.

For questions or advanced use cases, refer back to: