Можно ли использовать xUnit с LINQPad?
Можно ли использовать xUnit с LINQPad?
Было бы здорово написать несколько тестов для концепций, которые сначала разрабатываются в LINQPad. Это проще, чем добавить еще одно ConsoleApp23423894238, просто чтобы можно было быстро написать несколько модульных тестов.
2 ответа
Возможный? Вроде, как бы, что-то вроде.
Это не основной вариант использования LINQPad и не модульное тестирование.
Что касается LINQPad, вы можете использовать существующий тестовый прогон, но, вероятно, единственные, которые могут быть интегрированы с LINQPad, - это консольные. Тестовый бегун - это не тривиальная программа. Попробуйте Xunit.Runner.LinqPad.
Что касается необходимости "писать некоторые тесты для разрабатываемых концепций", учтите, что вы можете не получить достаточно от своего рабочего процесса модульного тестирования, если не найдете их достаточно ценными для создания проекта и сохранения его в системе контроля версий. Один из способов получить большую отдачу - использовать Behavior-Driven Development (BDD), и если вы хотите написать требования на понятном для бизнеса языке, попробуйте что-то вроде SpecFlow.
Два ответа указали мне правильное направление, но описания были недостаточно полными, поэтому мне пришлось немного поэкспериментировать. Чтобы сэкономить вам время, я описываю то, что я сделал; Теперь у меня есть рабочие решения для LinqPad 5 и LinqPad 6.
LinqPad 5 - для.NET
Судя по тому, что написал Том, мне удалось заставить его работать с LinqPad 5 (v5.42.01).
Требуются еще несколько шагов, которые не очевидны и не объяснены в принятом ответе, поэтому я опишу, что помогло с моей стороны.
Прежде всего, вам нужно будет использовать платную версию LinqPad, потому что только тогда вы сможете загружать пакеты NUGET.
Чтобы загрузить необходимые пакеты в LinqPad, нажмите F4. Откроется диалоговое окно свойств запроса. В этом диалоговом окне щелкните Add NUGET....
Откроется диалоговое окно NUGET. В середине диалогового окна NUGET есть текстовое поле поиска. ИскатьxUnit.Net
- как только он отобразится, щелкните Add to query, подождите, пока он загрузится, затем щелкните Добавить пространства имен. Затем сделайте то же самое дляXunit.Runner.LinqPad.
Затем закройте диалоговое окно NUGET, но не закрывайте свойства запроса. Вам необходимо перейти на вкладку " Дополнительно ": Включить (поставить галочку) "Копировать все ссылки, не относящиеся к платформе, в одну локальную папку". Теперь вы можете закрыть диалоговое окно свойств запроса.
Импортируйте следующий пример в редактор запросов (C# Program
Режим):
void Main()
{
// Press F4, go to Advanced, then
// tick-mark "Copy all non-framework references to a single local folder"
var me = Assembly.GetExecutingAssembly();
var result = Xunit.Runner.LinqPad.XunitRunner.Run(me);
result.Dump("Xunit runner result");
}
/// <summary>
/// This test class is there for demo purpose, so developers can
/// see how to write test methods.
/// It also verifies that XUnit itself is functioning correctly.
/// </summary>
public class A_XUnitSelfTest
{
[InlineData(2)]
[InlineData(3)]
[Theory]
public void Test_Theory(int a)
{
Assert.True(a == 2 || a == 3); // succeeds
}
[Fact]
public void Test_Fact()
{
Assert.False(1 == 0); // succeeds
}
}
Запустите его, и вы увидите результат работы средства запуска тестов.
Выполняется 3 из 3 тестов...
Завершено: 3 теста за 0,003 с (0 неудачных, 0 пропущенных)
Измените тест, чтобы увидеть, как он будет выглядеть в случае сбоя теста, изменив утверждение в Test_Fact()
к Assert.False(1 == 1);
, затем снова запустите. Он должен показать это время:
Выполняется 3 из 3 тестов...
[FAIL] UserQuery+A_XUnitSelfTest.Test_Fact: Assert.False()
Ожидаемая ошибка: False
Фактическое: True
в Xunit.Assert.False(условие Nullable`1, String userMessage)
в Xunit.Assert.False(Логическое условие)
в UserQuery.A_XUnitSelfTest.Test_Fact() в C:\Users...\AppData\Local\Temp\LINQPad5_oyxxqxbu\query_mxsmky.cs: строка 62
Завершено: 3 теста за 0,005 с (1 неудачно, 0 пропущено)
LinqPad 6 - для.NET Core
LinqPad 6 отличается, потому что он основан на.NET Core и, следовательно, требует других библиотек.
Начнем с этого:
void Main()
{
// Press F4, go to Advanced, then
// tick-mark "Copy all non-framework references to a single local folder"
var me = Assembly.GetExecutingAssembly();
var result = Xunit.Runner.LinqPad.XunitRunner.Run(me);
result.Dump("Xunit runner result");
}
/// <summary>
/// This test class is there for demo purpose, so developers can
/// see how to write test methods.
/// It also verifies that XUnit itself is functioning correctly.
/// </summary>
public class A_XUnitSelfTest
{
[InlineData(2)]
[InlineData(3)]
[Theory]
public void Test_Theory(int a)
{
Assert.True(a == 2 || a == 3); // succeeds
}
[Fact]
public void Test_Fact()
{
Assert.False(1 == 0); // succeeds
}
}
Затем добавьте xUnit.net
, xUnit.net [Core Unit Testing Framework]
а также xUnit.net [Runner Utility]
и все их пространства имен через F4 диалоговое окно (подробности см. в разделе LinqPad 5) и, наконец, скопируйте исходный код XUnit runner, как указано @ramiroalvarez, в конец примера теста xUnit выше:
Включите "копировать все сборки nuget в одну локальную папку" в диалоговом окне F4 на вкладке "Дополнительно"... этого должно быть достаточно, но это не так, читайте дальше:
Если вы попробуете это сделать, это вызовет исключение InvalidOperationException("Пожалуйста, включите опцию теневой папки для ссылок вне инфраструктуры (F4 -> Advanced).") В исходном коде.
Теперь я заглянул в бегун XUnit и обнаружил, что если вы закомментируете 2 строки кода, он будет работать нормально:
Исходный код (находится в методеGetTargetAssemblyFilename
):
if (shadowFolder != xunitFolder
|| Directory.GetFiles(shadowFolder, "xunit.execution.*.dll").Length == 0)
{
throw new InvalidOperationException("Please enable the shadow folder option ...");
}
// ...
var targetAssembly = Path.Combine(shadowFolder, Path.GetFileName(assemblyFilename));
//Console.WriteLine($"Copy \"{ assemblyFilename }\" -> \"{ targetAssembly }\"");
File.Copy(assemblyFilename, targetAssembly, true);
Прокомментируйте строки
// ...
// throw new InvalidOperationException("Please enable the shadow folder option ...");
// ...
// File.Copy(assemblyFilename, targetAssembly, true);
и вы сделали! (Протестировано с версией LinqPad 6 v6.8.3, версия X64)
Подсказки:
Подсказка 1.
Вы можете добавить бегун xUnit в свой код, как описано, но в LinqPad 6 есть более элегантный способ: сохранить копию, содержащую только исходный код xUnit.Runner, по тому же пути, что и ваши файлы модульного теста, с именем файла.xUnit.Runner.LinqPad6.linq
. Затем добавьте в верхнюю часть тестового кода следующее:
Теперь вы очистили свой код! Каждый раз, когда вы создаете новый тест, просто не забывайте добавлять
#load
команда.
Подсказка 2:
Добавьте следующие 2 атрибута в код средства запуска тестов:
/// <summary>
/// Skip a Fact (you can override it by setting OverrideSkip=true)
/// </summary>
public class SkipFactAttribute : FactAttribute
{
/// <summary>
/// Override SkipFact: Set OverrideSkip=true to run even skipped tests
/// </summary>
public static bool OverrideSkip = false; // set to true to ignore skip
/// <summary>
/// Constructor. Used to set skip condition.
/// </summary>
public SkipFactAttribute()
{
if (!OverrideSkip) Skip = "Skipped Fact";
}
}
/// <summary>
/// Skip a Theory (you can override it by setting OverrideSkip=true)
/// </summary>
public class SkipTheoryAttribute : TheoryAttribute
{
/// <summary>
/// Override SkipTheory: Set OverrideSkip=true to run even skipped tests
/// </summary>
public static bool OverrideSkip = false; // set to true to ignore skip
/// <summary>
/// Constructor. Used to set skip condition.
/// </summary>
public SkipTheoryAttribute()
{
if (!OverrideSkip) Skip = "Skipped Theory";
}
}
Это полезно, если вы хотите пропустить тесты. Чтобы пропустить тест, просто замените[Fact]
по [SkipFact]
или [Theory]
по [SkipTheory]
.
Если вы заняты написанием теста и хотите протестировать только этот единственный тест, установите для всех атрибутов значение [SkipFact]
или аналогично [SkipTheory]
, кроме единственной, которую вы пишете сейчас.
Затем, чтобы время от времени быстро запускать все тесты снова - без изменения каждого отдельного атрибута - добавьте следующее в часть инициализации вашего набора тестов (см. Глобальную настройку для запуска и разрыва):
public class TestsFixture : IDisposable
{
public TestsFixture() // running once before the tests
{
// true: Ignore Skip and run all tests, false: Skip is effective
SkipFactAttribute.OverrideSkip = true;
SkipTheoryAttribute.OverrideSkip = true;
}
public void Dispose() // running once, after the tests
{
// teardown code
}
}
Если вы закончили, восстановите [Fact]
/ [Theory]
атрибуты и установите .OverrideSkip
переменные обратно к false
.
Подробнее о модульном тестировании
Для некоторых дополнительных тем о модульном тестировании с xUnit я рекомендую прочитать:
- xunit тесты в чистом ядре
- глобальная настройка для запуска и разборки
- общий контекст
- параллельное выполнение тестов
- настройка с помощью json
- настройка с помощью xml
- пропуск Test and Theory // описание работает и для TheoryAttribute
Если вы хотите использовать его с Visual Studio, вы можете найти здесь информацию.
Благодаря asherber, xunit теперь работает с linqpad6 (netcore).
https://github.com/asherber/Xunit.Runner.LinqPad/blob/master/Xunit.Runner.LinqPad/XunitRunner.cs
Это важно в свойствах запроса, установите флажок "копировать все сборки nuget в одну локальную папку", иначе вы получите следующую ошибку "InvalidOperationException: включите параметр теневой папки для ссылок вне инфраструктуры"
Я просто попытался открыть файл запроса LINQPad, который пытался загрузить xunit
пакет и получил ошибку, которая никогда не случалась со мной при использовании LINQPad в течение многих лет. Так что мой ответ - нет.