diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c22a440..da98d3f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,4 +41,4 @@ jobs: run: | pip install pytest cd pilot - PYTHONPATH=. pytest + PYTHONPATH=. pytest -m "not slow" diff --git a/pilot/test_main_e2e.py b/pilot/test_main_e2e.py new file mode 100644 index 0000000..beeba9e --- /dev/null +++ b/pilot/test_main_e2e.py @@ -0,0 +1,71 @@ +import builtins +import pytest +from unittest.mock import patch +from dotenv import load_dotenv +load_dotenv() + +from database.database import create_tables, drop_tables +from helpers.Project import Project +from .main import init, get_custom_print + + +def test_init(): + # When + args = init() + + # Then + for field in ['app_id', 'user_id', 'email']: + assert args[field] is not None + + for field in ['workspace', 'step']: + assert args[field] is None + + +class MockQuestionary(): + def __init__(self, answers=[]): + self.answers = iter(answers) + self.state = 'project_description' + + def text(self, question: str, style=None): + print('AI: ' + question) + if question.startswith('User Story'): + self.state = 'user_stories' + elif question.endswith('write "DONE"'): + self.state = 'DONE' + return self + + def unsafe_ask(self): + if self.state == 'user_stories': + answer = '' + elif self.state == 'DONE': + answer = 'DONE' + else: # if self.state == 'project_description': + answer = next(self.answers) + + print('User:', answer) + return answer + + +@pytest.mark.slow +@pytest.mark.skip(reason="Uses lots of tokens") +def test_end_to_end(): + # Given + create_tables() + args = init() + builtins.print, ipc_client_instance = get_custom_print(args) + project = Project(args) + mock_questionary = MockQuestionary([ + 'Test App', + 'A web-based chat app', + # 5 clarifying questions + 'Users can send direct messages to each other but with no group chat functionality', + 'No authentication is required at this stage', + 'Use your best judgement', + 'Use your best judgement', + 'Use your best judgement', + ]) + + # When + with patch('utils.questionary.questionary', mock_questionary): + project.start() + diff --git a/pilot/utils/test_llm_connection.py b/pilot/utils/test_llm_connection.py new file mode 100644 index 0000000..38e16af --- /dev/null +++ b/pilot/utils/test_llm_connection.py @@ -0,0 +1,43 @@ +from dotenv import load_dotenv +from const.function_calls import ARCHITECTURE +from helpers.AgentConvo import AgentConvo +from helpers.Project import Project +from helpers.agents.Architect import Architect +from .llm_connection import create_gpt_chat_completion + +load_dotenv() + +project = Project({'app_id': 'test-app'}, current_step='test') + + +class TestLlmConnection: + """Test the LLM connection class.""" + + def test_chat_completion_Architect(self): + """Test the chat completion method.""" + # Given + agent = Architect(project) + convo = AgentConvo(agent) + convo.construct_and_add_message_from_prompt('architecture/technologies.prompt', + { + 'name': 'Test App', + 'prompt': 'A web-based chat app', + 'app_type': 'web app', + 'user_stories': [ + 'As a user I want to be able view messages sent and received' + ] + }) + + messages = convo.messages + # messages = [{"role": "user", "content": "I want to create a website"}] + + # When + response = create_gpt_chat_completion(messages, '', function_calls=ARCHITECTURE) + # Then + assert response is not None + assert len(response) > 0 + # assert response != prompt + + + def _create_convo(self, agent): + convo = AgentConvo(agent) \ No newline at end of file diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..a3b504a --- /dev/null +++ b/pytest.ini @@ -0,0 +1,7 @@ +[pytest] +testpaths = . +python_files = test_*.py + +markers = + slow: marks tests as slow (deselect with '-m "not slow"') + daily: tests which should be run daily