Я работаю над расширением атрибута TestMethod
в .NET Core. Я использую библиотеку Polly для логики повторных попыток вместе с внешней политикой тайм-аута.
Мне нужен вспомогательный метод, который может повторять вызов ITestMethod
, пока он не пройдет. Я не возражаю против количества повторных попыток. Но я поставлю тайм-аут, в течение которого он должен быть завершен. Если делегат успешно выполнен в течение тайм-аута, все в порядке. Но если есть исключение тайм-аута, мне все равно нужно значение неудачного результата (результат последней итерации) вместо TimeOutRejectedException
или значения по умолчанию для возвращаемого типа.
Ниже приведен мой расширенный класс атрибутов метода тестирования:
public sealed class GuaranteedPassTestMethodAttribute : TestMethodAttribute
{
/// <inheritdoc/>
public override TestResult[] Execute(ITestMethod testMethod)
{
return ExecuteTestTillSuccess(testMethod);
}
private TestResult[] ExecuteTestTillSuccess(ITestMethod testMethod)
{
var gracefulTestRun =
TestExecutionHelper.ExecuteTestTillPassAsync(
() => TestInvokeDelegate(testMethod));
return gracefulTestRun.Result;
}
private Task<TestResult[]> TestInvokeDelegate(ITestMethod testMethod)
{
TestResult[] result = null;
var thread = new Thread(() => result = Invoke(testMethod));
thread.Start();
thread.Join();
return Task.FromResult(result);
}
}
Ниже мой TestExecutionHelper
, который использует Polly:
internal static class TestExecutionHelper
{
private static readonly Func<TestResult[], bool> TestFailurePredicate =
results => results != null &&
results.Length == 1 &&
results.First().Outcome != UnitTestOutcome.Passed;
internal static async Task<TestResult[]> ExecuteTestTillPassAsync(
Func<Task<TestResult[]>> testInvokeDelegate,
int delayBetweenExecutionInMs = 3000,
int timeoutInSeconds = 60 * 10)
{
var timeoutPolicy = Policy.TimeoutAsync<TestResult[]>(timeoutInSeconds);
var retryPolicy = Policy.HandleResult<TestResult[]>(TestFailurePredicate)
.WaitAndRetryAsync(int.MaxValue, x => TimeSpan.FromMilliseconds(delayBetweenExecutionInMs));
var testRunPolicy = timeoutPolicy.WrapAsync(retryPolicy);
return await testRunPolicy.ExecuteAsync(testInvokeDelegate);
}
}
При такой настройке я получаю либо пройденное выполнение метода тестирования, либо TimeOutRejectedException
для неудачных тестов. Я хочу записывать TestResult
неудачных тестов даже после повторных попыток.
Invoke(testMethod)
? Насколько я понимаю,testMethod.Invoke
существует, но возвращает единственныйTestResult
. - person Peter Csala   schedule 26.01.2021