Как правильно протестировать .NET Standard AND Core версии библиотеки? - PullRequest
3 голосов
/ 30 сентября 2019

Справочная информация:

У меня есть библиотека, предназначенная как для .NET Standard 2.0, так и .NET Core (среди прочих). Поскольку в .NET Standard 2.0 отсутствуют многие функции, присутствующие в .NET Core / Framework, я выбрасываю PlatformNotSupportedException от многих членов в .NET Standard 2.0 версии.

Выпуск 1:

Проект UnitTest не может быть нацелен на .NET Standard, поэтому в тестовом проекте я использую .NET Core 2.0 для версий .NET Core и Standard.

В библиотеке .csproj мне нужно изменить целивручную:

library.csproj:
<PropertyGroup>
  <!-- Compiles everything; for testing everything but .NET Standard 2.0 -->
  <TargetFrameworks>net35;net40;net45;netcoreapp2.0;netstandard2.0;netstandard2.1</TargetFrameworks>
  <!-- For testing .NET Standard 2.0: -->
  <!--<TargetFrameworks>netstandard2.0</TargetFrameworks>-->
</PropertyGroup>

test.csproj:
<PropertyGroup>
  <!-- now 'netcoreapp2.0' references either the .NET Core 2.0 or Standard 2.0 version depending on library.csproj -->
  <TargetFrameworks>net35;net40;net45;netcoreapp2.0;netcoreapp3.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
  <ProjectReference Include="..\library\library.csproj" />
</ItemGroup>

Проблема 2:

Учитывая, что проект модульного тестирования не может быть нацелен на .NET Standard, этот код не работает:

[Test]
public void TestSomethingThatIsNotAvailableInNetStandard20()
{
    TestDelegate testCode = () => ...;

#if NETSTANDARD2_0 // This is never true
    Assert.Throws<PlatformNotSupportedException>(testCode);
#else
    Assert.DoesNotThrow(testCode);
#endif
}

Вместо этого теперь я использую что-то вроде этого:

[Test]
public void TestSomethingThatIsNotAvailableInNetStandard20()
{
    TestDelegate testCode = () => ...;

#if NETCOREAPP2_0 // .NET Core 2.0 OR .NET Standard 2.0
    if (IsNetStandard20)
        Assert.Throws<PlatformNotSupportedException>(testCode);
    else
        Assert.DoesNotThrow(testCode);
#else // all other targets
    Assert.DoesNotThrow(testCode);
#endif
}

...

// yikes... :/
public static bool IsNetStandard20 => typeof(SomeTypeFromMyLib).Assembly.GetReferencedAssemblies()
    .Any(an => an.Name == "netstandard" && an.Version == new Version(2, 0, 0, 0));

Вопрос:

Есть ли способ протестировать версию .NET Standard 2.0 без измененияФайл .csproj все время (и, если возможно, избавиться от свойства IsNetStandard20)?

Отказ от ответственности:

Я знаю, что обычно этого будет достаточно дляпоставляется версия .NET Standard 2.0 для поддержки приложений .NET Core, но, к сожалению, в ней много ошибокиспользовать функции, которые есть в .NET Core 2.0 (хотя они включены в .NET Standard 2.1, поэтому отдельная версия .NET Core 3.0 не требуется).

1 Ответ

1 голос
/ 02 октября 2019

Проект UnitTest не может быть нацелен на .NET Standard, поэтому в тестовом проекте я использую .NET Core 2.0 как для .NET Core, так и для стандартных версий.

Это утверждение не полностью правильно. Проекты модульных тестов могут быть нацелены на .NETStandard, но большинство тестовых платформ не могут найти или выполнить эти тесты.

Ориентация кода .NETCore может быть явно протестирована в процессе .NETCore. С другой стороны, нацеленность кода на .NETStandard может быть неявно протестирована в процессах, использующих среды выполнения, в которых реализована указанная версия .NETStandard. Если вы хотите протестировать последнее, вам нужно запустить свои тесты на всех соответствующих средах выполнения , которые вы ожидаете увидеть с потребителями вашей библиотеки.

Если вы хотите пройти модульный тестпроект для цели. NETStandard, то вы должны посмотреть на Nuclear.Test . Это позволяет вам создавать свои модульные тесты с использованием .NETStandard и выполнять их в версиях .NETCore и .NETFramework, которые реализуют выбранную вами версию .NETStandard.

Вы можете настроить целевой модульный тестПроект на .NETStandard 2.0 и .NETCoreApp 2.0, как вы уже делаете. Ваши тесты будут очень похожи на ваш первый пример.

[TestMethod]
void TestSomethingThatIsNotAvailableInNetStandard20()
{
    TestDelegate testCode = () => ...;

#if NETSTANDARD2_0 // This is compiled into net standard test assembly
    Test.If.ThrowsException(testCode, out PlatformNotSupportedException ex);
    // Assert.Throws<PlatformNotSupportedException>(testCode);
#else // This is compiled into every other test assembly
    Test.IfNot.ThrowsException(testCode, out PlatformNotSupportedException ex);
    // Assert.DoesNotThrow(testCode);
#endif
}

Этот подход решит вашу проблему, как описано. Однако это может привести к новым проблемам из-за смены платформы модульного тестирования.

...