Skip to content
GitHubDiscord

Your First Test

Open In Colab

Write and run your first Giskard Checks test in under ten minutes β€” no API key or LLM required.

By the end of this tutorial you will have a ScenarioResult that shows a passing check against a pure-Python function. This gives you the full test-writing loop β€” define a scenario, run it, inspect the result β€” before introducing any external services.

If you haven’t installed Giskard Checks yet, see the Installation guide first.

You need something to test. Create a simple greeting function:

No LLM, no API calls β€” just a Python function that returns a predictable string. Starting with a pure function removes all external dependencies so you can focus entirely on the testing mechanics.

def greet(name: str) -> str:
return f"Hello, {name}!"

A Scenario chains together one or more interactions and checks. Each .interact() call provides an input and the callable that produces the output. Each .check() call asserts something about the result.

Equals compares the value at the trace path trace.last.outputs against expected_value. If they match the check passes; otherwise it fails. Notice that trace.last.outputs is a dot-separated path β€” this is how all built-in checks address values stored in the trace, so you’ll see this pattern throughout the documentation.

from giskard.checks import Scenario, Equals
scenario = (
Scenario("greet_alice")
.interact(
inputs="Alice",
outputs=lambda inputs: greet(inputs),
)
.check(
Equals(
name="correct_greeting",
expected_value="Hello, Alice!",
key="trace.last.outputs",
)
)
)

Scenarios are async, so in a notebook you can await them directly.

result = await scenario.run()
result.print_report()

Output

──────────────────────────────────────────────────── βœ… PASSED ────────────────────────────────────────────────────
correct_greeting        PASS    
────────────────────────────────────────────────────── Trace ──────────────────────────────────────────────────────
────────────────────────────────────────────────── Interaction 1 ──────────────────────────────────────────────────
Inputs: 'Alice'
Outputs: 'Hello, Alice!'
────────────────────────────────────────────────── 1 step in 5ms ──────────────────────────────────────────────────

Outside a notebook there is no running event loop, so you wrap the call with asyncio.run.

import asyncio
from giskard.checks import Scenario, Equals
def greet(name: str) -> str:
return f"Hello, {name}!"
scenario = (
Scenario("greet_alice")
.interact(
inputs="Alice",
outputs=lambda inputs: greet(inputs),
)
.check(
Equals(
name="correct_greeting",
expected_value="Hello, Alice!",
key="trace.last.outputs",
)
)
)
result = asyncio.run(scenario.run())
result.print_report()

Output

──────────────────────────────────────────────────── βœ… PASSED ────────────────────────────────────────────────────
correct_greeting        PASS    
────────────────────────────────────────────────────── Trace ──────────────────────────────────────────────────────
────────────────────────────────────────────────── Interaction 1 ──────────────────────────────────────────────────
Inputs: 'Alice'
Outputs: 'Hello, Alice!'
────────────────────────────────────────────────── 1 step in 3ms ──────────────────────────────────────────────────

Your function always returns the expected string, so the test always passes. To see what a failure looks like, change expected_value to something that won’t match:

scenario = (
Scenario("greet_alice")
.interact(
inputs="Alice",
outputs=lambda inputs: greet(inputs),
)
.check(
Equals(
name="correct_greeting",
expected_value="Hi, Alice!", # wrong β€” greet() returns "Hello, Alice!"
key="trace.last.outputs",
)
)
)
result = await scenario.run()
result.print_report()

Output

──────────────────────────────────────────────────── ❌ FAILED ────────────────────────────────────────────────────
correct_greeting        FAIL    Expected value equal to 'Hi, Alice!' but got 'Hello, Alice!'
────────────────────────────────────────────────────── Trace ──────────────────────────────────────────────────────
────────────────────────────────────────────────── Interaction 1 ──────────────────────────────────────────────────
Inputs: 'Alice'
Outputs: 'Hello, Alice!'
────────────────────────────────────────────────── 1 step in 3ms ──────────────────────────────────────────────────

Failures are descriptive β€” the message tells you the expected vs. actual value.

Reset expected_value back to "Hello, Alice!" before continuing.

A real AI system is less predictable than a pure Python function β€” the next tutorial shows you how to configure a generator and test an actual LLM call:

Your First LLM Call