🔍 Duplicate Code Detected: CIEnvironmentDetector Class
Analysis of commit 3e056b0
Assignee: @copilot
Summary
The CIEnvironmentDetector class is nearly identically duplicated in two separate namespaces: Microsoft.VisualStudio.TestTools.UnitTesting (TestFramework) and Microsoft.Testing.Platform.Helpers (MTP). Both classes contain the same arrays of CI environment variable names and the same IsCIEnvironment() detection logic (~100 lines each).
Duplication Details
Pattern: Near-identical CIEnvironmentDetector class
- Severity: Medium
- Occurrences: 2 instances
- Locations:
src/TestFramework/TestFramework/Internal/CIEnvironmentDetector.cs (lines 23–114)
src/Platform/Microsoft.Testing.Platform/Helpers/CIEnvironmentDetector.cs (lines 15–110)
- Code Sample (same arrays in both files):
// Same CI-system variable arrays in both files:
private static readonly string[] BooleanVariables = [
"TF_BUILD",
"GITHUB_ACTIONS",
"APPVEYOR",
"CI",
"TRAVIS",
"CIRCLECI",
];
private static readonly string[][] AllNotNullVariables = [
["CODEBUILD_BUILD_ID", "AWS_REGION"],
["BUILD_ID", "BUILD_URL"],
["BUILD_ID", "PROJECT_ID"],
];
private static readonly string[] IfNonNullVariables = [
"TEAMCITY_VERSION",
"JB_SPACE_API_URL",
];
// Same IsCIEnvironment() logic in both files
public bool IsCIEnvironment() { ... }
Differences are minimal:
- Namespace (
Microsoft.VisualStudio.TestTools.UnitTesting vs Microsoft.Testing.Platform.Helpers)
[Embedded]/[ExcludeFromCodeCoverage] attributes only on the Platform version
- A static
Instance property only in the TestFramework version
string.IsNullOrEmpty vs global::Microsoft.Testing.Platform.RoslynString.IsNullOrEmpty
Impact Analysis
- Maintainability: Any CI system addition/removal requires changing two files. The current lists are already out of sync — the Platform version has XML docs on the constructor while the TestFramework version marks it
internal /* for testing purposes */.
- Bug Risk: If a new CI provider is added to one file but not the other, the two assemblies will behave differently when detecting the CI environment.
- Code Bloat: ~100 lines of near-identical code maintained in two places.
Refactoring Recommendations
-
Use a source-linked file (preferred for embedded classes):
- Keep the canonical copy in the Platform project (or TestFramework) and add a linked file in the other project via
<Compile Include="..." Link="..." />
- Adjust
RoslynString.IsNullOrEmpty vs string.IsNullOrEmpty differences via a #if guard or a shared helper
-
Move to a shared helper project:
- Add to
SharedExtensionHelpers or a similar internal shared project
- Reference from both TestFramework and Platform
-
Add a comment documenting the intentional copy if sharing is impractical:
- At minimum add a comment pointing to the authoritative copy
Implementation Checklist
Analysis Metadata
- Analyzed Files: 2
- Duplicated Lines: ~90 lines per file (180 lines total, ~90 lines redundant)
- Detection Method: Semantic code analysis + diff comparison
- Commit: 3e056b0
- Analysis Date: 2026-06-10
🤖 Automated content by GitHub Copilot. Posted via a maintainer's GitHub token, so it appears under their account — the account owner did not write or approve this content personally. Generated by the Duplicate Code Detector workflow.{ai_credits_suffix} · [◷]( · ◷)
Add this agentic workflows to your repo
To install this agentic workflow, run
gh aw add githubnext/agentics/workflows/duplicate-code-detector.md@main
🔍 Duplicate Code Detected: CIEnvironmentDetector Class
Analysis of commit 3e056b0
Assignee:
@copilotSummary
The
CIEnvironmentDetectorclass is nearly identically duplicated in two separate namespaces:Microsoft.VisualStudio.TestTools.UnitTesting(TestFramework) andMicrosoft.Testing.Platform.Helpers(MTP). Both classes contain the same arrays of CI environment variable names and the sameIsCIEnvironment()detection logic (~100 lines each).Duplication Details
Pattern: Near-identical CIEnvironmentDetector class
src/TestFramework/TestFramework/Internal/CIEnvironmentDetector.cs(lines 23–114)src/Platform/Microsoft.Testing.Platform/Helpers/CIEnvironmentDetector.cs(lines 15–110)Differences are minimal:
Microsoft.VisualStudio.TestTools.UnitTestingvsMicrosoft.Testing.Platform.Helpers)[Embedded]/[ExcludeFromCodeCoverage]attributes only on the Platform versionInstanceproperty only in the TestFramework versionstring.IsNullOrEmptyvsglobal::Microsoft.Testing.Platform.RoslynString.IsNullOrEmptyImpact Analysis
internal /* for testing purposes */.Refactoring Recommendations
Use a source-linked file (preferred for embedded classes):
<Compile Include="..." Link="..." />RoslynString.IsNullOrEmptyvsstring.IsNullOrEmptydifferences via a#ifguard or a shared helperMove to a shared helper project:
SharedExtensionHelpersor a similar internal shared projectAdd a comment documenting the intentional copy if sharing is impractical:
Implementation Checklist
IEnvironmentmocks against this classAnalysis Metadata
Add this agentic workflows to your repo
To install this agentic workflow, run