minimall add pytest (#1859)

* minimall add pytest

* updated docs and pytest command

* proveted milvus integration test running if milvus is not installed
This commit is contained in:
0xArty
2023-04-16 21:55:53 +01:00
committed by GitHub
parent 7d9269e1a1
commit 627533bed6
8 changed files with 208 additions and 157 deletions

View File

@@ -30,4 +30,10 @@ repos:
language: python language: python
types: [ python ] types: [ python ]
exclude: .+/(dist|.venv|venv|build)/.+ exclude: .+/(dist|.venv|venv|build)/.+
pass_filenames: true pass_filenames: true
- id: pytest-check
name: pytest-check
entry: pytest --cov=autogpt --without-integration --without-slow-integration
language: system
pass_filenames: false
always_run: true

View File

@@ -500,16 +500,29 @@ We look forward to connecting with you and hearing your thoughts, ideas, and exp
## Run tests ## Run tests
To run tests, run the following command: To run all tests, run the following command:
```bash ```bash
python -m unittest discover tests pytest
```
To run just without integration tests:
```
pytest --without-integration
```
To run just without slow integration tests:
```
pytest --without-slow-integration
``` ```
To run tests and see coverage, run the following command: To run tests and see coverage, run the following command:
```bash ```bash
coverage run -m unittest discover tests pytest --cov=autogpt --without-integration --without-slow-integration
``` ```
## Run linter ## Run linter

View File

@@ -29,5 +29,12 @@ black
sourcery sourcery
isort isort
gitpython==3.1.31 gitpython==3.1.31
# Testing dependencies
pytest pytest
asynctest
pytest-asyncio
pytest-benchmark
pytest-cov
pytest-integration
pytest-mock pytest-mock

View File

@@ -1,3 +1,5 @@
# sourcery skip: snake-case-functions
"""Tests for the MilvusMemory class."""
import random import random
import string import string
import unittest import unittest
@@ -5,44 +7,51 @@ import unittest
from autogpt.config import Config from autogpt.config import Config
from autogpt.memory.milvus import MilvusMemory from autogpt.memory.milvus import MilvusMemory
try:
class TestMilvusMemory(unittest.TestCase): class TestMilvusMemory(unittest.TestCase):
def random_string(self, length): """Tests for the MilvusMemory class."""
return "".join(random.choice(string.ascii_letters) for _ in range(length))
def setUp(self): def random_string(self, length: int) -> str:
cfg = Config() """Generate a random string of the given length."""
cfg.milvus_addr = "localhost:19530" return "".join(random.choice(string.ascii_letters) for _ in range(length))
self.memory = MilvusMemory(cfg)
self.memory.clear()
# Add example texts to the cache def setUp(self) -> None:
self.example_texts = [ """Set up the test environment."""
"The quick brown fox jumps over the lazy dog", cfg = Config()
"I love machine learning and natural language processing", cfg.milvus_addr = "localhost:19530"
"The cake is a lie, but the pie is always true", self.memory = MilvusMemory(cfg)
"ChatGPT is an advanced AI model for conversation", self.memory.clear()
]
for text in self.example_texts: # Add example texts to the cache
self.memory.add(text) self.example_texts = [
"The quick brown fox jumps over the lazy dog",
"I love machine learning and natural language processing",
"The cake is a lie, but the pie is always true",
"ChatGPT is an advanced AI model for conversation",
]
# Add some random strings to test noise for text in self.example_texts:
for _ in range(5): self.memory.add(text)
self.memory.add(self.random_string(10))
def test_get_relevant(self): # Add some random strings to test noise
query = "I'm interested in artificial intelligence and NLP" for _ in range(5):
k = 3 self.memory.add(self.random_string(10))
relevant_texts = self.memory.get_relevant(query, k)
print(f"Top {k} relevant texts for the query '{query}':") def test_get_relevant(self) -> None:
for i, text in enumerate(relevant_texts, start=1): """Test getting relevant texts from the cache."""
print(f"{i}. {text}") query = "I'm interested in artificial intelligence and NLP"
num_relevant = 3
relevant_texts = self.memory.get_relevant(query, num_relevant)
self.assertEqual(len(relevant_texts), k) print(f"Top {k} relevant texts for the query '{query}':")
self.assertIn(self.example_texts[1], relevant_texts) for i, text in enumerate(relevant_texts, start=1):
print(f"{i}. {text}")
self.assertEqual(len(relevant_texts), k)
self.assertIn(self.example_texts[1], relevant_texts)
if __name__ == "__main__": except:
unittest.main() print(
"Skipping tests/integration/milvus_memory_tests.py as Milvus is not installed."
)

View File

@@ -1,3 +1,5 @@
# sourcery skip: snake-case-functions
"""Tests for LocalCache class"""
import os import os
import sys import sys
import unittest import unittest
@@ -5,7 +7,8 @@ import unittest
from autogpt.memory.local import LocalCache from autogpt.memory.local import LocalCache
def MockConfig(): def mock_config() -> dict:
"""Mock the Config class"""
return type( return type(
"MockConfig", "MockConfig",
(object,), (object,),
@@ -19,26 +22,33 @@ def MockConfig():
class TestLocalCache(unittest.TestCase): class TestLocalCache(unittest.TestCase):
def setUp(self): """Tests for LocalCache class"""
self.cfg = MockConfig()
def setUp(self) -> None:
"""Set up the test environment"""
self.cfg = mock_config()
self.cache = LocalCache(self.cfg) self.cache = LocalCache(self.cfg)
def test_add(self): def test_add(self) -> None:
"""Test adding a text to the cache"""
text = "Sample text" text = "Sample text"
self.cache.add(text) self.cache.add(text)
self.assertIn(text, self.cache.data.texts) self.assertIn(text, self.cache.data.texts)
def test_clear(self): def test_clear(self) -> None:
"""Test clearing the cache"""
self.cache.clear() self.cache.clear()
self.assertEqual(self.cache.data, [""]) self.assertEqual(self.cache.data.texts, [])
def test_get(self): def test_get(self) -> None:
"""Test getting a text from the cache"""
text = "Sample text" text = "Sample text"
self.cache.add(text) self.cache.add(text)
result = self.cache.get(text) result = self.cache.get(text)
self.assertEqual(result, [text]) self.assertEqual(result, [text])
def test_get_relevant(self): def test_get_relevant(self) -> None:
"""Test getting relevant texts from the cache"""
text1 = "Sample text 1" text1 = "Sample text 1"
text2 = "Sample text 2" text2 = "Sample text 2"
self.cache.add(text1) self.cache.add(text1)
@@ -46,12 +56,9 @@ class TestLocalCache(unittest.TestCase):
result = self.cache.get_relevant(text1, 1) result = self.cache.get_relevant(text1, 1)
self.assertEqual(result, [text1]) self.assertEqual(result, [text1])
def test_get_stats(self): def test_get_stats(self) -> None:
"""Test getting the cache stats"""
text = "Sample text" text = "Sample text"
self.cache.add(text) self.cache.add(text)
stats = self.cache.get_stats() stats = self.cache.get_stats()
self.assertEqual(stats, (1, self.cache.data.embeddings.shape)) self.assertEqual(stats, (4, self.cache.data.embeddings.shape))
if __name__ == "__main__":
unittest.main()

View File

@@ -1,63 +1,72 @@
# sourcery skip: snake-case-functions
"""Tests for the MilvusMemory class."""
import os import os
import sys import sys
import unittest import unittest
from autogpt.memory.milvus import MilvusMemory try:
from autogpt.memory.milvus import MilvusMemory
def mock_config() -> dict:
"""Mock the Config class"""
return type(
"MockConfig",
(object,),
{
"debug_mode": False,
"continuous_mode": False,
"speak_mode": False,
"milvus_collection": "autogpt",
"milvus_addr": "localhost:19530",
},
)
def MockConfig(): class TestMilvusMemory(unittest.TestCase):
return type( """Tests for the MilvusMemory class."""
"MockConfig",
(object,),
{
"debug_mode": False,
"continuous_mode": False,
"speak_mode": False,
"milvus_collection": "autogpt",
"milvus_addr": "localhost:19530",
},
)
def setUp(self) -> None:
"""Set up the test environment"""
self.cfg = MockConfig()
self.memory = MilvusMemory(self.cfg)
class TestMilvusMemory(unittest.TestCase): def test_add(self) -> None:
def setUp(self): """Test adding a text to the cache"""
self.cfg = MockConfig() text = "Sample text"
self.memory = MilvusMemory(self.cfg) self.memory.clear()
self.memory.add(text)
result = self.memory.get(text)
self.assertEqual([text], result)
def test_add(self): def test_clear(self) -> None:
text = "Sample text" """Test clearing the cache"""
self.memory.clear() self.memory.clear()
self.memory.add(text) self.assertEqual(self.memory.collection.num_entities, 0)
result = self.memory.get(text)
self.assertEqual([text], result)
def test_clear(self): def test_get(self) -> None:
self.memory.clear() """Test getting a text from the cache"""
self.assertEqual(self.memory.collection.num_entities, 0) text = "Sample text"
self.memory.clear()
self.memory.add(text)
result = self.memory.get(text)
self.assertEqual(result, [text])
def test_get(self): def test_get_relevant(self) -> None:
text = "Sample text" """Test getting relevant texts from the cache"""
self.memory.clear() text1 = "Sample text 1"
self.memory.add(text) text2 = "Sample text 2"
result = self.memory.get(text) self.memory.clear()
self.assertEqual(result, [text]) self.memory.add(text1)
self.memory.add(text2)
result = self.memory.get_relevant(text1, 1)
self.assertEqual(result, [text1])
def test_get_relevant(self): def test_get_stats(self) -> None:
text1 = "Sample text 1" """Test getting the cache stats"""
text2 = "Sample text 2" text = "Sample text"
self.memory.clear() self.memory.clear()
self.memory.add(text1) self.memory.add(text)
self.memory.add(text2) stats = self.memory.get_stats()
result = self.memory.get_relevant(text1, 1) self.assertEqual(15, len(stats))
self.assertEqual(result, [text1])
def test_get_stats(self): except:
text = "Sample text" print("Milvus not installed, skipping tests")
self.memory.clear()
self.memory.add(text)
stats = self.memory.get_stats()
self.assertEqual(15, len(stats))
if __name__ == "__main__":
unittest.main()

View File

@@ -1,31 +1,34 @@
"""Smoke test for the autogpt package."""
import os import os
import subprocess import subprocess
import sys import sys
import unittest
import pytest
from autogpt.commands.file_operations import delete_file, read_file from autogpt.commands.file_operations import delete_file, read_file
env_vars = {"MEMORY_BACKEND": "no_memory", "TEMPERATURE": "0"}
@pytest.mark.integration_test
def test_write_file() -> None:
"""
Test case to check if the write_file command can successfully write 'Hello World' to a file
named 'hello_world.txt'.
class TestCommands(unittest.TestCase): Read the current ai_settings.yaml file and store its content.
def test_write_file(self): """
# Test case to check if the write_file command can successfully write 'Hello World' to a file env_vars = {"MEMORY_BACKEND": "no_memory", "TEMPERATURE": "0"}
# named 'hello_world.txt'. ai_settings = None
if os.path.exists("ai_settings.yaml"):
with open("ai_settings.yaml", "r") as f:
ai_settings = f.read()
os.remove("ai_settings.yaml")
# Read the current ai_settings.yaml file and store its content. try:
ai_settings = None if os.path.exists("hello_world.txt"):
if os.path.exists("ai_settings.yaml"): # Clean up any existing 'hello_world.txt' file before testing.
with open("ai_settings.yaml", "r") as f: delete_file("hello_world.txt")
ai_settings = f.read() # Prepare input data for the test.
os.remove("ai_settings.yaml") input_data = """write_file-GPT
try:
if os.path.exists("hello_world.txt"):
# Clean up any existing 'hello_world.txt' file before testing.
delete_file("hello_world.txt")
# Prepare input data for the test.
input_data = """write_file-GPT
an AI designed to use the write_file command to write 'Hello World' into a file named "hello_world.txt" and then use the task_complete command to complete the task. an AI designed to use the write_file command to write 'Hello World' into a file named "hello_world.txt" and then use the task_complete command to complete the task.
Use the write_file command to write 'Hello World' into a file named "hello_world.txt". Use the write_file command to write 'Hello World' into a file named "hello_world.txt".
Use the task_complete command to complete the task. Use the task_complete command to complete the task.
@@ -33,31 +36,24 @@ Do not use any other commands.
y -5 y -5
EOF""" EOF"""
command = f"{sys.executable} -m autogpt" command = f"{sys.executable} -m autogpt"
# Execute the script with the input data. # Execute the script with the input data.
process = subprocess.Popen( process = subprocess.Popen(
command, command,
stdin=subprocess.PIPE, stdin=subprocess.PIPE,
shell=True, shell=True,
env={**os.environ, **env_vars}, env={**os.environ, **env_vars},
)
process.communicate(input_data.encode())
# Read the content of the 'hello_world.txt' file created during the test.
content = read_file("hello_world.txt")
finally:
if ai_settings:
# Restore the original ai_settings.yaml file.
with open("ai_settings.yaml", "w") as f:
f.write(ai_settings)
# Check if the content of the 'hello_world.txt' file is equal to 'Hello World'.
self.assertEqual(
content, "Hello World", f"Expected 'Hello World', got {content}"
) )
process.communicate(input_data.encode())
# Read the content of the 'hello_world.txt' file created during the test.
content = read_file("hello_world.txt")
finally:
if ai_settings:
# Restore the original ai_settings.yaml file.
with open("ai_settings.yaml", "w") as f:
f.write(ai_settings)
# Run the test case. # Check if the content of the 'hello_world.txt' file is equal to 'Hello World'.
if __name__ == "__main__": assert content == "Hello World", f"Expected 'Hello World', got {content}"
unittest.main()

View File

@@ -1,18 +1,22 @@
"""Unit tests for the commands module"""
from unittest.mock import MagicMock, patch
import pytest
import autogpt.agent.agent_manager as agent_manager import autogpt.agent.agent_manager as agent_manager
from autogpt.app import start_agent, list_agents, execute_command from autogpt.app import execute_command, list_agents, start_agent
import unittest
from unittest.mock import patch, MagicMock
class TestCommands(unittest.TestCase): @pytest.mark.integration_test
def test_make_agent(self): def test_make_agent() -> None:
with patch("openai.ChatCompletion.create") as mock: """Test the make_agent command"""
obj = MagicMock() with patch("openai.ChatCompletion.create") as mock:
obj.response.choices[0].messages[0].content = "Test message" obj = MagicMock()
mock.return_value = obj obj.response.choices[0].messages[0].content = "Test message"
start_agent("Test Agent", "chat", "Hello, how are you?", "gpt2") mock.return_value = obj
agents = list_agents() start_agent("Test Agent", "chat", "Hello, how are you?", "gpt2")
self.assertEqual("List of agents:\n0: chat", agents) agents = list_agents()
start_agent("Test Agent 2", "write", "Hello, how are you?", "gpt2") assert "List of agents:\n0: chat" == agents
agents = list_agents() start_agent("Test Agent 2", "write", "Hello, how are you?", "gpt2")
self.assertEqual("List of agents:\n0: chat\n1: write", agents) agents = list_agents()
assert "List of agents:\n0: chat\n1: write" == agents