Welcome to the first chapter of the CrewAI testing tutorial!
Before we can start recording network requests or testing complex AI agents, we need a clean workspace. Imagine trying to paint a masterpiece on a canvas that someone else has already scribbled onβit would be a disaster!
In software testing, we need a "fresh canvas" for every single test. This ensures that one test doesn't accidentally break another. In crewAI, this fresh canvas is provided by the setup_test_environment abstraction.
The Use Case: Imagine you are testing an AI agent that saves its conversation history to a file.
history.txt in your project folder.The Solution: We need a temporary, isolated sandbox that exists only while the test is running and disappears immediately after.
In Python's testing framework (pytest), we use something called a fixture. Think of a fixture as the "Setup Crew" and "Cleanup Crew" at an event.
The setup_test_environment concept is exactly this type of crew.
When a test in CrewAI starts, this abstraction performs a specific sequence of actions to ensure safety.
/tmp/random_id) that the operating system manages.CREWAI_TESTING.
Let's look at how this is implemented in conftest.py. We will break it down into small, digestible pieces.
@pytest.fixture(autouse=True, scope="function")
def setup_test_environment() -> Generator[None, Any, None]:
"""Setup test environment for crewAI workspace."""
# ... logic continues ...
@pytest.fixture: This tells Python "This function is a testing helper."autouse=True: This is magical! It means every single test function will automatically use this setup without you having to ask for it. It forces a clean environment globally.scope="function": The setup and cleanup happen for each individual test function, ensuring maximum isolation.Inside the function, we first create the physical space for files.
with tempfile.TemporaryDirectory() as temp_dir:
storage_dir = Path(temp_dir) / "crewai_test_storage"
storage_dir.mkdir(parents=True, exist_ok=True)
tempfile.TemporaryDirectory(): Creates a folder that is guaranteed to be unique.storage_dir: We create a specific sub-folder where the AI agents will "think" they are saving real data.Before proceeding, the code checks if the sandbox works.
try:
test_file = storage_dir / ".permissions_test"
test_file.touch()
test_file.unlink()
except (OSError, IOError) as e:
# Error handling logic...
raise RuntimeError(f"Storage not writable: {e}")
touch() and unlink(): This tries to create a dummy file and immediately delete it.Now we configure the "mindset" of the application using Environment Variables.
os.environ["CREWAI_STORAGE_DIR"] = str(storage_dir)
os.environ["CREWAI_TESTING"] = "true"
CREWAI_STORAGE_DIR: Tells the app "If you need to save files, put them in that temp folder we just made, not in the real project."CREWAI_TESTING: Tells the app "We are running a test, so behave deterministically (don't send random analytics, etc)."
This is the most critical pattern in pytest fixtures: the yield keyword.
try:
yield # <--- The Test runs right here!
finally:
os.environ.pop("CREWAI_TESTING", "true")
os.environ.pop("CREWAI_STORAGE_DIR", None)
# ... pops other variables ...
yield: This pauses the setup function and lets the actual test run.finally: This block runs after the test finishes (whether it passed or failed).os.environ.pop: Removes the settings we added. This restores your computer's environment to exactly how it was before the test started.
In this chapter, we learned about setup_test_environment:
This ensures that every time you run a test, you are starting with a fresh, clean slate!
Now that our environment is clean and safe, we need to handle how our tests interact with the outside world (like network requests to OpenAI). We don't want to pay for API calls every time we test!
In the next chapter, we will learn how to configure "VCR," a tool that records and replays network requests.
Generated by Code IQ