Skip to content

Commit f5c1e89

Browse files
authored
Rework test discovery (#174)
1 parent 4684a1a commit f5c1e89

File tree

2 files changed

+71
-50
lines changed

2 files changed

+71
-50
lines changed

source/TestAdapter/Discover.cs

+68-47
Original file line numberDiff line numberDiff line change
@@ -103,54 +103,63 @@ public void DiscoverTests(IEnumerable<string> sources, IDiscoveryContext discove
103103
/// <returns>A list of test cases</returns>
104104
public static List<TestCase> FindTestCases(string source)
105105
{
106-
List<TestCase> testCases = new List<TestCase>();
106+
List<TestCase> collectionOfTestCases = new List<TestCase>();
107107

108108
var nfprojSources = FindNfprojSources(source);
109109
if (nfprojSources.Length == 0)
110110
{
111-
return testCases;
111+
return collectionOfTestCases;
112112
}
113113

114-
var allCsFils = GetAllCsFileNames(nfprojSources);
114+
var allCsFiles = GetAllCsFileNames(nfprojSources);
115115

116+
// developer note: we have to use LoadFile() and not Load() which loads the assembly into the caller domain
116117
Assembly test = Assembly.LoadFile(source);
117118
AppDomain.CurrentDomain.AssemblyResolve += App_AssemblyResolve;
118119
AppDomain.CurrentDomain.Load(test.GetName());
119120

120-
var allTypes = test.GetTypes().Where(x=> x.IsClass);
121-
foreach (var type in allTypes)
121+
var typeCandidatesForTests = test.GetTypes()
122+
.Where(x => x.IsClass);
123+
124+
foreach (var typeCandidate in typeCandidatesForTests)
122125
{
123-
if (!type.IsClass)
124-
{
125-
continue;
126-
}
126+
var testClasses = typeCandidate.GetCustomAttributes(true)
127+
.Where(x => x.GetType().FullName == typeof(TestClassAttribute).FullName);
127128

128-
var typeAttribs = type.GetCustomAttributes(true)
129-
.Where(x => x.GetType().FullName == typeof(TestClassAttribute).GetType().FullName);
130-
foreach (var typeAttrib in typeAttribs)
129+
foreach (var testClassAttrib in testClasses)
131130
{
132-
var methods = type.GetMethods();
131+
var methods = typeCandidate.GetMethods();
132+
133133
// First we look at Setup
134134
foreach (var method in methods)
135135
{
136-
var attribs = method.GetCustomAttributes(true);
137-
attribs = Helper.RemoveTestMethodIfDataRowExists(attribs);
138-
var attribsToItterate = attribs.Where(x => IsTestMethod(x)).ToArray();
139-
for (int i = 0; i < attribsToItterate.Length; i++)
136+
var methodAttribs = method.GetCustomAttributes(true);
137+
methodAttribs = Helper.RemoveTestMethodIfDataRowExists(methodAttribs);
138+
139+
var testMethodsToItterate = methodAttribs.Where(x => IsTestMethod(x)).ToArray();
140+
141+
for (int i = 0; i < testMethodsToItterate.Length; i++)
140142
{
141-
var attrib = attribsToItterate[i];
142-
var testCase = GetFileNameAndLineNumber(allCsFils, type, method, attrib, i);
143+
var testMethodAttrib = testMethodsToItterate[i];
144+
var testCase = GetFileNameAndLineNumber(
145+
allCsFiles,
146+
typeCandidate,
147+
method,
148+
testMethodAttrib,
149+
i);
150+
143151
testCase.Source = source;
144152
testCase.ExecutorUri = new Uri(TestsConstants.NanoExecutor);
145-
testCase.FullyQualifiedName = $"{type.FullName}.{testCase.DisplayName}";
146-
testCase.Traits.Add(new Trait("Type", attrib.GetType().Name.Replace("Attribute", "")));
147-
testCases.Add(testCase);
153+
testCase.FullyQualifiedName = $"{typeCandidate.FullName}.{testCase.DisplayName}";
154+
testCase.Traits.Add(new Trait("Type", testMethodAttrib.GetType().Name.Replace("Attribute", "")));
155+
156+
collectionOfTestCases.Add(testCase);
148157
}
149158
}
150159
}
151160
}
152161

153-
return testCases;
162+
return collectionOfTestCases;
154163
}
155164

156165
private static bool IsTestMethod(object attrib)
@@ -244,42 +253,54 @@ private static FileInfo[] FindNfprojSources(string source)
244253
}
245254
}
246255

247-
private static TestCase GetFileNameAndLineNumber(string[] csFiles, Type className, MethodInfo method, object attribute, int attributeIndex)
256+
private static TestCase GetFileNameAndLineNumber(
257+
string[] csFiles,
258+
Type className,
259+
MethodInfo method,
260+
object attribute,
261+
int attributeIndex)
248262
{
249-
var clName = className.Name;
250-
var methodName = method.Name;
251-
TestCase flret = new TestCase();
263+
TestCase testCase = new TestCase();
264+
252265
foreach (var csFile in csFiles)
253266
{
254-
StreamReader sr = new StreamReader(csFile);
255-
var allFile = sr.ReadToEnd();
256-
if (!allFile.Contains($"class {clName}"))
267+
using (StreamReader sr = new StreamReader(csFile))
257268
{
258-
continue;
259-
}
269+
var fileContent = sr.ReadToEnd();
260270

261-
if (!allFile.Contains($" {methodName}("))
262-
{
263-
continue;
264-
}
271+
if (!fileContent.Contains($"class {className.Name}"))
272+
{
273+
continue;
274+
}
265275

266-
// We found it!
267-
int lineNum = 1;
268-
foreach (var line in allFile.Split('\r'))
269-
{
270-
if (line.Contains($" {methodName}("))
276+
if (!fileContent.Contains($" {method.Name}("))
271277
{
272-
flret.CodeFilePath = csFile;
273-
flret.LineNumber = lineNum;
274-
flret.DisplayName = Helper.GetTestDisplayName(method, attribute, attributeIndex);
275-
return flret;
278+
continue;
276279
}
277280

278-
lineNum++;
281+
// We found it!
282+
int lineNumber = 1;
283+
284+
foreach (var line in fileContent.Split('\r'))
285+
{
286+
if (line.Contains($" {method.Name}("))
287+
{
288+
testCase.CodeFilePath = csFile;
289+
testCase.LineNumber = lineNumber;
290+
testCase.DisplayName = Helper.GetTestDisplayName(
291+
method,
292+
attribute,
293+
attributeIndex);
294+
295+
return testCase;
296+
}
297+
298+
lineNumber++;
299+
}
279300
}
280301
}
281302

282-
return flret;
303+
return testCase;
283304
}
284305
}
285306
}

source/TestAdapter/Properties/launchSettings.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
"profiles": {
33
"nanoFramework.TestAdapter": {
44
"commandName": "Executable",
5-
"executablePath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Professional\\Common7\\IDE\\Extensions\\TestPlatform\\vstest.console.exe",
6-
"commandLineArgs": "E:\\Github\\nflib-CoreLibrary\\Tests\\NFUnitTestThread\\bin\\Debug\\NFUnitTest.dll /Settings:E:\\Github\\nflib-CoreLibrary\\Tests\\NFUnitTestThread\\nano.runsettings /TestAdapterPath:."
5+
"executablePath": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\Common7\\IDE\\Extensions\\TestPlatform\\vstest.console.exe",
6+
"commandLineArgs": "E:\\GitHub\\nf-nanoFramework.TestFramework\\poc\\TestOfTestFramework\\bin\\Debug\\NFUnitTest.dll /Settings:E:\\GitHub\\nf-nanoFramework.TestFramework\\poc\\.runsettings /TestAdapterPath:."
77
},
88
"nanoFramework.TestAdapter Enterprise": {
99
"commandName": "Executable",
1010
"executablePath": "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\Common7\\IDE\\Extensions\\TestPlatform\\vstest.console.exe",
11-
"commandLineArgs": "C:\\Repos\\nanoFramework\\lib-CoreLibrary\\nanoFramework.TestFramework\\poc\\TestOfTestFrameworkByReference\\bin\\Debug\\NFUnitTest.dll /Settings:C:\\Repos\\nanoFramework\\lib-CoreLibrary\\nanoFramework.TestFramework\\poc\\TestOfTestFrameworkByReference\\nano.runsettings /TestAdapterPath:."
11+
"commandLineArgs": "C:\\Repos\\nanoFramework\\lib-CoreLibrary\\nanoFramework.TestFramework\\poc\\TestOfTestFrameworkByReference\\bin\\Debug\\NFUnitTest.dll /Settings:C:\\Repos\\nanoFramework\\lib-CoreLibrary\\nanoFramework.TestFramework\\poc\\TestOfTestFrameworkByReference\\.runsettings /TestAdapterPath:."
1212
}
1313
}
1414
}

0 commit comments

Comments
 (0)