Mixing custom Test Steps, created for .NET6.0 and .NET4.8

Hi,

first our the complete setup:

  • OpenTAP 9.17.4.0, with “Developer’s System CE” is installed in D:\OpenTAP
  • All our custom Steps are located in D:\OpenTAP\Plugins, each Step in its own folder.

We have following Test Steps:

  1. Test Step “Test48_1”, created in VS2022 based on the “OpenTAP Plugin Project (.NET Standard)” template. The TargetFramework has been modified for “net48”.
  2. Test Step “Test48_2”, in VS2022 as 'Class Library (.NET Framework), for net4.8, and added the OpenTap package via NuGet.
  3. Test Step “Test60_1”, in VS2022 as ‘Class Library’, for net6.0, and added the OpenTap package via NuGet.
  4. Test Step “Test60_2”, started as ‘Test48_1’ but modified the framework to NET6.0.

All Test Steps are individually recognized, and work, by the D:\OpenTAP\Editor.exe, if we put it in the \Plugins folder.

Things go wrong when we start mixing, so a combination of those Test Steps.
The “Test60_1” is not found by the Editor if we put “Test48_1” and “Test60_1” in the \Plugins folder.
But “Test60_1” along with “Test48_2” (and also “Test60_2”) apparently works.

Conclusion: if we make a Test Step, as a regular ‘Class Library’, ie without using the OpenTAP template, in both .NET4 and .NET6, everything works.
Apparently there is something in the VS OpenTAP template that prevents this.
Someone ?

Thanks in advance.

1 Like

Hi @fostyn

First of all, welcome!

In general, mixing plugins for different target frameworks can cause problems.

Loading a .NET 6 plugin in a .NET Framework process will usually fail because runtime DLLs such as System.Runtime 6.0.0.0 cannot be resolved.

Loading .NET Framework plugins in a .NET 6 process (on Windows) will often work, unless the .NET Framework plugin uses types that are not defined in .NET 6. This will often fail WPF and Windows Forms types, for example, though there are others.

Whether or not a type can successfully be loaded depends entirely on the assembly references of that specific type. E.g. a .NET Framework assembly may have references to WPF, but you can still load types from that assembly in the .NET 6 runtime, as long as those types do not have any such dependencies. This is my guess as to why one of your .NET 6 test steps is found by the editor while the other is not.

Editor.exe targets .NET Framework, and uses the .NET Framework 4.8 runtime, so issues are likely to arise if you target .NET 6 in your plugin.

Our recommendation is to always target netstandard2.0 in your plugins if at all possible to ensure maximum compatibility. Such plugins will work in all runtimes on all platforms (unless you have native dependencies for some reason).

I hope this helps!

1 Like

Hi Alexander,

first of all, thanks for your reply.
Indeed, mixing different target frameworks can sometimes be a bit tricky.

My only observation was that it does not work with “TEST48_1” but with “Test48_2” in combination with “Test60_1” or “Test60_2”.

Furthermore, this is a test case, simple in design without further references to other dll’s,
but created for different .NET frameworks. The Test Step looks like:

[Display(Name: “Sum”,
Groups: new { “CalculatorNET48” },
Description: “Sum of A + B”)]
public class Sum : TestStep
{
public Sum()
{ }

    [Display(Name: "Value A")]
    public double Value_A { get; set; }

    [Display(Name: "Value B")]
    public double Value_B { get; set; }

    [Output]
    [Display(Name: "Sum")]
    public double Result { get; private set; }

    public override void Run()
    {
        Result = Value_A + Value_B;
        Log?.Debug($"Result = {Result} -> {Value_A} + {Value_B}");
        UpgradeVerdict(Verdict.Pass);
    }
}

Pretty simple, isn’t it? :grinning:

The reason we’re testing this:

  1. I understand that with OpenTAP, release 9.17.4, Microsoft .NET 6 is supported. If OpenTAP supports this, but the Editor CE does not, then we have a problem.
    Do you now advise us to only use .NET48 or NetStandard?
  2. We would like to opt for NET6 Test Steps ourselves, but we know from experience that not all external dll’s support .NET6 yet, hence the test.

Kind regards,

1 Like

Hi Fostyn,

You hit the nail on the head. Editor CE does not support .NET 6. If you need a test plan editor that does, you can try the open source terminal editor: TUI

We always recommend using NetStandard if possible, but we understand the limitations. If you don’t care about supporting Linux / MacOS, then you can go ahead and target .NET48 as this will be fully supported on Windows as long as Microsoft supports it.

Sorry for the late reply!

Hi Alexander,

maybe I wasn’t completely clear, but the Editor CE DOES support .NET6, even in combination with .NET48 !
BUT, that only works if you start from scratch in Visual Studio (new project (.NET library), via NuGet adding OpenTAP.)
That does NOT work if we use the Visual Studio OpenTAP template, for .NET48, then the existing .NET6 dll’s are no longer recognized by the Editor CE, which is strange.

So I suspect there’re settings in that OpenTAP template that somehow prevent this, I don’t know.

This is not a late reply, my previous reply was marked as ‘hidden’. But thanks anyway.

KR

Hi @fostyn ,

Are you building in “Debug” or “Release” mode? One thing you’ll notice if you check the csproj files for each of these is that in the ones based off the template (“Test48_1” and “Test60_2”), in the “Debug” configuration, they are actually targeting .NET Framework 4.7.2 (or 4.6.2 for some earlier versions), so if you’re building in “Debug” mode, then they should actually both target 4.7.2. Although you’re right about what combinations work and what don’t is strange, this is what’s different about the template.

Although I will echo @alexander.larsen that both mixing up target frameworks (.NET Framework and .NET Core) is not the best idea and will very likely lead to issues, and also it’s recommended to use .NET Standard for the plugins unless you’re trying to target native code (by using WPF, for example).

Maybe you could post the contents of the csproj files you’re using, so we can compare and get the full picture?

1 Like

Hi John,

we’re building in “Debug” and here are the the csproj files, nothing special :grinning:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <BaseOutputPath>F:\C#\OpenTAP\Plugins\CalculatorNET60</BaseOutputPath>
  </PropertyGroup>
	
  <PropertyGroup>
	<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
	<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
  </PropertyGroup>
	
	
  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
    <!-- We are setting TargetFramework in debug configuration, otherwise Visual Studio tries to attach a .NET Core debugger. That will not work, because the program we open is a .NET Framework executable -->
	<TargetFramework>net48</TargetFramework>
  </PropertyGroup>
	
  <ItemGroup>
    <PackageReference Include="OpenTAP" Version="9.17.4" />
  </ItemGroup>

</Project>

-----------------------------------------------------------------------------------------------------------

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
    <ProjectGuid>{2E6586AD-FCA0-4603-9A95-A9AC76EA7558}</ProjectGuid>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
    <RootNamespace>CalculatorNET48_2</RootNamespace>
    <AssemblyName>CalculatorNET48_2</AssemblyName>
    <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
    <FileAlignment>512</FileAlignment>
    <Deterministic>true</Deterministic>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DebugSymbols>true</DebugSymbols>
    <DebugType>full</DebugType>
    <Optimize>false</Optimize>
    <OutputPath>..\..\Plugins\Calculator\</OutputPath>
    <DefineConstants>DEBUG;TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    <DebugType>pdbonly</DebugType>
    <Optimize>true</Optimize>
    <OutputPath>bin\Release\</OutputPath>
    <DefineConstants>TRACE</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <WarningLevel>4</WarningLevel>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="OpenTap">
      <HintPath>.\OpenTap.dll</HintPath>
      <Private>False</Private>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.Core" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="Microsoft.CSharp" />
    <Reference Include="System.Data" />
    <Reference Include="System.Net.Http" />
    <Reference Include="System.Xml" />
  </ItemGroup>
  <ItemGroup>
    <Compile Include="SumInput.cs" />
    <Compile Include="Sum.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

Oeps, not readable in this forum ?

If you use the code block, it will display nicely:
image

1 Like

If you are building in debug mode it looks like you are actually targeting net48 in debug builds (lines 14 to 18)

Does your plugin still work in Editor CE if you remove that?

Indeed, the TargetFramework is net48, the reason is stated above in comment.

And so when we remove this, we can’t debug in Visual Studio.
But the plugin still works with the Editor CE.
If we then attach Visual Studio to the Editor CE, we can debug again.