Skip to content

Commit 6626e88

Browse files
authored
Fix issue with results of tests with DataRow (#201)
***NO_CI***
1 parent c42205b commit 6626e88

File tree

4 files changed

+86
-92
lines changed

4 files changed

+86
-92
lines changed

source/TestAdapter/Discover.cs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -148,13 +148,11 @@ public static List<TestCase> ComposeTestCases(string sourceFile)
148148
var testCase = BuildTestCaseFromSourceFile(
149149
allCsFiles,
150150
typeCandidate,
151-
method,
152-
testMethodAttrib,
153-
i);
151+
method);
154152

155153
testCase.Source = sourceFile;
156154
testCase.ExecutorUri = new Uri(TestsConstants.NanoExecutor);
157-
testCase.FullyQualifiedName = $"{typeCandidate.FullName}.{testCase.DisplayName}";
155+
testCase.FullyQualifiedName = $"{typeCandidate.FullName}.{method.Name}.{i}";
158156
testCase.Traits.Add(new Trait("Type", testMethodAttrib.GetType().Name.Replace("Attribute", "")));
159157

160158
collectionOfTestCases.Add(testCase);
@@ -267,9 +265,7 @@ private static FileInfo[] FindNfprojFile(string source)
267265
private static TestCase BuildTestCaseFromSourceFile(
268266
string[] csFiles,
269267
Type className,
270-
MethodInfo method,
271-
object attribute,
272-
int attributeIndex)
268+
MethodInfo method)
273269
{
274270
TestCase testCase = new TestCase();
275271

@@ -296,10 +292,7 @@ private static TestCase BuildTestCaseFromSourceFile(
296292
{
297293
testCase.CodeFilePath = sourceFile;
298294
testCase.LineNumber = lineNumber;
299-
testCase.DisplayName = Helper.GetTestDisplayName(
300-
method,
301-
attribute,
302-
attributeIndex);
295+
testCase.DisplayName = method.Name;
303296

304297
return testCase;
305298
}

source/TestAdapter/Executor.cs

Lines changed: 73 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ namespace nanoFramework.TestPlatform.TestAdapter
3030
[ExtensionUri(TestsConstants.NanoExecutor)]
3131
class Executor : ITestExecutor
3232
{
33-
private const string TestPassed = "Test passed: ";
34-
private const string TestFailed = "Test failed: ";
35-
private const string TestSkipped = "Test skipped: ";
33+
private const string TestPassed = "Test passed";
34+
private const string TestFailed = "Test failed";
35+
private const string TestSkipped = "Test skipped";
3636
private const string Exiting = "Exiting.";
3737
private const string Done = "Done.";
3838
private Settings _settings;
@@ -554,6 +554,12 @@ private List<TestResult> PrepareListResult(List<TestCase> tests)
554554
foreach (var test in tests)
555555
{
556556
TestResult result = new TestResult(test) { Outcome = TestOutcome.None };
557+
558+
foreach (var t in result.Traits)
559+
{
560+
result.Traits.Add(new Trait(t.Name, ""));
561+
}
562+
557563
results.Add(result);
558564
}
559565

@@ -731,94 +737,101 @@ private void CheckAllTests(string rawOutput, List<TestResult> results)
731737
StringBuilder testOutput = new StringBuilder();
732738

733739
bool readyFound = false;
740+
string method;
741+
TestResult testResult = new TestResult(new TestCase());
742+
string[] resultDataSet = default;
734743

735744
foreach (var line in outputStrings)
736745
{
737-
if (line.Contains(TestPassed))
746+
if ((line.Contains(TestPassed)
747+
|| (line.Contains(TestFailed))
748+
|| (line.Contains(TestSkipped))))
738749
{
739-
// Format is "Test passed: MethodName, ticks";
750+
resultDataSet = line.Split(',');
740751

741-
string method = line.Substring(line.IndexOf(TestPassed) + TestPassed.Length).Split(',')[0];
742-
string ticks = line.Substring(line.IndexOf(TestPassed) + TestPassed.Length + method.Length + 2);
752+
// sanity check for enough data
753+
if (resultDataSet.Length != 3)
754+
{
755+
// something wrong!
756+
_logger.LogPanicMessage($"*** ERROR: can't parse test result {line}");
743757

744-
long ticksNum = 0;
745-
long.TryParse(ticks, out ticksNum);
758+
continue;
759+
}
760+
761+
method = resultDataSet[1].Trim();
746762

747763
// Find the test
748-
var res = results.FirstOrDefault(m => m.TestCase.DisplayName == method);
749-
if (res != null)
764+
testResult = results.FirstOrDefault(m => m.TestCase.FullyQualifiedName == method);
765+
766+
if (testResult is null)
750767
{
751-
res.Duration = TimeSpan.FromTicks(ticksNum);
752-
res.Outcome = TestOutcome.Passed;
753-
res.Messages.Add(new TestResultMessage(
754-
TestResultMessage.StandardOutCategory,
755-
testOutput.ToString()));
768+
// something wrong!
769+
_logger.LogPanicMessage($"*** ERROR: can't find test result for test {method}");
770+
771+
continue;
756772
}
773+
}
774+
775+
if (line.Contains(TestPassed))
776+
{
777+
// Format is "Test passed,MethodName,ticks";
778+
779+
string ticks = resultDataSet[2];
780+
long.TryParse(ticks, out long ticksNum);
781+
782+
testResult.Duration = TimeSpan.FromTicks(ticksNum);
783+
testResult.Outcome = TestOutcome.Passed;
784+
testResult.Messages.Add(new TestResultMessage(
785+
TestResultMessage.StandardOutCategory,
786+
testOutput.ToString()));
757787

758788
// reset test output
759789
testOutput = new StringBuilder();
760790
}
761791
else if (line.Contains(TestFailed))
762792
{
763-
// Format is "Test failed: MethodName, Exception message";
764-
765-
string method = line.Substring(line.IndexOf(TestFailed) + TestFailed.Length).Split(',')[0];
793+
// Format is "Test failed,MethodName,Exception message";
766794

767-
string exception = line.Substring(line.IndexOf(TestFailed) + TestFailed.Length + method.Length + 2);
768-
769-
// Find the test
770-
var res = results.FirstOrDefault(m => m.TestCase.DisplayName == method);
771-
if (res != null)
772-
{
773-
res.ErrorMessage = exception;
774-
res.Outcome = TestOutcome.Failed;
775-
res.Messages.Add(new TestResultMessage(
776-
TestResultMessage.StandardErrorCategory,
777-
testOutput.ToString()));
778-
}
795+
testResult.ErrorMessage = resultDataSet[2];
796+
testResult.Outcome = TestOutcome.Failed;
797+
testResult.Messages.Add(new TestResultMessage(
798+
TestResultMessage.StandardErrorCategory,
799+
testOutput.ToString()));
779800

780801
// reset test output
781802
testOutput = new StringBuilder();
782803
}
783804
else if (line.Contains(TestSkipped))
784805
{
785-
// Format is "Test failed: MethodName, Exception message";
806+
// Format is "Test failed,MethodName,Exception message";
786807

787-
string method = line.Substring(line.IndexOf(TestSkipped) + TestSkipped.Length).Split(',')[0];
808+
testResult.ErrorMessage = resultDataSet[2];
809+
testResult.Outcome = TestOutcome.Skipped;
810+
testResult.Messages.Add(new TestResultMessage(
811+
TestResultMessage.StandardErrorCategory,
812+
testOutput.ToString()));
788813

789-
string exception = line.Substring(line.IndexOf(TestSkipped) + TestSkipped.Length + method.Length + 2);
814+
// If this is a Steup Test, set all the other tests from the class to skipped as well
815+
var trait = testResult.TestCase.Traits.FirstOrDefault();
790816

791-
// Find the test
792-
var res = results.FirstOrDefault(m => m.TestCase.DisplayName == method);
793-
if (res != null)
817+
if (trait != null)
794818
{
795-
res.ErrorMessage = exception;
796-
res.Outcome = TestOutcome.Skipped;
797-
res.Messages.Add(new TestResultMessage(
798-
TestResultMessage.StandardErrorCategory,
799-
testOutput.ToString()));
800-
801-
// If this is a Steup Test, set all the other tests from the class to skipped as well
802-
var trait = res.TestCase.Traits.FirstOrDefault();
803-
if (trait != null)
819+
if (trait.Value == "Setup" && trait.Name == "Type")
804820
{
805-
if (trait.Value == "Setup" && trait.Name == "Type")
821+
// A test name is the full qualify name of the metho.methodname, finding the list . index will give all the familly name
822+
var testCasesToSkipName = testResult.TestCase.FullyQualifiedName.Substring(0, testResult.TestCase.FullyQualifiedName.LastIndexOf('.'));
823+
var allTestToSkip = results.Where(m => m.TestCase.FullyQualifiedName.Contains(testCasesToSkipName));
824+
foreach (var testToSkip in allTestToSkip)
806825
{
807-
// A test name is the full qualify name of the metho.methodname, finding the list . index will give all the familly name
808-
var testCasesToSkipName = res.TestCase.FullyQualifiedName.Substring(0, res.TestCase.FullyQualifiedName.LastIndexOf('.'));
809-
var allTestToSkip = results.Where(m => m.TestCase.FullyQualifiedName.Contains(testCasesToSkipName));
810-
foreach (var testToSkip in allTestToSkip)
826+
if(testToSkip.TestCase.FullyQualifiedName == resultDataSet[1])
811827
{
812-
if(testToSkip.TestCase.DisplayName == method)
813-
{
814-
continue;
815-
}
816-
817-
testToSkip.Outcome = TestOutcome.Skipped;
818-
res.Messages.Add(new TestResultMessage(
819-
TestResultMessage.StandardErrorCategory,
820-
$"Setup method '{method}' has been skipped."));
828+
continue;
821829
}
830+
831+
testToSkip.Outcome = TestOutcome.Skipped;
832+
testResult.Messages.Add(new TestResultMessage(
833+
TestResultMessage.StandardErrorCategory,
834+
$"Setup method '{testResult.DisplayName}' has been skipped."));
822835
}
823836
}
824837
}

source/TestFrameworkShared/Helper.cs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,6 @@ private static bool Any(this object[] array, AnyDelegateType predicate)
2626
return false;
2727
}
2828

29-
/// <summary>
30-
/// Generates test display name based on passed <paramref name="method"/>, <paramref name="attribute"/> and <paramref name="attributeIndex"/>.
31-
/// </summary>
32-
/// <returns>Returns method name with attributeIndex if passed attribute is of DataRow type</returns>
33-
public static string GetTestDisplayName(MethodInfo method, object attribute, int attributeIndex)
34-
{
35-
// Comparing via full name, because attribute parameter is from "TestFramework.dll"
36-
// and current type TestCaseAttribute is in scope of "TestAdapter" due to shared project
37-
// The same reason - reflection to get value
38-
if (attribute.GetType().FullName == typeof(DataRowAttribute).FullName)
39-
{
40-
return $"{method.Name} (index {attributeIndex})";
41-
}
42-
43-
return method.Name;
44-
}
45-
4629
/// <summary>
4730
/// Removes "TestMethod" attribute from array if "DataRow" attribute exists in the same array
4831
/// </summary>

source/UnitTestLauncher/Program.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ private static bool RunTest(
7474
for (int i = 0; i < attribs.Length; i++)
7575
{
7676
var attrib = attribs[i];
77-
var methodName = Helper.GetTestDisplayName(method, attrib, i);
77+
var methodName = $"{method.DeclaringType.FullName}.{method.Name}.{i}";
78+
7879
if (attribToRun != attrib.GetType())
7980
{
8081
continue;
@@ -87,13 +88,16 @@ private static bool RunTest(
8788
method.Invoke(null, parameters);
8889
totalTicks = DateTime.UtcNow.Ticks - dt;
8990

90-
Console.WriteLine($"Test passed: {methodName}, {totalTicks}");
91+
// on change this pattern it has to be updated at Executor.CheckAllTests
92+
Console.WriteLine($"Test passed,{methodName},{totalTicks}");
9193
}
9294
catch (Exception ex)
9395
{
9496
if (ex.GetType() == typeof(SkipTestException))
9597
{
96-
Console.WriteLine($"Test skipped: {methodName}, {ex.Message}");
98+
// on change this pattern it has to be updated at Executor.CheckAllTests
99+
Console.WriteLine($"Test skipped,{methodName},{ex.Message}");
100+
97101
if (isSetupMethod)
98102
{
99103
// In case the Setup attribute test is skipped, we will skip
@@ -103,7 +107,8 @@ private static bool RunTest(
103107
}
104108
else
105109
{
106-
Console.WriteLine($"Test failed: {methodName}, {ex.Message}");
110+
// on change this pattern it has to be updated at Executor.CheckAllTests
111+
Console.WriteLine($"Test failed,{methodName},{ex.Message}");
107112
}
108113
}
109114
}

0 commit comments

Comments
 (0)