Merge pull request #652 from better629/dev

Feat add extra role/actions' ser&desr unittest
This commit is contained in:
geekan 2023-12-29 13:50:23 +08:00 committed by GitHub
commit 5510df5f96
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 238 additions and 9 deletions

View file

@ -7,12 +7,11 @@
"""
from typing import Optional
from pydantic import Field
from metagpt.document_store.base_store import BaseStore
from metagpt.roles import Sales
# from metagpt.actions import SearchAndSummarize
# from metagpt.tools import SearchEngineType
DESC = """
## Principles (all things must not bypass the principles)
@ -29,4 +28,4 @@ class CustomerService(Sales):
name: str = "Xiaomei"
profile: str = "Human customer service"
desc: str = DESC
store: Optional[str] = None
store: Optional[BaseStore] = Field(default=None, exclude=True)

View file

@ -8,6 +8,8 @@
from typing import Optional
from pydantic import Field
from metagpt.actions import SearchAndSummarize, UserRequirement
from metagpt.document_store.base_store import BaseStore
from metagpt.roles import Role
@ -25,7 +27,7 @@ class Sales(Role):
"delivered with the professionalism and courtesy expected of a seasoned sales guide."
)
store: Optional[BaseStore] = None
store: Optional[BaseStore] = Field(default=None, exclude=True)
def __init__(self, **kwargs):
super().__init__(**kwargs)

View file

@ -41,13 +41,13 @@ class SkAgent(Role):
goal: str = "Execute task based on passed in task description"
constraints: str = ""
plan: Plan = None
plan: Plan = Field(default=None, exclude=True)
planner_cls: Any = None
planner: Union[BasicPlanner, SequentialPlanner, ActionPlanner] = None
llm: BaseLLM = Field(default_factory=LLM)
kernel: Kernel = Field(default_factory=Kernel)
import_semantic_skill_from_directory: Callable = None
import_skill: Callable = None
import_semantic_skill_from_directory: Callable = Field(default=None, exclude=True)
import_skill: Callable = Field(default=None, exclude=True)
def __init__(self, **data: Any) -> None:
"""Initializes the Engineer role with given attributes."""

View file

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# @Desc :
import pytest
from metagpt.actions.action_node import ActionNode
from metagpt.actions.prepare_interview import PrepareInterview
@pytest.mark.asyncio
async def test_action_deserialize():
action = PrepareInterview()
serialized_data = action.model_dump()
assert serialized_data["name"] == "PrepareInterview"
new_action = PrepareInterview(**serialized_data)
assert new_action.name == "PrepareInterview"
assert type(await new_action.run("python developer")) == ActionNode

View file

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# @Desc :
import pytest
from metagpt.actions import CollectLinks
from metagpt.roles.researcher import Researcher
@pytest.mark.asyncio
async def test_tutorial_assistant_deserialize():
role = Researcher()
ser_role_dict = role.model_dump()
assert "name" in ser_role_dict
assert "language" in ser_role_dict
new_role = Researcher(**ser_role_dict)
assert new_role.language == "en-us"
assert len(new_role.actions) == 3
assert isinstance(new_role.actions[0], CollectLinks)
# todo: 需要测试不同的action失败下记忆是否正常保存

View file

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# @Desc :
import pytest
from metagpt.roles.sk_agent import SkAgent
def test_sk_agent_serialize():
role = SkAgent()
ser_role_dict = role.model_dump(exclude={"import_semantic_skill_from_directory", "import_skill"})
assert "name" in ser_role_dict
assert "planner" in ser_role_dict
@pytest.mark.asyncio
async def test_sk_agent_deserialize():
role = SkAgent()
ser_role_dict = role.model_dump(exclude={"import_semantic_skill_from_directory", "import_skill"})
assert "name" in ser_role_dict
assert "planner" in ser_role_dict
new_role = SkAgent(**ser_role_dict)
assert new_role.name == "Sunshine"
assert len(new_role.actions) == 1

View file

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# @Desc :
import pytest
from metagpt.actions.write_tutorial import WriteDirectory
from metagpt.roles.tutorial_assistant import TutorialAssistant
@pytest.mark.asyncio
async def test_tutorial_assistant_deserialize():
role = TutorialAssistant()
ser_role_dict = role.model_dump()
assert "name" in ser_role_dict
assert "language" in ser_role_dict
assert "topic" in ser_role_dict
new_role = TutorialAssistant(**ser_role_dict)
assert new_role.name == "Stitch"
assert len(new_role.actions) == 1
assert isinstance(new_role.actions[0], WriteDirectory)

View file

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
# @Desc :
import pytest
from metagpt.actions.write_docstring import WriteDocstring
code = """
def add_numbers(a: int, b: int):
return a + b
class Person:
def __init__(self, name: str, age: int):
self.name = name
self.age = age
def greet(self):
return f"Hello, my name is {self.name} and I am {self.age} years old."
"""
@pytest.mark.asyncio
@pytest.mark.parametrize(
("style", "part"),
[
("google", "Args:"),
("numpy", "Parameters"),
("sphinx", ":param name:"),
],
ids=["google", "numpy", "sphinx"],
)
async def test_action_deserialize(style: str, part: str):
action = WriteDocstring()
serialized_data = action.model_dump()
assert "name" in serialized_data
assert serialized_data["desc"] == "Write docstring for code."
new_action = WriteDocstring(**serialized_data)
assert not new_action.name
assert new_action.desc == "Write docstring for code."
ret = await new_action.run(code, style=style)
assert part in ret

View file

@ -0,0 +1,56 @@
# -*- coding: utf-8 -*-
# @Desc :
import pytest
from metagpt.actions.action_node import ActionNode
from metagpt.actions.write_review import WriteReview
CONTEXT = """
{
"Language": "zh_cn",
"Programming Language": "Python",
"Original Requirements": "写一个简单的2048",
"Project Name": "game_2048",
"Product Goals": [
"创建一个引人入胜的用户体验",
"确保高性能",
"提供可定制的功能"
],
"User Stories": [
"作为用户,我希望能够选择不同的难度级别",
"作为玩家,我希望在每局游戏结束后能看到我的得分"
],
"Competitive Analysis": [
"Python Snake Game: 界面简单,缺乏高级功能"
],
"Competitive Quadrant Chart": "quadrantChart\n title \"Reach and engagement of campaigns\"\n x-axis \"Low Reach\" --> \"High Reach\"\n y-axis \"Low Engagement\" --> \"High Engagement\"\n quadrant-1 \"我们应该扩展\"\n quadrant-2 \"需要推广\"\n quadrant-3 \"重新评估\"\n quadrant-4 \"可能需要改进\"\n \"Campaign A\": [0.3, 0.6]\n \"Campaign B\": [0.45, 0.23]\n \"Campaign C\": [0.57, 0.69]\n \"Campaign D\": [0.78, 0.34]\n \"Campaign E\": [0.40, 0.34]\n \"Campaign F\": [0.35, 0.78]\n \"Our Target Product\": [0.5, 0.6]",
"Requirement Analysis": "产品应该用户友好。",
"Requirement Pool": [
[
"P0",
"主要代码..."
],
[
"P0",
"游戏算法..."
]
],
"UI Design draft": "基本功能描述,简单的风格和布局。",
"Anything UNCLEAR": "..."
}
"""
@pytest.mark.asyncio
async def test_action_deserialize():
action = WriteReview()
serialized_data = action.model_dump()
assert serialized_data["name"] == "WriteReview"
new_action = WriteReview(**serialized_data)
review = await new_action.run(CONTEXT)
assert new_action.name == "WriteReview"
assert type(review) == ActionNode
assert review.instruct_content
assert review.get("LGTM") in ["LGTM", "LBTM"]

View file

@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
# @Desc :
from typing import Dict
import pytest
from metagpt.actions.write_tutorial import WriteContent, WriteDirectory
@pytest.mark.asyncio
@pytest.mark.parametrize(("language", "topic"), [("English", "Write a tutorial about Python")])
async def test_write_directory_deserialize(language: str, topic: str):
action = WriteDirectory()
serialized_data = action.model_dump()
assert serialized_data["name"] == "WriteDirectory"
assert serialized_data["language"] == "Chinese"
new_action = WriteDirectory(**serialized_data)
ret = await new_action.run(topic=topic)
assert isinstance(ret, dict)
assert "title" in ret
assert "directory" in ret
assert isinstance(ret["directory"], list)
assert len(ret["directory"])
assert isinstance(ret["directory"][0], dict)
@pytest.mark.asyncio
@pytest.mark.parametrize(
("language", "topic", "directory"),
[("English", "Write a tutorial about Python", {"Introduction": ["What is Python?", "Why learn Python?"]})],
)
async def test_write_content_deserialize(language: str, topic: str, directory: Dict):
action = WriteContent(language=language, directory=directory)
serialized_data = action.model_dump()
assert serialized_data["name"] == "WriteContent"
new_action = WriteContent(**serialized_data)
ret = await new_action.run(topic=topic)
assert isinstance(ret, str)
assert list(directory.keys())[0] in ret
for value in list(directory.values())[0]:
assert value in ret