Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ CodeCoverage/
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

# Test Coverage
coverage/
coverage-report/
coverage-report-all/
TestResults/
*.cobertura.xml
*.trx

# Visual Studio
.vs/

Expand Down
27 changes: 27 additions & 0 deletions src/Tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Microsoft Agent 365 SDK Tests

Unit and integration tests for the Microsoft Agent 365 .NET SDK. This test suite ensures reliability, maintainability, and quality across all modules including runtime, tooling, notifications, and observability extensions.

## Usage

For detailed instructions on running tests and generating coverage reports, see:

- [Test Plan](TEST_PLAN.md) - Comprehensive testing strategy and implementation roadmap
- [Running Tests](RUNNING_TESTS.md) - Complete guide for installation, running tests, generating coverage reports, and troubleshooting

## Support

For issues, questions, or feedback:

- File issues in the [GitHub Issues](https://github.com/microsoft/Agent365-dotnet/issues) section
- See the [main documentation](../README.md) for more information

## Trademarks

Microsoft, Windows, Microsoft Azure and/or other Microsoft products and services referenced in the documentation may be either trademarks or registered trademarks of Microsoft in the United States and/or other countries. The licenses for this project do not grant you rights to use any Microsoft names, logos, or trademarks. Microsoft's general trademark guidelines can be found at http://go.microsoft.com/fwlink/?LinkID=254653.

## License

Copyright (c) Microsoft Corporation. All rights reserved.

Licensed under the MIT License - see the [LICENSE](../LICENSE) file for details.
147 changes: 147 additions & 0 deletions src/Tests/RUNNING_TESTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# Running Unit Tests for Agent365-dotnet SDK

This guide covers setting up and running tests.

---

## Prerequisites

### 1. Install .NET SDK

Ensure you have .NET 8 SDK or later installed:

```powershell
# Verify installation
dotnet --version # Should be 8.0.0 or later
```

### 2. Restore Dependencies

```powershell
# From repository root
dotnet restore

# Or from src directory
cd src
dotnet restore
```

---

## Test Structure

> **Note:** This structure will be updated as new tests are added.

```plaintext
Tests/
├── Runtime.Tests/ # Runtime core tests
├── Microsoft.Agents.A365.Observability.Runtime.Tests/ # Observability runtime tests
├── Microsoft.Agents.A365.Observability.Hosting.Tests/ # Observability hosting tests
├── Microsoft.Agents.A365.Observability.Extension.Tests/ # Observability extension tests
└── Microsoft.Agents.A365.Notifications.Tests/ # Notifications tests
```

---

## Running Tests in VS Code (Optional)

### Test Explorer

1. Install **C# Dev Kit** extension
2. Click the beaker icon in the Activity Bar or press `Ctrl+Shift+P` → "Test: Focus on Test Explorer View"
3. Click the play button to run tests (all/folder/file/individual)
4. Right-click → "Debug Test" to debug with breakpoints

### Command Palette

- `Test: Run All Tests`
- `Test: Run Tests in Current File`
- `Test: Debug Tests in Current File`

---

## Running Tests from Command Line

```powershell
# Run all tests
dotnet test

# Run specific module/file
dotnet test Tests/Runtime.Tests/
dotnet test Tests/Runtime.Tests/Microsoft.Agents.A365.Runtime.Tests.csproj

# Run with options
dotnet test --verbosity detailed # Verbose
dotnet test --filter "FullyQualifiedName~Utility" # Pattern matching
dotnet test --logger "console;verbosity=detailed" # Detailed logging
```

---

## Generating Reports

### HTML Reports

```powershell
# Install coverage tools (one-time)
dotnet tool install --global dotnet-reportgenerator-globaltool

# Generate coverage report
dotnet test --collect:"XPlat Code Coverage" --results-directory ./coverage

# Generate HTML report
reportgenerator -reports:"./coverage/**/coverage.cobertura.xml" -targetdir:"./coverage-report" -reporttypes:Html

# View reports
start ./coverage-report/index.html
```

### CI/CD Reports

```powershell
# XML reports for CI/CD pipelines
dotnet test --logger "trx;LogFileName=test-results.trx" --collect:"XPlat Code Coverage"

# View reports
start TestResults/test-results.trx
```

---

## Troubleshooting

### Common Issues

| Issue | Solution |
|-------|----------|
| **Test loading failed** | Clean and rebuild: `dotnet clean`, then `dotnet build` |
| **Tests not discovered** | Verify `[Fact]` or `[Theory]` attributes, refresh Test Explorer |
| **Build failures** | Run `dotnet restore`, check package references |
| **Coverage not generated** | Verify `coverlet.collector` package is referenced |

### Fix Steps

If tests fail to discover or build errors occur:

**1. Clean and Rebuild**

```powershell
dotnet clean
dotnet restore
dotnet build
```

**2. Clear Test Cache**

```powershell
Remove-Item -Recurse -Force bin, obj
dotnet restore
dotnet build
dotnet test
```

**3. Restart VS Code**

- Close completely and reopen
- Wait for C# extension to reload
- Refresh Test Explorer
99 changes: 99 additions & 0 deletions src/Tests/Runtime.Tests/AgenticAuthenticationServiceTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using Microsoft.Agents.A365.Runtime.Utils;
using Microsoft.Extensions.Configuration;
using Moq;
using System;
using System.Collections.Generic;
using Xunit;

namespace Microsoft.Agents.A365.Runtime.Tests
{
/// <summary>
/// Unit tests for AgenticAuthenticationService class.
/// Tests the authentication token retrieval and utility methods.
/// </summary>
public class AgenticAuthenticationServiceTests
Comment on lines +14 to +17
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The class name AgenticAuthenticationServiceTests suggests this class tests AgenticAuthenticationService, but the tests are actually testing Utility class methods (Utility.GetMcpPlatformAuthenticationScope and Utility.GetCurrentEnvironment).

Consider renaming this class to better reflect what it's testing, such as UtilityConfigurationTests or moving these tests into the existing UtilityTests class to avoid confusion.

Suggested change
/// Unit tests for AgenticAuthenticationService class.
/// Tests the authentication token retrieval and utility methods.
/// </summary>
public class AgenticAuthenticationServiceTests
/// Unit tests for configuration-related methods in the Utility class.
/// Tests Utility.GetMcpPlatformAuthenticationScope and Utility.GetCurrentEnvironment.
/// </summary>
public class UtilityConfigurationTests

Copilot uses AI. Check for mistakes.
{
[Theory]
[InlineData("custom-scope", "custom-scope")] // Custom scope
[InlineData("SKIP", "ea9ffc3e-8a23-4a7d-836d-234d7c7565c1/.default")] // Null returns default
[InlineData("", "")] // Empty string
public void GetMcpPlatformAuthenticationScope_WithVariousConfigurations_ReturnsExpectedScope(
string? configValue,
string expectedScope)
{
// Arrange
var mockConfiguration = new Mock<IConfiguration>();
mockConfiguration.Setup(c => c["MCP_PLATFORM_AUTHENTICATION_SCOPE"])
.Returns(configValue == "SKIP" ? null : configValue);

// Act
var result = Utility.GetMcpPlatformAuthenticationScope(mockConfiguration.Object);

// Assert
Assert.Equal(expectedScope, result);
}

[Theory]
[InlineData("Production", "SKIP", "Production")] // ASPNETCORE_ENVIRONMENT takes precedence
[InlineData("SKIP", "Development", "Development")] // Falls back to DOTNET_ENVIRONMENT
[InlineData("SKIP", "SKIP", "Development")] // Both null returns default
public void GetCurrentEnvironment_WithVariousConfigurations_ReturnsExpectedEnvironment(
string? aspNetCoreEnv,
string? dotNetEnv,
string expectedEnvironment)
{
// Arrange
var mockConfiguration = new Mock<IConfiguration>();
mockConfiguration.Setup(c => c["ASPNETCORE_ENVIRONMENT"])
.Returns(aspNetCoreEnv == "SKIP" ? null : aspNetCoreEnv);
mockConfiguration.Setup(c => c["DOTNET_ENVIRONMENT"])
.Returns(dotNetEnv == "SKIP" ? null : dotNetEnv);

// Act
var result = Utility.GetCurrentEnvironment(mockConfiguration.Object);

// Assert
Assert.Equal(expectedEnvironment, result);
}

[Fact]
public void GetMcpPlatformAuthenticationScope_ConfigurationReturnsNull_ReturnsDefaultScope()
{
// Arrange
var mockConfiguration = new Mock<IConfiguration>();
mockConfiguration.Setup(c => c["MCP_PLATFORM_AUTHENTICATION_SCOPE"])
.Returns((string?)null);

// Act
var result = Utility.GetMcpPlatformAuthenticationScope(mockConfiguration.Object);

// Assert
Assert.Equal("ea9ffc3e-8a23-4a7d-836d-234d7c7565c1/.default", result);
}

[Theory]
[InlineData("scope1", 1)]
[InlineData("scope2", 3)]
public void GetMcpPlatformAuthenticationScope_CalledMultipleTimes_AccessesConfigurationCorrectly(
string testScope,
int callCount)
{
// Arrange
var mockConfiguration = new Mock<IConfiguration>();
mockConfiguration.Setup(c => c["MCP_PLATFORM_AUTHENTICATION_SCOPE"])
.Returns(testScope);

// Act
for (int i = 0; i < callCount; i++)
{
Utility.GetMcpPlatformAuthenticationScope(mockConfiguration.Object);
}

// Assert
mockConfiguration.Verify(c => c["MCP_PLATFORM_AUTHENTICATION_SCOPE"], Times.Exactly(callCount));
}
Comment on lines +80 to +97
Copy link

Copilot AI Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test at line 99 (GetMcpPlatformAuthenticationScope_CalledMultipleTimes_AccessesConfigurationCorrectly) doesn't verify the actual return value of the method being tested. It only verifies that the configuration was accessed the correct number of times.

While verifying interaction count can be useful, this test should also assert that the correct scope value is returned on each call to ensure the method behaves correctly, not just that it accesses configuration. Consider adding assertions like:

var result = Utility.GetMcpPlatformAuthenticationScope(mockConfiguration.Object);
Assert.Equal(testScope, result);

inside the loop or after it.

Copilot uses AI. Check for mistakes.
}
}
Loading