From a5af12953995595b592dc761f0aecd6dc07d4c78 Mon Sep 17 00:00:00 2001 From: Vishwanath Martur <64204611+vishwamartur@users.noreply.github.com> Date: Fri, 1 Nov 2024 14:00:26 +0530 Subject: [PATCH] Add unit tests and CI workflow using GitHub Actions Related to #9 Add unit tests and CI workflow using GitHub Actions. * **Add GitHub Actions Workflow**: Create `.github/workflows/ci.yml` to run tests on push and pull request. - Set up Python 3.12 using `actions/setup-python`. - Install dependencies using `poetry`. - Run tests using `pytest`. * **Add Unit Tests**: Create `tests/test_integration_agent.py` to test `IntegrationAgent` class. - Write unit tests for `end_url_identify_agent` method. - Write unit tests for `input_variables_identifying_agent` method. - Write unit tests for `dynamic_part_identifying_agent` method. * **Update README**: Add instructions for running unit tests and details about the CI workflow. - Add instructions for running unit tests using `pytest`. - Add details about the CI workflow using GitHub Actions. --- .github/workflows/ci.yml | 30 ++++++++++++++ README.md | 17 ++++++++ tests/test_integration_agent.py | 71 +++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 tests/test_integration_agent.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..48c5774 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,30 @@ +name: CI + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: 3.12 + + - name: Install dependencies + run: | + curl -sSL https://install.python-poetry.org | python3 - + poetry install + + - name: Run tests + run: poetry run pytest diff --git a/README.md b/README.md index c286de6..849f377 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,23 @@ Options: --help Show this message and exit. ``` +## Running Unit Tests + +To run unit tests using `pytest`, use the following command: + +``` +poetry run pytest +``` + +## Continuous Integration (CI) Workflow + +This repository includes a CI workflow using GitHub Actions. The workflow is defined in the `.github/workflows/ci.yml` file and is triggered on each push and pull request to the `main` branch. The workflow performs the following steps: + +1. Checks out the code. +2. Sets up Python 3.12. +3. Installs dependencies using `poetry`. +4. Runs tests using `pytest`. + ## Demo [![Demo Video](https://img.youtube.com/vi/7OJ4w5BCpQ0/0.jpg)](https://www.youtube.com/watch?v=7OJ4w5BCpQ0) diff --git a/tests/test_integration_agent.py b/tests/test_integration_agent.py new file mode 100644 index 0000000..6ca77cb --- /dev/null +++ b/tests/test_integration_agent.py @@ -0,0 +1,71 @@ +import unittest +from integuru.agent import IntegrationAgent +from integuru.models.agent_state import AgentState +from unittest.mock import patch, MagicMock + +class TestIntegrationAgent(unittest.TestCase): + + def setUp(self): + self.prompt = "Test prompt" + self.har_file_path = "test.har" + self.cookie_path = "test_cookies.json" + self.agent = IntegrationAgent(self.prompt, self.har_file_path, self.cookie_path) + self.state = AgentState( + master_node=None, + in_process_node=None, + to_be_processed_nodes=[], + in_process_node_dynamic_parts=[], + action_url="", + input_variables={} + ) + + @patch('integuru.agent.llm.get_instance') + def test_end_url_identify_agent(self, mock_llm_instance): + mock_response = MagicMock() + mock_response.additional_kwargs = { + 'function_call': { + 'arguments': '{"url": "http://example.com/action"}' + } + } + mock_llm_instance.return_value.invoke.return_value = mock_response + + updated_state = self.agent.end_url_identify_agent(self.state) + self.assertEqual(updated_state[self.agent.ACTION_URL_KEY], "http://example.com/action") + + @patch('integuru.agent.llm.get_instance') + def test_input_variables_identifying_agent(self, mock_llm_instance): + self.state[self.agent.IN_PROCESS_NODE_KEY] = "node_1" + self.state[self.agent.INPUT_VARIABLES_KEY] = {"var1": "value1"} + self.agent.dag_manager.graph.add_node("node_1", content={"key": MagicMock()}) + self.agent.dag_manager.graph.nodes["node_1"]["content"]["key"].to_curl_command.return_value = "curl command" + + mock_response = MagicMock() + mock_response.additional_kwargs = { + 'function_call': { + 'arguments': '{"identified_variables": [{"variable_name": "var1", "variable_value": "value1"}]}' + } + } + mock_llm_instance.return_value.invoke.return_value = mock_response + + updated_state = self.agent.input_variables_identifying_agent(self.state) + self.assertEqual(updated_state[self.agent.INPUT_VARIABLES_KEY], {"var1": "value1"}) + + @patch('integuru.agent.llm.get_instance') + def test_dynamic_part_identifying_agent(self, mock_llm_instance): + self.state[self.agent.TO_BE_PROCESSED_NODES_KEY] = ["node_1"] + self.agent.dag_manager.graph.add_node("node_1", content={"key": MagicMock()}) + self.agent.dag_manager.graph.nodes["node_1"]["content"]["key"].to_minified_curl_command.return_value = "curl command" + + mock_response = MagicMock() + mock_response.additional_kwargs = { + 'function_call': { + 'arguments': '{"dynamic_parts": ["dynamic_part1"]}' + } + } + mock_llm_instance.return_value.invoke.return_value = mock_response + + updated_state = self.agent.dynamic_part_identifying_agent(self.state) + self.assertEqual(updated_state[self.agent.IN_PROCESS_NODE_DYNAMIC_PARTS_KEY], ["dynamic_part1"]) + +if __name__ == '__main__': + unittest.main()