Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
31 changes: 31 additions & 0 deletions poc/TestOfTestFrameworkByReference/DataRowTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// Copyright (c) .NET Foundation and Contributors
// Portions Copyright (c) Microsoft Corporation. All rights reserved.
// See LICENSE file in the project root for full license information.
//

using System;
using System.Diagnostics;
using System.Threading;

namespace nanoFramework.TestFramework.Test
{
[TestClass]
public class TestOfDataRow
{
[DataRow(1, 2, 3)]
[DataRow(5, 6, 11)]
public void TestAddition(int number1, int number2, int result)
{
var additionResult = number1 + number2;

Assert.Equal(additionResult, result);
}

[DataRow("TestString")]
public void TestString(string testData)
{
Assert.Equal(testData, "TestString");
}
}
}
11 changes: 5 additions & 6 deletions poc/TestOfTestFrameworkByReference/NFUnitTestByReference.nfproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
<RunSettingsFilePath>$(MSBuildProjectDirectory)\nano.runsettings</RunSettingsFilePath>
</PropertyGroup>
<ItemGroup>
<Compile Include="DataRowTests.cs" />
<Compile Include="SkipFewMethods.cs" />
<Compile Include="SkipTestClass.cs" />
<Compile Include="Test.cs" />
Expand All @@ -41,13 +42,11 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Reference Include="mscorlib, Version=1.11.7.2, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>..\packages\nanoFramework.CoreLibrary.1.11.7\lib\mscorlib.dll</HintPath>
<Private>True</Private>
<Reference Include="mscorlib">
<HintPath>..\packages\nanoFramework.CoreLibrary.1.12.0\lib\mscorlib.dll</HintPath>
</Reference>
<Reference Include="nanoFramework.Runtime.Native, Version=1.5.2.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>..\packages\nanoFramework.Runtime.Native.1.5.2-preview.6\lib\nanoFramework.Runtime.Native.dll</HintPath>
<Private>True</Private>
<Reference Include="nanoFramework.Runtime.Native">
<HintPath>..\packages\nanoFramework.Runtime.Native.1.5.4\lib\nanoFramework.Runtime.Native.dll</HintPath>
</Reference>
</ItemGroup>
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets')" />
Expand Down
4 changes: 2 additions & 2 deletions poc/TestOfTestFrameworkByReference/packages.config
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="nanoFramework.CoreLibrary" version="1.11.7" targetFramework="netnanoframework10" />
<package id="nanoFramework.Runtime.Native" version="1.5.2-preview.6" targetFramework="netnanoframework10" />
<package id="nanoFramework.CoreLibrary" version="1.12.0" targetFramework="netnanoframework10" />
<package id="nanoFramework.Runtime.Native" version="1.5.4" targetFramework="netnanoframework10" />
</packages>
9 changes: 5 additions & 4 deletions source/TestAdapter/Discover.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,10 @@ public static List<TestCase> FindTestCases(string source)
{
if (attrib.GetType().FullName == typeof(SetupAttribute).FullName ||
attrib.GetType().FullName == typeof(TestMethodAttribute).FullName ||
attrib.GetType().FullName == typeof(CleanupAttribute).FullName)
attrib.GetType().FullName == typeof(CleanupAttribute).FullName ||
attrib.GetType().FullName == typeof(DataRowAttribute).FullName)
{
var testCase = GetFileNameAndLineNumber(allCsFils, type, method);
var testCase = GetFileNameAndLineNumber(allCsFils, type, method, attrib);
testCase.Source = source;
testCase.ExecutorUri = new Uri(TestsConstants.NanoExecutor);
testCase.FullyQualifiedName = $"{type.FullName}.{testCase.DisplayName}";
Expand Down Expand Up @@ -221,7 +222,7 @@ private static FileInfo[] FindNfprojSources(string source)
}
}

private static TestCase GetFileNameAndLineNumber(string[] csFiles, Type className, MethodInfo method)
private static TestCase GetFileNameAndLineNumber(string[] csFiles, Type className, MethodInfo method, object attribute)
{
var clName = className.Name;
var methodName = method.Name;
Expand All @@ -242,7 +243,7 @@ private static TestCase GetFileNameAndLineNumber(string[] csFiles, Type classNam
{
flret.CodeFilePath = csFile;
flret.LineNumber = lineNum;
flret.DisplayName = method.Name;
flret.DisplayName = Helper.GetTestDisplayName(method, attribute);
return flret;
}

Expand Down
7 changes: 3 additions & 4 deletions source/TestAdapter/Executor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -735,9 +735,8 @@ private void CheckAllTests(string rawOutput, List<TestResult> results)
if (line.Contains(TestPassed))
{
// Format is "Test passed: MethodName, ticks";
// We do get split with space if the coma is missing, happens time to time

string method = line.Substring(line.IndexOf(TestPassed) + TestPassed.Length).Split(',')[0].Split(' ')[0];
string method = line.Substring(line.IndexOf(TestPassed) + TestPassed.Length).Split(',')[0];
string ticks = line.Substring(line.IndexOf(TestPassed) + TestPassed.Length + method.Length + 2);

long ticksNum = 0;
Expand All @@ -761,7 +760,7 @@ private void CheckAllTests(string rawOutput, List<TestResult> results)
{
// Format is "Test failed: MethodName, Exception message";

string method = line.Substring(line.IndexOf(TestFailed) + TestFailed.Length).Split(',')[0].Split(' ')[0];
string method = line.Substring(line.IndexOf(TestFailed) + TestFailed.Length).Split(',')[0];

string exception = line.Substring(line.IndexOf(TestFailed) + TestPassed.Length + method.Length + 2);

Expand All @@ -783,7 +782,7 @@ private void CheckAllTests(string rawOutput, List<TestResult> results)
{
// Format is "Test failed: MethodName, Exception message";

string method = line.Substring(line.IndexOf(TestSkipped) + TestSkipped.Length).Split(',')[0].Split(' ')[0];
string method = line.Substring(line.IndexOf(TestSkipped) + TestSkipped.Length).Split(',')[0];

string exception = line.Substring(line.IndexOf(TestSkipped) + TestPassed.Length + method.Length + 2);

Expand Down
43 changes: 43 additions & 0 deletions source/TestFrameworkShared/DataRowAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// Copyright (c) .NET Foundation and Contributors
// Portions Copyright (c) Microsoft Corporation. All rights reserved.
// See LICENSE file in the project root for full license information.
//

using System;

namespace nanoFramework.TestFramework
{
/// <summary>
/// Data row attribute. Used for passing multiple parameters into same test method.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class DataRowAttribute : Attribute
{
/// <summary>
/// Array containing all passed parameters
/// </summary>
public object[] MethodParameters { get; }

/// <summary>
/// Initializes a new instance of the DataRowAttribute class.
/// </summary>
/// <param name="methodParameters">Parameters which should be stored for future execution of test method</param>
/// <exception cref="ArgumentNullException">Thrown when methodParameters is null</exception>
/// <exception cref="ArgumentException">Thrown when methodParameters is empty</exception>
public DataRowAttribute(params object[] methodParameters)
{
if (methodParameters == null)
{
throw new ArgumentNullException($"{nameof(methodParameters)} can not be null");
}

if (methodParameters.Length == 0)
{
throw new ArgumentException($"{nameof(methodParameters)} can not be empty");
}

MethodParameters = methodParameters;
}
}
}
51 changes: 51 additions & 0 deletions source/TestFrameworkShared/Helper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// Copyright (c) .NET Foundation and Contributors
// Portions Copyright (c) Microsoft Corporation. All rights reserved.
// See LICENSE file in the project root for full license information.
//

using System.Reflection;

namespace nanoFramework.TestFramework
{
/// <summary>
/// Helper class for keeping test name same in TestAdapter and TestRunner
/// </summary>
public static class Helper
{
private static string GetJoinedParams(object[] data)
{
var returnString = string.Empty;
foreach (var item in data)
{
returnString += $"{item} | ";
}

// In each loop iteration we are appending " | " event at the end
// To keep return string clean, we are removing last 3 charcters
// Lenght starts from 1, substring from 0
// To remove 3 last characters using this method, we need to add 1
return returnString.Substring(0, returnString.Length - 4);
}

/// <summary>
/// Generates test display name based on passed <paramref name="method"/> and <paramref name="attribute"/>.
/// </summary>
/// <returns>Returns method name with parameters if passed attribute is of DataRow type</returns>
public static string GetTestDisplayName(MethodInfo method, object attribute)
{
// Comparing via full name, because attribute parameter is from "TestFramework.dll"
// and current type TestCaseAttribute is in scope of "TestAdapter" due to shared project
// The same reason - reflection to get value
if (attribute.GetType().FullName == typeof(DataRowAttribute).FullName)
{
var methodParameters = (object[])attribute.GetType()
.GetMethod($"get_{nameof(DataRowAttribute.MethodParameters)}").Invoke(attribute, null);

return $"{method.Name} - (params: {GetJoinedParams(methodParameters)})";
}

return method.Name;
}
}
}
2 changes: 2 additions & 0 deletions source/TestFrameworkShared/TestFrameworkShared.projitems
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)CleanupAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)DataRowAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Helper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)SetupAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)SkipTestException.cs" />
<Compile Include="$(MSBuildThisFileDirectory)TestClassAttribute.cs" />
Expand Down
22 changes: 18 additions & 4 deletions source/UnitTestLauncher/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public static void Main()
{
// then we run the tests
RunTest(methods, typeof(TestMethodAttribute));
RunTest(methods, typeof(DataRowAttribute));

// last we handle Cleanup
RunTest(methods, typeof(CleanupAttribute));
Expand All @@ -67,21 +68,23 @@ private static bool RunTest(

foreach (var attrib in attribs)
{
var methodName = Helper.GetTestDisplayName(method, attrib);
if (attribToRun == attrib.GetType())
{
try
{
dt = DateTime.UtcNow.Ticks;
method.Invoke(null, null);
object[] parameters = GetParameters(attrib);
method.Invoke(null, parameters);
totalTicks = DateTime.UtcNow.Ticks - dt;

Console.WriteLine($"Test passed: {method.Name}, {totalTicks}");
Console.WriteLine($"Test passed: {methodName}, {totalTicks}");
}
catch (Exception ex)
{
if (ex.GetType() == typeof(SkipTestException))
{
Console.WriteLine($"Test skipped: {method.Name}, {ex.Message}");
Console.WriteLine($"Test skipped: {methodName}, {ex.Message}");
if (isSetupMethod)
{
// In case the Setup attribute test is skipped, we will skip
Expand All @@ -91,7 +94,7 @@ private static bool RunTest(
}
else
{
Console.WriteLine($"Test failed: {method.Name}, {ex.Message}");
Console.WriteLine($"Test failed: {methodName}, {ex.Message}");
}
}

Expand All @@ -101,5 +104,16 @@ private static bool RunTest(

return true;
}

private static object[] GetParameters(object attribute)
{
if (attribute.GetType() != typeof(DataRowAttribute))
{
return null;
}

var testCaseAttribute = (DataRowAttribute)attribute;
return testCaseAttribute.MethodParameters;
}
}
}