Skip to content

Commit 036ef11

Browse files
authored
Merge pull request #11 from vishwamartur/add-unit-tests-ci
Add unit tests and CI workflow using GitHub Actions
2 parents d3c1403 + 0090e7b commit 036ef11

File tree

3 files changed

+120
-0
lines changed

3 files changed

+120
-0
lines changed

.github/workflows/ci.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
11+
jobs:
12+
test:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout code
17+
uses: actions/checkout@v2
18+
19+
- name: Set up Python
20+
uses: actions/setup-python@v2
21+
with:
22+
python-version: 3.12
23+
24+
- name: Install dependencies
25+
run: |
26+
curl -sSL https://install.python-poetry.org | python3 -
27+
poetry install
28+
29+
- name: Run tests
30+
run: poetry run pytest

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,29 @@ Options:
8989
--help Show this message and exit.
9090
```
9191

92+
93+
## Running Unit Tests
94+
95+
To run unit tests using `pytest`, use the following command:
96+
97+
```
98+
poetry run pytest
99+
```
100+
101+
## Continuous Integration (CI) Workflow
102+
103+
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:
104+
105+
1. Checks out the code.
106+
2. Sets up Python 3.12.
107+
3. Installs dependencies using `poetry`.
108+
4. Runs tests using `pytest`.
109+
92110
## Note on 2FA
93111

94112
When the destination site uses two-factor authentication (2FA), the workflow remains the same. Ensure that you complete the 2FA process and obtain the cookies/auth tokens/session tokens after 2FA. These tokens will be used in the workflow.
95113

114+
96115
## Demo
97116

98117
[![Demo Video](http://markdown-videos-api.jorgenkh.no/youtube/7OJ4w5BCpQ0)](https://www.youtube.com/watch?v=7OJ4w5BCpQ0)

tests/test_integration_agent.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import unittest
2+
from integuru.agent import IntegrationAgent
3+
from integuru.models.agent_state import AgentState
4+
from unittest.mock import patch, MagicMock
5+
6+
class TestIntegrationAgent(unittest.TestCase):
7+
8+
def setUp(self):
9+
self.prompt = "Test prompt"
10+
self.har_file_path = "test.har"
11+
self.cookie_path = "test_cookies.json"
12+
self.agent = IntegrationAgent(self.prompt, self.har_file_path, self.cookie_path)
13+
self.state = AgentState(
14+
master_node=None,
15+
in_process_node=None,
16+
to_be_processed_nodes=[],
17+
in_process_node_dynamic_parts=[],
18+
action_url="",
19+
input_variables={}
20+
)
21+
22+
@patch('integuru.agent.llm.get_instance')
23+
def test_end_url_identify_agent(self, mock_llm_instance):
24+
mock_response = MagicMock()
25+
mock_response.additional_kwargs = {
26+
'function_call': {
27+
'arguments': '{"url": "http://example.com/action"}'
28+
}
29+
}
30+
mock_llm_instance.return_value.invoke.return_value = mock_response
31+
32+
updated_state = self.agent.end_url_identify_agent(self.state)
33+
self.assertEqual(updated_state[self.agent.ACTION_URL_KEY], "http://example.com/action")
34+
35+
@patch('integuru.agent.llm.get_instance')
36+
def test_input_variables_identifying_agent(self, mock_llm_instance):
37+
self.state[self.agent.IN_PROCESS_NODE_KEY] = "node_1"
38+
self.state[self.agent.INPUT_VARIABLES_KEY] = {"var1": "value1"}
39+
self.agent.dag_manager.graph.add_node("node_1", content={"key": MagicMock()})
40+
self.agent.dag_manager.graph.nodes["node_1"]["content"]["key"].to_curl_command.return_value = "curl command"
41+
42+
mock_response = MagicMock()
43+
mock_response.additional_kwargs = {
44+
'function_call': {
45+
'arguments': '{"identified_variables": [{"variable_name": "var1", "variable_value": "value1"}]}'
46+
}
47+
}
48+
mock_llm_instance.return_value.invoke.return_value = mock_response
49+
50+
updated_state = self.agent.input_variables_identifying_agent(self.state)
51+
self.assertEqual(updated_state[self.agent.INPUT_VARIABLES_KEY], {"var1": "value1"})
52+
53+
@patch('integuru.agent.llm.get_instance')
54+
def test_dynamic_part_identifying_agent(self, mock_llm_instance):
55+
self.state[self.agent.TO_BE_PROCESSED_NODES_KEY] = ["node_1"]
56+
self.agent.dag_manager.graph.add_node("node_1", content={"key": MagicMock()})
57+
self.agent.dag_manager.graph.nodes["node_1"]["content"]["key"].to_minified_curl_command.return_value = "curl command"
58+
59+
mock_response = MagicMock()
60+
mock_response.additional_kwargs = {
61+
'function_call': {
62+
'arguments': '{"dynamic_parts": ["dynamic_part1"]}'
63+
}
64+
}
65+
mock_llm_instance.return_value.invoke.return_value = mock_response
66+
67+
updated_state = self.agent.dynamic_part_identifying_agent(self.state)
68+
self.assertEqual(updated_state[self.agent.IN_PROCESS_NODE_DYNAMIC_PARTS_KEY], ["dynamic_part1"])
69+
70+
if __name__ == '__main__':
71+
unittest.main()

0 commit comments

Comments
 (0)