-
Notifications
You must be signed in to change notification settings - Fork 56
Users/robrandao/data driven tests #245
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
84 commits
Select commit
Hold shift + click to select a range
cfb8847
basic integration utility
rodrigobr-msft 4d93a46
Integration test suite factory implementation
rodrigobr-msft be2fb1c
Implementing core models for integration testing
rodrigobr-msft 0d5539a
AutoClient mockup
rodrigobr-msft bf4c006
Adding runner starter code
rodrigobr-msft ebe622d
Adding foundational classes
rodrigobr-msft 45678e9
Drafting AgentClient and ResponseClient implementations
rodrigobr-msft c2b84cb
Spec test
rodrigobr-msft 2816e68
Filling in more implementation details
rodrigobr-msft 2214827
More files
rodrigobr-msft c90c8e4
Cleaning up implementations
rodrigobr-msft 36f5c3b
Adding expect replies sending method
rodrigobr-msft dfdd959
Beginning unit tests
rodrigobr-msft d4828fb
Adding integration decor from sample test cases
rodrigobr-msft 91b3c44
Integration from service url tests
rodrigobr-msft 1eefe44
_handle_conversation implementation for response_client
rodrigobr-msft a06da9a
AgentClient tests completed
rodrigobr-msft d36ec7a
Creating response client tests
rodrigobr-msft c096048
Hosting server for response client
rodrigobr-msft 5451ddf
Response client tests completed
rodrigobr-msft c2cdd40
Beginning refactor of aiohttp runner
rodrigobr-msft 7d91ef9
Unit test updates
rodrigobr-msft 87610a5
Fixing issues in refactor
rodrigobr-msft ddfdd0b
Fixed TestIntegrationFromSample unit test
rodrigobr-msft dd0a87d
Another commit
rodrigobr-msft 6a4e8ef
Reorganizing files
rodrigobr-msft 7793790
Completed TestIntegrationFromServiceUrl unit tests
rodrigobr-msft 3ebbd44
Reformatting with black
rodrigobr-msft a6681bf
Quickstart integration test beginning
rodrigobr-msft 1a7264b
Draft of quickstart sample setup
rodrigobr-msft 9ba4a43
Environment config connection
rodrigobr-msft fab4368
Renaming messaging endpoint to agent url
rodrigobr-msft a111155
Removing unnecessary files
rodrigobr-msft a2a1092
Fixing agent client payload sending
rodrigobr-msft ae8a286
First successful integration test
rodrigobr-msft 9a5a6a8
Beginning foundational test cases
rodrigobr-msft aad011a
TypingIndicator test
rodrigobr-msft be0032a
Adding more test cases
rodrigobr-msft e3f4324
More foundational integration test cases
rodrigobr-msft a077eed
Reorganizing testing tools into package
rodrigobr-msft 49161c3
Polished the testing framework package
rodrigobr-msft 69d68d4
Adding verbose logging for results with benchmark tool
rodrigobr-msft 3dc3efa
General cleanup
rodrigobr-msft 054a3a2
Adding README
rodrigobr-msft 8a5f22e
Revising README
rodrigobr-msft 4b7c673
Formatting
rodrigobr-msft 01f8f5a
Addressing PR comments
rodrigobr-msft 9cccc1f
Merge branch 'main' of https://github.com/microsoft/Agents-for-python…
rodrigobr-msft 8f87aff
Removing unused import
rodrigobr-msft e742e00
Update dev/microsoft-agents-testing/microsoft_agents/testing/sdk_conf…
rodrigobr-msft a6e305a
Update dev/microsoft-agents-testing/pyproject.toml
rodrigobr-msft c3877a3
Update dev/microsoft-agents-testing/microsoft_agents/testing/auth/gen…
rodrigobr-msft fb5b76d
Update dev/microsoft-agents-testing/microsoft_agents/testing/integrat…
rodrigobr-msft 5eb9bfb
Removing unused code
rodrigobr-msft 81b5d6b
Merge branch 'users/robrandao/integration' of https://github.com/micr…
rodrigobr-msft e451459
Adding field assertion helpers
rodrigobr-msft f241df8
Implementing field assertion types
rodrigobr-msft cb3c6aa
Adding data driven test foundation
rodrigobr-msft b8f3304
Separating assertions from checkers
rodrigobr-msft 42b4ea1
Adjusting return values for check_activity with refactor
rodrigobr-msft 2f79824
Fixing package name in pyproject.toml
rodrigobr-msft cfded79
Assertion test cases
rodrigobr-msft b6618b2
_parse_assertion unit tests
rodrigobr-msft 1e8f19e
More assertion tests and fixes to data normalization logic
rodrigobr-msft d9eb5fa
Fixing more test cases with newest refactor
rodrigobr-msft f02b875
Fixing merge conflicts
rodrigobr-msft 57b87eb
assert_activity tests
rodrigobr-msft 6925093
Reorganizing tests
rodrigobr-msft 6d55b29
Copyright comments
rodrigobr-msft 6866f5d
DDT implementation outline
rodrigobr-msft 1db2bf5
DataDrivenTest class
rodrigobr-msft e44a2da
select_activity implementation for assertions
rodrigobr-msft 1cf561b
inverted assertions for quantifiers
rodrigobr-msft e651f92
ActivityAssertion class implementation
rodrigobr-msft ed7f2f1
DataDrivenTest implementation
rodrigobr-msft e88997e
Populate function for dictionaries
rodrigobr-msft 0a48730
Populate tests
rodrigobr-msft 2f96d88
Selector class implementation
rodrigobr-msft 3a04fb5
Assertion tests completed for now
rodrigobr-msft 31b2b99
Adding ActivityAssertion tests
rodrigobr-msft 4df4788
DataDrivenTest implementation connected with default config
rodrigobr-msft 0c195b1
More test cases and formatting
rodrigobr-msft 7a79cc9
Data driven testing single test setup support
rodrigobr-msft f8c9166
Formatting
rodrigobr-msft File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| parent: ./defaults.yaml | ||
| description: A basic data driven test example | ||
| defaults: | ||
| input: | ||
| sleep: | ||
| assertion: | ||
| test: | ||
| - type: input | ||
| activity: | ||
| type: message | ||
| text: "Hello, World!" | ||
|
|
||
| - type: sleep | ||
| duration: 1 | ||
|
|
||
| - type: assertion | ||
| quantifier: ONE | ||
| selector: | ||
| index: -1 | ||
| quantifier: ONE | ||
| activity: | ||
| type: message | ||
| activity: | ||
| type: message | ||
| text: "Hello, World!" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| defaults: | ||
| all: | ||
| channel_id: "test_channel" | ||
| service_url: "http://localhost:3978" | ||
| locale: "en-US" | ||
| conversation_id: "test_conversation" | ||
| input: | ||
| user_id: "test_user" | ||
| output: | ||
| user_id: "test_bot" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| # Microsoft 365 Agents SDK for Python Integration Testing Framework | ||
|
|
Empty file.
Empty file.
16 changes: 16 additions & 0 deletions
16
dev/integration/integration/integration/foundational/_common.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| import json | ||
|
|
||
| from microsoft_agents.activity import Activity | ||
|
|
||
|
|
||
| def load_activity(channel: str, name: str) -> Activity: | ||
|
|
||
| with open( | ||
| "./dev/integration/src/tests/integration/foundational/activities/{}/{}.json".format( | ||
| channel, name | ||
| ), | ||
| "r", | ||
| ) as f: | ||
| activity = json.load(f) | ||
|
|
||
| return Activity.model_validate(activity) |
141 changes: 141 additions & 0 deletions
141
dev/integration/integration/integration/foundational/test_suite.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| import json | ||
| import pytest | ||
| import asyncio | ||
|
|
||
| from microsoft_agents.activity import ( | ||
| ActivityTypes, | ||
| ) | ||
|
|
||
| from src.core import integration, IntegrationFixtures, AiohttpEnvironment | ||
| from src.samples import QuickstartSample | ||
|
|
||
| from ._common import load_activity | ||
|
|
||
| DIRECTLINE = "directline" | ||
|
|
||
| @integration() | ||
| class TestFoundation(IntegrationFixtures): | ||
|
|
||
| def load_activity(self, activity_name) -> Activity: | ||
| return load_activity(DIRECTLINE, activity_name) | ||
|
|
||
| @pytest.mark.asyncio | ||
| async def test__send_activity__sends_hello_world__returns_hello_world(self, agent_client): | ||
| activity = load_activity(DIRECTLINE, "hello_world.json") | ||
| result = await agent_client.send_activity(activity) | ||
| assert result is not None | ||
| last = result[-1] | ||
| assert last.type == ActivityTypes.message | ||
| assert last.text.lower() == "you said: {activity.text}".lower() | ||
|
|
||
| @pytest.mark.asyncio | ||
| async def test__send_invoke__send_basic_invoke_activity__receive_invoke_response(self, agent_client): | ||
| activity = load_activity(DIRECTLINE, "basic_invoke.json") | ||
| result = await agent_client.send_activity(activity) | ||
| assert result | ||
| data = json.loads(result) | ||
| message = data.get("message", {}) | ||
| assert "Invoke received." in message | ||
| assert "data" in data | ||
| assert data["parameters"] and len(data["parameters"]) > 0 | ||
| assert "hi" in data["value"] | ||
|
|
||
| @pytest.mark.asyncio | ||
| async def test__send_activity__sends_message_activity_to_ac_submit__return_valid_response(self, agent_client): | ||
| activity = load_activity(DIRECTLINE, "ac_submit.json") | ||
| result = await agent_client.send_activity(activity) | ||
| assert result is not None | ||
| last = result[-1] | ||
| assert last.type == ActivityTypes.message | ||
| assert "doStuff" in last.text | ||
| assert "Action.Submit" in last.text | ||
| assert "hello" in last.text | ||
|
|
||
| @pytest.mark.asyncio | ||
| async def test__send_invoke_sends_invoke_activity_to_ac_execute__returns_valid_adaptive_card_invoke_response(self, agent_client): | ||
| activity = load_activity(DIRECTLINE, "ac_execute.json") | ||
| result = await agent_client.send_invoke(activity) | ||
|
|
||
| result = json.loads(result) | ||
|
|
||
| assert result.status == 200 | ||
| assert result.value | ||
|
|
||
| assert "application/vnd.microsoft.card.adaptive" in result.type | ||
|
|
||
| activity_data = json.loads(activity.value) | ||
| assert activity_data.get("action") | ||
| user_text = activity_data.get("usertext") | ||
| assert user_text in result.value | ||
|
|
||
| @pytest.mark.asyncio | ||
| async def test__send_activity_sends_text__returns_poem(self, agent_client): | ||
| pass | ||
|
|
||
| @pytest.mark.asyncio | ||
| async def test__send_expected_replies_activity__sends_text__returns_poem(self, agent_client): | ||
| activity = self.load_activity("expected_replies.json") | ||
| result = await agent_client.send_expected_replies(activity) | ||
| last = result[-1] | ||
| assert last.type == ActivityTypes.message | ||
| assert "Apollo" in last.text | ||
| assert "\n" in last.text | ||
|
|
||
| @pytest.mark.asyncio | ||
| async def test__send_invoke__query_link__returns_text(self, agent_client): | ||
| activity = self.load_activity("query_link.json") | ||
| result = await agent_client.send_invoke(activity) | ||
| pass # TODO | ||
|
|
||
| @pytest.mark.asyncio | ||
| async def test__send_invoke__select_item__receive_item(self, agent_client): | ||
| activity = self.load_activity("select_item.json") | ||
| result = await agent_client.send_invoke(activity) | ||
| pass # TODO | ||
|
|
||
| @pytest.mark.asyncio | ||
| async def test__send_activity__conversation_update__returns_welcome_message(self, agent_client): | ||
| activity = self.load_activity("conversation_update.json") | ||
| result = await agent_client.send_activity(activity) | ||
| last = result[-1] | ||
| assert "Hello and Welcome!" in last.text | ||
|
|
||
| @pytest.mark.asyncio | ||
| async def test__send_activity__send_heart_message_reaction__returns_message_reaction_heart(self, agent_client): | ||
| activity = self.load_activity("message_reaction_heart.json") | ||
| result = await agent_client.send_activity(activity) | ||
| last = result[-1] | ||
| assert last.type == ActivityTypes.message | ||
| assert "Message Reaction Added: heart" in last.text | ||
|
|
||
| @pytest.mark.asyncio | ||
| async def test__send_activity__remove_heart_message_reaction__returns_message_reaction_heart(self, agent_client): | ||
| activity = self.load_activity | ||
| result = await agent_client.send_activity(activity) | ||
| last = result[-1] | ||
| assert last.type == ActivityTypes.message | ||
| assert "Message Reaction Removed: heart" in last.text | ||
|
|
||
| @pytest.mark.asyncio | ||
| async def test__send_expected_replies_activity__send_seattle_today_weather__returns_weather(self, agent_client): | ||
| activity = self.load_activity("expected_replies_seattle_weather.json") | ||
| result = await agent_client.send_expected_replies(activity) | ||
| last = result[-1] | ||
| assert last.type == ActivityTypes.message | ||
| assert last.attachments and len(last.attachments) > 0 | ||
|
|
||
| adaptive_card = last.attachments.first() | ||
| assert adaptive_card | ||
| assert "application/vnd.microsoft.card.adaptive" == adaptive_card.content_type | ||
| assert adaptive_card.content | ||
|
|
||
| assert \ | ||
| "�" in adaptive_card.content or \ | ||
| "\\u00B0" in adaptive_card.content or \ | ||
| f"Missing temperature inside adaptive card: {adaptive_card.content}" in adaptive_card.content | ||
|
|
||
| @pytest.mark.asyncio | ||
| async def test__send_activity__simulate_message_loop__expect_question_about_time_and_returns_weather(self, agent_client): | ||
| activities = self.load_activity("message_loop_1.json") | ||
| fresult = await agent_client.send_activity(activities[0]) | ||
| assert | ||
21 changes: 21 additions & 0 deletions
21
dev/integration/integration/integration/test_quickstart.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # import pytest | ||
| # import asyncio | ||
|
|
||
| # from src.core import IntegrationFixtures, AiohttpEnvironment | ||
| # from src.samples import QuickstartSample | ||
|
|
||
| # class TestQuickstart(Integration): | ||
| # _sample_cls = QuickstartSample | ||
| # _environment_cls = AiohttpEnvironment | ||
|
|
||
| # @pytest.mark.asyncio | ||
| # async def test_welcome_message(self, agent_client, response_client): | ||
| # res = await agent_client.send_expect_replies("hi") | ||
| # await asyncio.sleep(1) # Wait for processing | ||
| # responses = await response_client.pop() | ||
|
|
||
| # assert len(responses) == 0 | ||
|
|
||
| # first_non_typing = next((r for r in res if r.type != "typing"), None) | ||
| # assert first_non_typing is not None | ||
| # assert first_non_typing.text == "you said: hi" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| aioresponses |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| from microsoft_agents.testing import DataDrivenTester | ||
|
|
||
|
|
||
| class TestBasics(DataDrivenTester): | ||
| _input_dir = "./data_driven_tests" | ||
|
|
||
| def test(self): | ||
| self._run_data_driven_test("input_file.json") |
Empty file.
File renamed without changes.
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
dev/microsoft-agents-testing/microsoft_agents/testing/assertions/__init__.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| # Copyright (c) Microsoft Corporation. All rights reserved. | ||
| # Licensed under the MIT License. | ||
|
|
||
| from .activity_assertion import ActivityAssertion | ||
| from .assertions import ( | ||
| assert_activity, | ||
| assert_field, | ||
| ) | ||
| from .check_activity import check_activity, check_activity_verbose | ||
| from .check_field import check_field, check_field_verbose | ||
| from .type_defs import FieldAssertionType, AssertionQuantifier, UNSET_FIELD | ||
| from .selector import Selector | ||
|
|
||
| __all__ = [ | ||
| "ActivityAssertion", | ||
| "assert_activity", | ||
| "assert_field", | ||
| "check_activity", | ||
| "check_activity_verbose", | ||
| "check_field", | ||
| "check_field_verbose", | ||
| "FieldAssertionType", | ||
| "Selector", | ||
| "AssertionQuantifier", | ||
| "UNSET_FIELD", | ||
| ] |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Syntax Error (in Python 3).