Note
ãã®ããŒãžã«ã¢ã¯ã»ã¹ããã«ã¯ãæ¿èªãå¿ èŠã§ãã ãµã€ã³ã€ã³ãŸãã¯ãã£ã¬ã¯ããªã®å€æŽã詊ãããšãã§ããŸãã
ãã®ããŒãžã«ã¢ã¯ã»ã¹ããã«ã¯ãæ¿èªãå¿ èŠã§ãã ãã£ã¬ã¯ããªã®å€æŽã詊ãããšãã§ããŸãã
ãã®èšäºã§ã¯ãMicrosoftçšã®ã«ã¹ã¿ã ãã¹ã ãã¬ãŒã ã¯ãŒã¯ãäœæããæ¹æ³ã«ã€ããŠèª¬æããŸããTesting.Platform (MTP)ã ãã¹ã ãã¬ãŒã ã¯ãŒã¯ã¯ãå¯äžã®å¿ é æ¡åŒµæ©èœã§ãã ãã¹ããæ€åºããŠå®è¡ããçµæããã©ãããã©ãŒã ã«å ±åããŸãã
å®å šãªæ¡åŒµãã€ã³ãã®æŠèŠãšããã»ã¹å /ããã»ã¹å€ã®æŠå¿µã«ã€ããŠã¯ãã ã«ã¹ã¿ã æ¡åŒµæ©èœã®äœæããåç §ããŠãã ããã
æ¢åã® VSTest ããŒã¹ã®ãã¹ã ãã¬ãŒã ã¯ãŒã¯ãç§»è¡ããå Žåã¯ã ITestFramework ã€ã³ã¿ãŒãã§ã€ã¹ããã€ãã£ãã«å®è£
ããããšããå§ãããŸãã
VSTest Bridge æ¡åŒµæ©èœã¯ç§»è¡æé ãšããŠäœ¿çšã§ããŸããããã€ãã£ãå®è£
ã§ã¯æé©ãªãšã¯ã¹ããªãšã³ã¹ãæäŸãããŸãã
ãã¹ããã¬ãŒã ã¯ãŒã¯ã®æ¡åŒµ
ãã¹ã ãã¬ãŒã ã¯ãŒã¯ã¯ããã¹ã ãã©ãããã©ãŒã ã«ãã¹ããæ€åºããŠå®è¡ããæ©èœãæäŸããäž»èŠãªæ¡åŒµæ©èœã§ãã ãã¹ã ãã¬ãŒã ã¯ãŒã¯ã¯ããã¹ãã®çµæããã¹ã ãã©ãããã©ãŒã ã«æ»ã圹å²ãæ ããŸãã ãã¹ã ãã¬ãŒã ã¯ãŒã¯ã¯ããã¹ã ã»ãã·ã§ã³ãå®è¡ããããã«å¿ èŠãªå¯äžã®å¿ é ã®æ¡åŒµæ©èœã§ãã
ãã¹ã ãã¬ãŒã ã¯ãŒã¯ãç»é²ãã
ãã®ã»ã¯ã·ã§ã³ã§ã¯ããã¹ã ãã¬ãŒã ã¯ãŒã¯ããã¹ã ãã©ãããã©ãŒã ã«ç»é²ããæ¹æ³ã«ã€ããŠèª¬æããŸãã
TestApplication.RegisterTestFrameworkã®ããã¥ã¡ã³ãã«ç€ºãããã«ã API ã䜿çšããŠããã¹ã ã¢ããªã±ãŒã·ã§ã³ ãã«ããŒããšã« 1 ã€ã®ãã¹ã ãã¬ãŒã ã¯ãŒã¯ã®ã¿ãç»é²ããŸãã
ç»é² API ã¯æ¬¡ã®ããã«å®çŸ©ãããŸãã
ITestApplicationBuilder RegisterTestFramework(
Func<IServiceProvider, ITestFrameworkCapabilities> capabilitiesFactory,
Func<ITestFrameworkCapabilities, IServiceProvider, ITestFramework> adapterFactory);
RegisterTestFramework API ã«ã¯ã次㮠2 ã€ã®ãã¡ã¯ããªãå¿
èŠã§ãã
Func<IServiceProvider, ITestFrameworkCapabilities>: ããã¯ãIServiceProviderã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ãããªããžã§ã¯ããåãå ¥ããITestFrameworkCapabilitiesã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ãããªããžã§ã¯ããè¿ãããªã²ãŒãã§ããIServiceProviderã¯ãæ§æããã¬ãŒãã³ãã³ã ã©ã€ã³åŒæ°ãšãã£ããã©ãããã©ãŒã ãµãŒãã¹ãžã®ã¢ã¯ã»ã¹ãæäŸããŸããITestFrameworkCapabilitiesã€ã³ã¿ãŒãã§ã€ã¹ã¯ããã¹ã ãã¬ãŒã ã¯ãŒã¯ã§ãµããŒããããæ©èœããã©ãããã©ãŒã ãšæ¡åŒµæ©èœã«éç¥ããããã«äœ¿çšãããŸãã ããã«ãããç¹å®ã®åäœãå®è£ ããã³ãµããŒãããããšã§ããã©ãããã©ãŒã ãšæ¡åŒµæ©èœã¯é©åã«å¯Ÿè©±ã§ããããã«ãªããŸãã æ©èœã®æŠå¿µã«ã€ããŠçè§£ãæ·±ããã«ã¯ãããããã®ã»ã¯ã·ã§ã³ãåç §ããŠãã ãããFunc<ITestFrameworkCapabilities, IServiceProvider, ITestFramework>: ããã¯ãITestFrameworkCapabilities ãªããžã§ã¯ããåãåãããªã²ãŒãã§ããããã®ãªããžã§ã¯ãã¯Func<IServiceProvider, ITestFrameworkCapabilities>ã«ãã£ãŠè¿ãããã€ã³ã¹ã¿ã³ã¹ã§ãããŸããIServiceProvider ã䜿çšããŠãã©ãããã©ãŒã ãµãŒãã¹ãžã®ã¢ã¯ã»ã¹ãåæäŸããŸãã äºæãããæ»ããªããžã§ã¯ãã¯ãITestFramework ã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ãããªããžã§ã¯ãã§ããITestFrameworkã¯ããã¹ããæ€åºããŠå®è¡ããŠããçµæããã¹ã ãã©ãããã©ãŒã ã«äŒããå®è¡ãšã³ãžã³ãšããŠæ©èœããŸãã
ãã©ãããã©ãŒã ã ITestFrameworkCapabilities ã®äœæãš ITestFramework ã®äœæãåé¢ããå¿
èŠãããã®ã¯ããµããŒããããŠããæ©èœãçŸåšã®ãã¹ã ã»ãã·ã§ã³ãå®è¡ããã®ã«ååã§ãªãå Žåã«ããã¹ã ãã¬ãŒã ã¯ãŒã¯ã®äœæãåé¿ããããæé©åããããã§ãã
次ã®ãŠãŒã¶ãŒ ã³ãŒãã®äŸãèããŠã¿ãŸãããããã®äŸã¯ãç©ºã®æ©èœã»ãããè¿ããã¹ã ãã¬ãŒã ã¯ãŒã¯ã®ç»é²ã瀺ããŠããŸãã
internal class TestingFrameworkCapabilities : ITestFrameworkCapabilities
{
public IReadOnlyCollection<ITestFrameworkCapability> Capabilities => [];
}
internal class TestingFramework : ITestFramework
{
public TestingFramework(ITestFrameworkCapabilities capabilities, IServiceProvider serviceProvider)
{
// ...
}
// Omitted for brevity...
}
public static class TestingFrameworkExtensions
{
public static void AddTestingFramework(this ITestApplicationBuilder builder)
{
builder.RegisterTestFramework(
_ => new TestingFrameworkCapabilities(),
(capabilities, serviceProvider) => new TestingFramework(capabilities, serviceProvider));
}
}
// ...
次ã«ãç»é²ã³ãŒãã䜿çšããŠããã®äŸã®å¯Ÿå¿ãããšã³ã㪠ãã€ã³ãã«ã€ããŠèããŠã¿ãŸãããã
var testApplicationBuilder = await TestApplication.CreateBuilderAsync(args);
// Register the testing framework
testApplicationBuilder.AddTestingFramework();
using var testApplication = await testApplicationBuilder.BuildAsync();
return await testApplication.RunAsync();
泚
空㮠ITestFrameworkCapabilities ãè¿ããŠãããã¹ã ã»ãã·ã§ã³ã®å®è¡ã劚ããããããšã¯ãããŸããã ãã¹ãŠã®ãã¹ã ãã¬ãŒã ã¯ãŒã¯ã¯ããã¹ããæ€åºããŠå®è¡ã§ããå¿ èŠããããŸãã ãã®åœ±é¿ã¯ããã¹ã ãã¬ãŒã ã¯ãŒã¯ã«ç¹å®ã®æ©èœããªãå Žåã«ãªããã¢ãŠãããå¯èœæ§ãããæ¡åŒµæ©èœã«éå®ããå¿ èŠããããŸãã
ãã¬ãŒã ã¯ãŒã¯åºæã®ã¡ã¿ããŒã¿ãå¿
èŠãªã¬ããŒãã«ã€ããŠã¯ãITrxReportCapability ãç»é²ãããã¹ãçµæã«å¯Ÿå¿ãã TRX ããããã£ã远å ããŠãã ããã
ãã¹ã ãã¬ãŒã ã¯ãŒã¯ãäœæãã
Microsoft.Testing.Platform.Extensions.TestFramework.ITestFramework ã¯ããã¹ã ãã¬ãŒã ã¯ãŒã¯ãæäŸããæ¡åŒµæ©èœã«ãã£ãŠå®è£
ãããŸãã
public interface ITestFramework : IExtension
{
Task<CreateTestSessionResult> CreateTestSessionAsync(CreateTestSessionContext context);
Task ExecuteRequestAsync(ExecuteRequestContext context);
Task<CloseTestSessionResult> CloseTestSessionAsync(CloseTestSessionContext context);
}
IExtension ã€ã³ã¿ãŒãã§ã€ã¹
ITestFramework ã€ã³ã¿ãŒãã§ã€ã¹ã¯ãIExtension ã€ã³ã¿ãŒãã§ã€ã¹ãç¶æ¿ããŸããããã¯ããã¹ãŠã®æ¡åŒµãã€ã³ããç¶æ¿ããã€ã³ã¿ãŒãã§ã€ã¹ã§ãã
IExtension ã¯ãæ¡åŒµæ©èœã®ååãšèª¬æãååŸããããã«äœ¿çšãããŸãã ãŸã IExtension ã¯ãTask<bool> IsEnabledAsync() ãéããŠãã»ããã¢ããã§æ¡åŒµæ©èœãåçã«æå¹ãŸãã¯ç¡å¹ã«ããæ¹æ³ãæäŸããŸãã ç¡å¹ã«ããç¹å®ã®èŠä»¶ããªãå Žåã¯ããã®ã¡ãœãããã true ãè¿ãããã«ããŠãã ããã
CreateTestSessionAsync ã¡ãœãã
CreateTestSessionAsync ã¡ãœããã¯ãã¹ã ã»ãã·ã§ã³ã®éå§æã«åŒã³åºããããã¹ã ãã¬ãŒã ã¯ãŒã¯ã®åæåã«äœ¿çšãããŸãã API 㯠CreateTestSessionContext ãªããžã§ã¯ããåãå
¥ããCreateTestSessionResult ãè¿ããŸãã
public sealed class CreateTestSessionContext : TestSessionContext
{
public CancellationToken CancellationToken { get; }
}
SessionUid ããããã£ã¯ãTestSessionContextããç¶æ¿ãããŸã (ãTestSessionContextãã»ã¯ã·ã§ã³ãåç
§)ã
CancellationToken ã䜿çšããŠãCreateTestSessionAsync ã®å®è¡ã忢ããŸãã
æ»ããªããžã§ã¯ãã¯ã次ã®ããã« CreateTestSessionResult ã«ãªããŸãã
public sealed class CreateTestSessionResult
{
public string? WarningMessage { get; set; }
public string? ErrorMessage { get; set; }
public bool IsSuccess { get; set; }
}
IsSuccess ããããã£ã¯ãã»ãã·ã§ã³ã®äœæãæåãããã©ããã瀺ãããã«äœ¿çšãããŸãã
false ãè¿ããããšããã¹ãã®å®è¡ã¯åæ¢ããŸãã
CloseTestSessionAsync ã¡ãœãã
CloseTestSessionAsync ã¡ãœããã¯æ©èœçã«ã¯ CreateTestSessionAsync ãšäžŠåã§ããªããžã§ã¯ãåã ããç°ãªããŸãã 詳现ã«ã€ããŠã¯ããCreateTestSessionAsyncãã®ã»ã¯ã·ã§ã³ãåç
§ããŠãã ããã
ExecuteRequestAsync ã¡ãœãã
ExecuteRequestAsync ã¡ãœããã¯ãå ExecuteRequestContext ã®ãªããžã§ã¯ããåãå
¥ããŸãã ãã®ãªããžã§ã¯ãã«ã¯ãååããããããããã«ããã¹ã ãã¬ãŒã ã¯ãŒã¯ã§ã®å®è¡ãæ³å®ãããŠããã¢ã¯ã·ã§ã³ã®è©³çŽ°ãæ ŒçŽãããŠããŸãã
ExecuteRequestContext ã®å®çŸ©ã¯æ¬¡ã®ãšããã§ãã
public sealed class ExecuteRequestContext
{
public IRequest Request { get; }
public IMessageBus MessageBus { get; }
public CancellationToken CancellationToken { get; }
public void Complete();
}
IRequest: ããã¯ãä»»æã®çš®é¡ã®èŠæ±ã«å¯Ÿå¿ããåºæ¬ã€ã³ã¿ãŒãã§ã€ã¹ã§ãã ãã¹ã ãã¬ãŒã ã¯ãŒã¯ã¯ã次ã®ãããªã©ã€ããµã€ã¯ã«ã®ã€ã³ããã»ã¹ ã¹ããŒããã« ãµãŒããŒãšèããå¿
èŠããããŸãã
äžã®å³ã¯ããã¹ã ãã¬ãŒã ã¯ãŒã¯ ã€ã³ã¹ã¿ã³ã¹ã®äœæåŸã«ãã¹ã ãã©ãããã©ãŒã ã 3 ã€ã®èŠæ±ãçºè¡ããããšã瀺ããŠããŸãã ãã¹ã ãã¬ãŒã ã¯ãŒã¯ã¯ãããã®èŠæ±ãåŠçããèŠæ±èªäœã«å«ãŸããŠãã IMessageBus ãµãŒãã¹ãå©çšããŠãç¹å®ã®èŠæ±ããšã®çµæãæäŸããŸãã ç¹å®ã®èŠæ±ãåŠçããããšããã¹ã ãã¬ãŒã ã¯ãŒã¯ã¯ãã®èŠæ±ã«å¯Ÿã㊠Complete() ã¡ãœãããåŒã³åºããèŠæ±ãå®è¡ãããããšããã¹ã ãã©ãããã©ãŒã ã«éç¥ãããŸãã
ãã¹ã ãã©ãããã©ãŒã ã¯ããã£ã¹ãããããããã¹ãŠã®èŠæ±ãç£èŠããŸãã ãã¹ãŠã®èŠæ±ãå®è¡ããããšãã€ã³ã¹ã¿ã³ã¹ã® CloseTestSessionAsync ãåŒã³åºããŠç Žæ£ããŸã (IDisposable/IAsyncDisposable ãå®è£
ãããŠããå Žå)ã
èŠæ±ãšãã®å®äºãéè€ããŠãèŠæ±ã®åæå®è¡ãšéåæå®è¡ãæå¹ã«ãªãå¯èœæ§ãããããšã¯æããã§ãã
泚
çŸåšããã¹ã ãã©ãããã©ãŒã ã§ã¯éè€ããèŠæ±ã¯éä¿¡ããããæ¬¡ã®èŠæ±ãéä¿¡ããåã«èŠæ± >> ã®å®äºãåŸ ã¡ãŸãã ãã ãããã®åäœã¯ãä»åŸå€æŽãããå¯èœæ§ããããŸãã åæèŠæ±ã®ãµããŒãã¯ãæ©èœã·ã¹ãã ãéããŠæ±ºå®ãããŸãã
IRequest ã®å®è£
ã«ãããå®è¡ããå¿
èŠã®ããæ£ç¢ºãªèŠæ±ãæå®ãããŸãã ãã¹ã ãã¬ãŒã ã¯ãŒã¯ã¯èŠæ±ã®çš®é¡ãèå¥ããããã«å¿ããŠåŠçããŸãã èŠæ±ã®çš®é¡ãèªèãããªãå Žåã¯ãäŸå€ãçºçããŸãã
䜿çšå¯èœãªèŠæ±ã®è©³çްã«ã€ããŠã¯ãIRequest ã»ã¯ã·ã§ã³ãåç §ããŠãã ããã
IMessageBus: ãã®ãµãŒãã¹ã¯ãèŠæ±ã«ãªã³ã¯ãããŠããããããã¹ã ãã¬ãŒã ã¯ãŒã¯ã¯ãé²è¡äžã®èŠæ±ã«é¢ããæ
å ±ãéåæã§ãã¹ã ãã©ãããã©ãŒã ã«çºè¡ã§ããŸãã
ã¡ãã»ãŒãž ãã¹ã¯ãã©ãããã©ãŒã ã®äžå€®ãããšããŠæ©èœãããã¹ãŠã®ãã©ãããã©ãŒã ã³ã³ããŒãã³ããšæ¡åŒµæ©èœéã®éåæéä¿¡ãæ¯æŽããŸãã
ãã¹ã ãã©ãããã©ãŒã ã«å
¬éãããå¯èœæ§ã®ããæ
å ±ã®å
æ¬çãªäžèЧã«ã€ããŠã¯ãIMessageBus ã»ã¯ã·ã§ã³ãåç
§ããŠãã ããã
CancellationToken: ãã®ããŒã¯ã³ã¯ãç¹å®ã®èŠæ±ã®åŠçãäžæããããã«äœ¿çšãããŸãã
çµæã®å
¬éãã¯ãªãŒã³ã¢ããããã£ã³ã»ã«ããã«æ°ãããã¹ãã®ã¹ã±ãžã¥ãŒã«ã忢ããã«ã¯ãIGracefulStopTestExecutionCapabilityãå®è£
ããŠãã ããã ãã®ç¬ç«ããæ©èœã«ããã--maximum-failed-tests ãªã©ã®æ©èœããµããŒããããŠããŸãã
Complete(): åã®ã·ãŒã±ã³ã¹ã§ç€ºããããã«ãComplete ã¡ãœããã¯ãèŠæ±ãæ£åžžã«åŠçãããé¢é£ãããã¹ãŠã®æ
å ±ã IMessageBus ã«éä¿¡ãããããšããã©ãããã©ãŒã ã«éç¥ããŸãã
Warnung
èŠæ±ã§ Complete() ã®åŒã³åºããç¡èŠãããšããã¹ã ã¢ããªã±ãŒã·ã§ã³ãå¿çããªããªããŸãã
ãã¹ã ãã¬ãŒã ã¯ãŒã¯ãèªåèªèº«ã®èŠä»¶ãŸãã¯ãŠãŒã¶ãŒã®èŠä»¶ã«åãããŠã«ã¹ã¿ãã€ãºããã«ã¯ãæ§æãã¡ã€ã«å ã®ããŒãœãã©ã€ãºãããã»ã¯ã·ã§ã³ã䜿çšããããã«ã¹ã¿ã ã³ãã³ã ã©ã€ã³ ãªãã·ã§ã³ã䜿çšããŸãã
èŠæ±ã®åŠç
次ã®ã»ã¯ã·ã§ã³ã§ã¯ããã¹ã ãã¬ãŒã ã¯ãŒã¯ãåä¿¡ããŠåŠçããå¯èœæ§ã®ããããŸããŸãªèŠæ±ã«ã€ããŠè©³ãã説æããŸãã
次ã®ã»ã¯ã·ã§ã³ã«é²ãåã«ããã¹ãå®è¡æ å ±ããã¹ã ãã©ãããã©ãŒã ã«äŒããããã®éèŠãªãµãŒãã¹ãIMessageBus ã®æŠå¿µã«ã€ããŠååçè§£ããããšãéèŠã§ãã
TestSessionContext
TestSessionContext ã¯ãã¹ãŠã®èŠæ±ã®å
±æããããã£ã§ãé²è¡äžã®ãã¹ã ã»ãã·ã§ã³ã«é¢ããæ
å ±ãæäŸããŸãã
public class TestSessionContext
{
public SessionUid SessionUid { get; }
}
public readonly struct SessionUid(string value)
{
public string Value { get; }
}
TestSessionContext ã¯ãé²è¡äžã®ãã¹ã ã»ãã·ã§ã³ã®äžæèå¥åã§ãã SessionUid ã§æ§æããããã¹ã ã»ãã·ã§ã³ ããŒã¿ã®ãã°äœæãšé¢é£ä»ããæ¯æŽããŸãã
DiscoverTestExecutionRequestïŒãã¹ãå®è¡ãªã¯ãšã¹ãã®æ€åºïŒ
public class DiscoverTestExecutionRequest
{
public TestSessionContext Session { get; }
public ITestExecutionFilter Filter { get; }
}
DiscoverTestExecutionRequest ã¯ããã¹ã ãã¬ãŒã ã¯ãŒã¯ã«ãã¹ããæ€åºãããã®æ
å ±ã IMessageBus ã«äŒããããæç€ºããŸãã
åã®ã»ã¯ã·ã§ã³ã§èª¬æããããã«ãæ€åºããããã¹ãã®ããããã£ã¯ DiscoveredTestNodeStateProperty ã§ãã åç
§çšã®æ±çšã³ãŒã ã¹ãããããæ¬¡ã«ç€ºããŸãã
var testNode = new TestNode
{
Uid = GenerateUniqueStableId(),
DisplayName = GetDisplayName(),
Properties = new PropertyBag(
DiscoveredTestNodeStateProperty.CachedInstance),
};
await context.MessageBus.PublishAsync(
this,
new TestNodeUpdateMessage(
discoverTestExecutionRequest.Session.SessionUid,
testNode));
// ...
ãã¹ãå®è¡èŠæ±ãå®è¡
public class RunTestExecutionRequest
{
public TestSessionContext Session { get; }
public ITestExecutionFilter Filter { get; }
}
RunTestExecutionRequest ã¯ããã¹ã ãã¬ãŒã ã¯ãŒã¯ã«ãã¹ããå®è¡ãããã®æ
å ±ã IMessageBus ã«äŒããããæç€ºããŸãã
åç §çšã®æ±çšã³ãŒã ã¹ãããããæ¬¡ã«ç€ºããŸãã
var skippedTestNode = new TestNode()
{
Uid = GenerateUniqueStableId(),
DisplayName = GetDisplayName(),
Properties = new PropertyBag(
SkippedTestNodeStateProperty.CachedInstance),
};
await context.MessageBus.PublishAsync(
this,
new TestNodeUpdateMessage(
runTestExecutionRequest.Session.SessionUid,
skippedTestNode));
// ...
var successfulTestNode = new TestNode()
{
Uid = GenerateUniqueStableId(),
DisplayName = GetDisplayName(),
Properties = new PropertyBag(
PassedTestNodeStateProperty.CachedInstance),
};
await context.MessageBus.PublishAsync(
this,
new TestNodeUpdateMessage(
runTestExecutionRequest.Session.SessionUid,
successfulTestNode));
// ...
var assertionFailedTestNode = new TestNode()
{
Uid = GenerateUniqueStableId(),
DisplayName = GetDisplayName(),
Properties = new PropertyBag(
new FailedTestNodeStateProperty(assertionException)),
};
await context.MessageBus.PublishAsync(
this,
new TestNodeUpdateMessage(
runTestExecutionRequest.Session.SessionUid,
assertionFailedTestNode));
// ...
var failedTestNode = new TestNode()
{
Uid = GenerateUniqueStableId(),
DisplayName = GetDisplayName(),
Properties = new PropertyBag(
new ErrorTestNodeStateProperty(ex.InnerException!)),
};
await context.MessageBus.PublishAsync(
this,
new TestNodeUpdateMessage(
runTestExecutionRequest.Session.SessionUid,
failedTestNode));
èŠæ±ãã£ã«ã¿ãŒãé©çšãã
ãŠãŒã¶ãŒãŸãã¯ããŒã«ãéžæãããã¹ãã®ã¿ãå®è¡ããã«ã¯ãæ€åºãšå®è¡ã®äž¡æ¹ã« TestExecutionRequest.Filter ãé©çšããŸãã MTP ã¯ãã£ã«ã¿ãŒããã¬ãŒã ã¯ãŒã¯ã«æž¡ããŸãããã©ãããã©ãŒã ã§ã¯ããã¬ãŒã ã¯ãŒã¯ãçºè¡ãŸãã¯å®è¡ãããã¹ãã¯ãã£ã«ã¿ãŒåŠçãããŸããã
Microsoft.Testing.Platform.Requestsã®stable ãã£ã«ã¿ãŒ ã³ã³ãã©ã¯ãã¯æ¬¡ã®ãšããã§ãã
| Filter | ãã¬ãŒã ã¯ãŒã¯ã®åäœ |
|---|---|
NopFilter |
远å ã®å¶çŽãé©çšããŸããã |
TestNodeUidListFilter |
å®å®ãã TestNodeUid ã TestNodeUids ã«å«ãŸãããã¹ãã®ã¿ãéžæããŸãã 空ã®é
åã§ã¯ããã¹ãã¯éžæãããŸããã |
UID ããå
容ãè§£éããªã倧æåãšå°æåãåºå¥ããèå¥åãšããŠæ¯èŒããŸãã 衚瀺åãæ°ããçæãããèå¥åã«çœ®ãæããªãã§ãã ããã ãã®ãã©ãããã©ãŒã ã§ã¯ã--filter-uid çšã® UID ãã£ã«ã¿ãŒã察象ãçµã£ãããŒã«èŠæ±ãããã³ åè©Šè¡æ¡åŒµæ©èœ ã䜿çšãããŠããŸãã
次ã®ãã«ããŒã¯ãããã 2 ã€ã®ãã£ã«ã¿ãŒã®çš®é¡ãåŠçããå®å šãªã¹ã€ãŒãããµã€ã¬ã³ãå®è¡ããã®ã§ã¯ãªãããµããŒããããŠããªããã£ã«ã¿ãŒãæåŠããŸãã
private static bool MatchesFilter(ITestExecutionFilter filter, TestNodeUid uid)
=> filter switch
{
NopFilter => true,
TestNodeUidListFilter uidFilter => uidFilter.TestNodeUids.Any(
candidate => string.Equals(candidate.Value, uid.Value, StringComparison.Ordinal)),
_ => throw new NotSupportedException(
$"Filter '{filter.GetType().FullName}' isn't supported.")
};
Private Shared Function MatchesFilter(filter As ITestExecutionFilter, uid As TestNodeUid) As Boolean
If TypeOf filter Is NopFilter Then
Return True
End If
Dim uidFilter = TryCast(filter, TestNodeUidListFilter)
If uidFilter IsNot Nothing Then
Return uidFilter.TestNodeUids.Any(
Function(candidate) String.Equals(candidate.Value, uid.Value, StringComparison.Ordinal))
End If
Throw New NotSupportedException($"Filter '{filter.GetType().FullName}' isn't supported.")
End Function
æ€åºãããããŒããçºè¡ããããéžæãããã¹ããå®è¡ããåã«ããã«ããŒã䜿çšããŸãã æ¬¡ã®ãµã³ãã« ãã¬ãŒã ã¯ãŒã¯ã§ã¯ãäž¡æ¹ã®èŠæ±ã«åãéžæããžãã¯ã䜿çšããŸãã
public async Task ExecuteRequestAsync(ExecuteRequestContext context)
{
if (context.Request is not DiscoverTestExecutionRequest
and not RunTestExecutionRequest)
{
throw new NotSupportedException("The request type isn't supported.");
}
var request = (TestExecutionRequest)context.Request;
foreach (var test in s_tests)
{
context.CancellationToken.ThrowIfCancellationRequested();
var uid = new TestNodeUid(test.Uid);
if (!MatchesFilter(request.Filter, uid))
{
continue;
}
if (request is DiscoverTestExecutionRequest)
{
await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(
request.Session.SessionUid,
new TestNode
{
Uid = uid,
DisplayName = test.Name,
Properties = new PropertyBag(DiscoveredTestNodeStateProperty.CachedInstance)
}));
}
else
{
await PublishResultAsync(context, request, uid, test.Name);
}
}
context.Complete();
}
Public Async Function ExecuteRequestAsync(context As ExecuteRequestContext) As Task Implements ITestFramework.ExecuteRequestAsync
If Not TypeOf context.Request Is DiscoverTestExecutionRequest AndAlso
Not TypeOf context.Request Is RunTestExecutionRequest Then
Throw New NotSupportedException("The request type isn't supported.")
End If
Dim request = DirectCast(context.Request, TestExecutionRequest)
For Each test In s_tests
context.CancellationToken.ThrowIfCancellationRequested()
Dim uid As New TestNodeUid(test.Uid)
If Not MatchesFilter(request.Filter, uid) Then
Continue For
End If
If TypeOf request Is DiscoverTestExecutionRequest Then
Await context.MessageBus.PublishAsync(Me, New TestNodeUpdateMessage(
request.Session.SessionUid,
New TestNode With {
.Uid = uid,
.DisplayName = test.Name,
.Properties = New PropertyBag(DiscoveredTestNodeStateProperty.CachedInstance)
}))
Else
Await PublishResultAsync(context, request, uid, test.Name)
End If
Next
context.Complete()
End Function
äžèŽãããã¹ãããªãå Žåã¯ãéžæãããŠããªããã¹ããå®è¡ãŸãã¯çºè¡ããã«ãªã¯ãšã¹ããå®äºããŸãã MTP ã¯ãããŒããã¹ãããŸãã¯ãæå°æ³å®ãã¹ããã®ããªã·ãŒãé©çšããŠããŸãã
Important
TreeNodeFilterãšCompositeTestExecutionFilterã¯è©Šé𿮵éã§ãããTPEXP蚺æ ID ã䜿çšããŸãã ããªãŒ ãã£ã«ã¿ãŒããµããŒããããã¬ãŒã ã¯ãŒã¯ã§ã¯ããã¹ã ããªãŒãšããããã£ã«å¯ŸããŠãã£ã«ã¿ãŒãè©äŸ¡ããå¿
èŠããããŸãã
ãã£ã«ã¿ãŒ ãããã€ããŒã䜿çšãããã¬ãŒã ã¯ãŒã¯ã§ã¯ãè€åãã£ã«ã¿ãŒã®ãã¹ãŠã®åãè©äŸ¡ããå¿
èŠããããŸãã ãã®äŸã®ãã«ããŒã¯ã NopFilter ãš TestNodeUidListFilterã®ã¿ããµããŒãããŠããŸãã
æ£èŠãã¹ãã®å®è¡
MTP 2.5 ãã¬ãã¥ãŒä»¥éã§ã¯ãé²è¡äžã® TestNodeUpdateMessage ã«å¯Ÿã㊠ExecuteRequestContext.StartTestExecutionAsync ãåŒã³åºãããšã§ãå®éšçãªæšæºåœ¢åŒ TestExecution ãéå§ã§ããŸãã start ã¡ãœããã¯ãé²è¡äžã®æŽæ°ããã°ã©ã ãçºè¡ããå®è¡ã©ã€ããµã€ã¯ã«ãã¡ãã»ãŒãžã®é åºä»ãããã¬ã¡ããªã®çžé¢é¢ä¿ãäžç·ã«ä¿æãããªããžã§ã¯ããè¿ããŸãã
RunãŸãã¯RunAsyncã䜿çšããŠãæ£èŠã®å®è¡ã³ã³ããã¹ãã§ãã¬ãŒã ã¯ãŒã¯ãåŒã³åºããã³ãŒãããã¹ãããŸãã OpenTelemetry ãã¢ã¯ãã£ããªå Žåããã¹ãã«ãã£ãŠäœæãããåã¢ã¯ãã£ããã£ã¯ãåããã¹ãå®è¡ã¢ã¯ãã£ããã£ã®äžã«æ®ããŸãã
é åºä»ããããçµæã¡ãã»ãŒãžãšãããã¥ãŒãµãŒã«ãã£ãŠç£èŠãããå®è¡ã®çµäºæå»ã䜿çšã㊠CompleteAsync ãåŒã³åºããŸãã ãã¹ãŠã®çµæã¯ãéå§ã¡ãã»ãŒãžã®ã»ãã·ã§ã³ããã¹ã UIDãããã³èŠª UID ã䜿çšããå¿
èŠããããŸãã æåŸã®ã¡ãã»ãŒãžã¯æçµçãªçµæã§ãã 空ã®ã³ã¬ã¯ã·ã§ã³ã¯ãçµæãçºæããããšãªããå®è¡ãå®äºããæŽæ°ãçºè¡ããŸãã
çµæãå
¬éããã«äžæ¢ããã«ã¯ãæªå®äºã® TestExecution ãç Žæ£ããŸãã å®äºãŸãã¯ç Žæ£åŸããªããžã§ã¯ãã¯è¿œå ã®å®è¡ãŸãã¯å®äºåŒã³åºããæåŠããŸãã
Important
StartTestExecutionAsync ãš TPEXP 㯠TestExecution 蚺æ ID ã䜿çšããŠãããä»åŸã®ãªãªãŒã¹ã§å€æŽãŸãã¯åé€ãããå¯èœæ§ããããŸãã
TestNodeUpdateMessage ããŒã¿
IMessageBus ã»ã¯ã·ã§ã³ã§èª¬æããããã«ãã¡ãã»ãŒãž ãã¹ã䜿çšããåã«ãæäŸããããŒã¿ã®åãæå®ããå¿
èŠããããŸãã ãã¹ããã©ãããã©ãŒã ã¯ãTestNodeUpdateMessage ã®æŠå¿µã衚çŸããããã«ãæ¢ç¥ã®åã§ãã ãå®çŸ©ããŠããŸãã
ããã¥ã¡ã³ãã®ãã®ããŒãã§ã¯ããã®ãã€ããŒã ããŒã¿ãå©çšããæ¹æ³ã«ã€ããŠèª¬æããŸãã 衚é¢ã確èªããŸãããã
public sealed class TestNodeUpdateMessage(
SessionUid sessionUid,
TestNode testNode,
TestNodeUid? parentTestNodeUid = null)
{
public TestNode TestNode { get; }
public TestNodeUid? ParentTestNodeUid { get; }
}
public class TestNode
{
public required TestNodeUid Uid { get; init; }
public required string DisplayName { get; init; }
public PropertyBag Properties { get; init; } = new();
}
public sealed class TestNodeUid(string value);
public sealed partial class PropertyBag
{
public PropertyBag();
public PropertyBag(params IProperty[] properties);
public PropertyBag(IEnumerable<IProperty> properties);
public int Count { get; }
public void Add(IProperty property);
public bool Any<TProperty>();
public TProperty? SingleOrDefault<TProperty>();
public TProperty Single<TProperty>();
public TProperty[] OfType<TProperty>();
public IEnumerable<IProperty> AsEnumerable();
public IEnumerator<IProperty> GetEnumerator();
...
}
public interface IProperty
{
}
TestNodeUpdateMessage:TestNodeUpdateMessageã¯TestNodeãšParentTestNodeUidã® 2 ã€ã®ããããã£ã§æ§æãããŸããParentTestNodeUidã¯ãã¹ãã芪ãã¹ããæã€å¯èœæ§ã瀺ãããã¹ãããªãŒã®æŠå¿µãå°å ¥ããŠããŸããTestNodeãäºãã«é¢é£ä»ããŠé 眮ããããšãã§ããŸãã ãã®æ§é ã«ãããããŒãéã®ããªãŒé¢ä¿ã«åºã¥ããŠãå°æ¥ã®æ©èœåŒ·åãšæ©èœãå¯èœã«ãªããŸãã ãã¹ã ãã¬ãŒã ã¯ãŒã¯ã§ãã¹ã ããªãŒæ§é ãå¿ èŠãªãå Žåã¯ãããã䜿çšãããnull ã«èšå®ããã ãã§ãTestNodeã®åçŽãªãã©ãã ãªã¹ããäœæã§ããŸããTestNode:TestNode㯠3 ã€ã®ããããã£ã§æ§æããããã®ãã¡ã® 1 ã€ã¯åUidã®TestNodeUidã§ãã ãã®Uidã¯ãããŒãã®äžæã®å®å®ãã ID ãšããŠæ©èœããŸãã "äžæã®å®å®ãã ID" ãšããçšèªã¯ãåãTestNodeãç°ãªãå®è¡éãšã·ã¹ãã éã§åäžã®Uidãç¶æããå¿ èŠãããããšãæå³ããŸãã ãã®TestNodeUidã¯ããã¹ã ãã©ãããã©ãŒã ããã®ãŸãŸåãå ¥ããä»»æã®äžéæãªæååã§ãã
Important
ID ã®å®å®æ§ãšäžææ§ã¯ããã¹ã ãã¡ã€ã³ã§ã¯éèŠã§ãã ãããã¯ãå®è¡ããåäžãã¹ãã®æ£ç¢ºãªã¿ãŒã²ããèšå®ãå¯èœã«ããID ããã¹ãã®æ°žç¶çãªèå¥åãšããŠæ©èœã§ããããã«ããŠã匷åãªæ¡åŒµæ©èœãæ©èœãæ¯æŽããŸãã
2 çªç®ã®ããããã£ã¯ DisplayName ã§ããã¹ãã®ããããããååã«ãªããŸãã ããšãã°ã--list-tests ã³ãã³ã ã©ã€ã³ãå®è¡ããéã«ãã®ååã衚瀺ãããŸãã
3 çªç®ã®å±æ§ã¯ Properties ã§ãPropertyBag åã«ãªããŸãã ã³ãŒãå
ã«ç€ºãããŠããããã«ããã㯠TestNodeUpdateMessage ã«é¢ããäžè¬çãªããããã£ãä¿æããç¹æ®ãªãããã㣠ããã°ã§ãã ããã¯ããã¬ãŒã¹ãã«ã㌠ã€ã³ã¿ãŒãã§ã€ã¹ IProperty ãå®è£
ããããŒãã«ä»»æã®ããããã£ã远å ã§ããããšãæå³ããŸãã
ãã¹ã ãã©ãããã©ãŒã ã¯ãTestNode.Properties ã«è¿œå ãããç¹å®ã®ããããã£ãèå¥ãããã¹ããåæ Œãããã倱æãããããŸãã¯ã¹ãããããããã倿ããŸãã
䜿çšå¯èœãªããããã£ã®çŸåšã®äžèЧã«ã€ããŠã¯ããTestNodeUpdateMessage.TestNode ãã»ã¯ã·ã§ã³çžå¯Ÿèª¬æãåç §ããŠãã ããã
PropertyBag åã¯ãéåžžããã¹ãŠã® IData ã§ã¢ã¯ã»ã¹ã§ãããã©ãããã©ãŒã ãšæ¡åŒµæ©èœã§ã¯ãšãªã®å®è¡ãã§ãããã®ä»ã®ããããã£ãæ ŒçŽããããã«äœ¿çšãããŸãã ãã®ã¡ã«ããºã ã«ãããç Žå£ç倿Žãå°å
¥ããããšãªããæ°ããæ
å ±ã§ãã©ãããã©ãŒã ã匷åã§ããŸãã ã³ã³ããŒãã³ãã¯ããããã£ãèªèãããšããã®ã¯ãšãªãå®è¡ã§ããŸããèªèããªãå Žåã¯ãç¡èŠããŸãã
æåŸã«ããã®ã»ã¯ã·ã§ã³ã§ã¯ããã¹ã ãã¬ãŒã ã¯ãŒã¯ã®å®è£
ã«ã¯ã次ã®ãµã³ãã«å
ã®ãã㪠IDataProducer ãçæãã TestNodeUpdateMessage ãå®è£
ããå¿
èŠãããããšã«ã€ããŠèª¬æããŸãã
internal sealed class TestingFramework
: ITestFramework, IDataProducer
{
// ...
public Type[] DataTypesProduced =>
[
typeof(TestNodeUpdateMessage)
];
// ...
}
ãã¹ã ã¢ããã¿ãŒãå®è¡äžã« ãã¡ã€ã« ãçæããå Žåããã©ãããã©ãŒã 㯠2 ã€ã®ç°ãªãã¡ã«ããºã ãèªèããŸããé©åãªã¡ã«ããºã ã¯ããã¡ã€ã«ãç¹å®ã®ãã¹ãã«å±ããŠããããå®è¡å šäœã«å±ããŠãããã«ãã£ãŠç°ãªããŸãã 詳现ã«ã€ããŠã¯ãã ã¡ãã»ãŒãž ãã¹ ãã¡ã€ã«ã®ææç©ããåç §ããŠãã ããã
- å®è¡ã¬ãã«ãŸãã¯ã»ãã·ã§ã³ ã¬ãã«ã®ãã¡ã€ã«ã¯ãã¹ã¿ã³ãã¢ãã³ ã®ãã¹ ã¡ãã»ãŒãžã§ãã
FileArtifact(ã¹ã³ãŒããªã) ãŸãã¯SessionFileArtifact(SessionUidãä»ããŠå®è¡ãã¹ã³ãŒãæå®) ãçºè¡ããŸãã - ãã¹ãåºæã®æ·»ä»ãã¡ã€ã«ã¯ãã¹ã¿ã³ãã¢ãã³ ã¡ãã»ãŒãžã§ã¯ãããŸããã ãããã
FileArtifactPropertyå ã®TestNode.Propertiesã«TestNodeUpdateMessageãšã³ããªãšããŠè¿œå ããã¿ãŒããã«ãdotnet testãIDE ãåãã¡ã€ã«ããã¹ãã«é¢é£ä»ããŸãã
SessionFileArtifactãçºè¡ããå Žåã¯ã次ã«ç€ºãããã«ãDataTypesProducedãéããŠäºåã«ãã®ã©ã³ã¿ã€ã åããã©ãããã©ãŒã ã«å®£èšããå¿
èŠããããŸãã
FileArtifactPropertyã¯ãç¬èªã®ã¡ãã»ãŒãžã®çš®é¡ã§ã¯ãªããTestNodeUpdateMessageå
ãç§»åãããããåå¥ã«äžèŠ§è¡šç€ºãããŠããªãããšã«æ³šæããŠãã ããã
internal sealed class TestingFramework
: ITestFramework, IDataProducer
{
// ...
public Type[] DataTypesProduced =>
[
typeof(TestNodeUpdateMessage),
typeof(SessionFileArtifact)
];
// ...
}
æ¢ç¥ã®ããããã£
èŠæ±ã»ã¯ã·ã§ã³ã§è©³ãã説æããããã«ããã¹ã ãã©ãããã©ãŒã ã§ã¯ãTestNodeUpdateMessageã®ç¶æ
(æåã倱æãã¹ããããªã©) ã倿ããããã«ãTestNodeã«è¿œå ãããç¹å®ã®ããããã£ãèå¥ãããŸãã ããã«ãããã©ã³ã¿ã€ã ã¯ã倱æãããã¹ãã®äžèЧãšå€±æãããã¹ãã«å¯Ÿå¿ããæ
å ±ãã³ã³ãœãŒã«ã§æ£ç¢ºã«è¡šç€ºãããããã¹ã ããã»ã¹ã«é©åãªçµäºã³ãŒããèšå®ãããã§ããããã«ãªããŸãã
èŠæ±ã»ã¯ã·ã§ã³ã§è©³ãã説æããããã«ããã¹ã ãã©ãããã©ãŒã ã§ã¯ãTestNodeUpdateMessageã«è¿œå ãããç¹å®ã®ããããã£ãèå¥ããŠãTestNodeã®ç¶æ
(æåã倱æãã¹ããããªã©) ãæ±ºå®ããŸãã ããã«ãããã©ã³ã¿ã€ã ã¯ã倱æãããã¹ãã®äžèЧãšå€±æãããã¹ãã«å¯Ÿå¿ããæ
å ±ãã³ã³ãœãŒã«ã§æ£ç¢ºã«è¡šç€ºãããããã¹ã ããã»ã¹ã«é©åãªçµäºã³ãŒããèšå®ãããã§ããããã«ãªããŸãã
ãã®ã»ã¯ã·ã§ã³ã§ã¯ãããç¥ãããŠããããŸããŸãª IProperty ãªãã·ã§ã³ãšãããããã®åœ±é¿ã«ã€ããŠèª¬æããŸãã
æ¢ç¥ã®ããããã£ã®å
æ¬çãªäžèЧã«ã€ããŠã¯ã TestNodeStateProperties.cs (ããã³åããã£ã¬ã¯ããªå
ã®ä»ã® Property å) ãåç
§ããŠãã ããã ããããã£ã®èª¬æãèŠã€ãããªãå Žåã¯ãåé¡ãæåºããŠãã ããã
ãããã®ããããã£ã¯ã次ã®ã«ããŽãªã«åé¡ã§ããŸãã
- äžè¬çãªæ å ±: ä»»æã®çš®é¡ã®èŠæ±ã«å«ããããšãã§ããããããã£ã
-
æ€åºæ
å ±:
DiscoverTestExecutionRequestæ€åºèŠæ±äžã«æå®ãããããããã£ã -
å®è¡æ
å ±: ãã¹ãå®è¡èŠæ±
RunTestExecutionRequestäžã«æå®ãããããããã£ã
ç¹å®ã®ããããã£ã¯å¿ é ã§ããããã®ä»ã®ããããã£ã¯çç¥å¯èœã§ãã å¿ é ããããã£ã¯ã倱æãããã¹ããå ±åãããããã¹ã ã»ãã·ã§ã³å šäœãæåãããã©ããã瀺ããããããªã©ãåºæ¬çãªãã¹ãæ©èœãæäŸããããã«å¿ èŠã§ãã
äžæ¹ãçç¥å¯èœãªããããã£ã¯ãè¿œå æ å ±ãæäŸããããšã§ãã¹ã ãšã¯ã¹ããªãšã³ã¹ã匷åããŸãã ãããã¯ç¹ã«ãIDE ã·ããªãª (VSãVSCode ãªã©) ããã³ã³ãœãŒã«ã®å®è¡ããŸãã¯æ£ããæ©èœããããã«ããè©³çŽ°ãªæ å ±ãå¿ èŠãšããç¹å®ã®æ¡åŒµæ©èœããµããŒãããéã«æçšã§ãã ãã ãããããã®çç¥å¯èœãªããããã£ã¯ããã¹ãã®å®è¡ã«ã¯åœ±é¿ããŸããã
泚
æ¡åŒµæ©èœã¯ãæ£ããåäœããããã«ç¹å®ã®æ å ±ãå¿ èŠãªå ŽåãäŸå€ãéç¥ããŠç®¡çãã圹å²ãæ ããŸãã æ¡åŒµæ©èœã¯ãå¿ èŠãªæ å ±ãæ¬ èœããŠããå Žåããã¹ãå®è¡ã®å€±æãåŒãèµ·ããã®ã§ã¯ãªããåã«ãªããã¢ãŠãããŸãã
äžè¬çãªæ å ±
public record struct LinePosition(
int Line,
int Column);
public record struct LinePositionSpan(
LinePosition Start,
LinePosition End);
public abstract record FileLocationProperty(
string FilePath,
LinePositionSpan LineSpan)
: IProperty;
public sealed record TestFileLocationProperty(
string FilePath,
LinePositionSpan LineSpan)
: FileLocationProperty(FilePath, LineSpan);
TestFileLocationProperty ã¯ããœãŒã¹ ãã¡ã€ã«å
ã®ãã¹ãã®å Žæãç¹å®ããããã«äœ¿çšãããŸãã ããã¯ãã€ãã·ãšãŒã¿ãŒã Visual Studio ã Visual Studio Code ãªã©ã® IDE ã§ããå Žåã«ç¹ã«äŸ¿å©ã§ãã
public sealed record TestMethodIdentifierProperty(
string AssemblyFullName,
string Namespace,
string TypeName,
string MethodName,
string[] ParameterTypeFullNames,
string ReturnTypeFullName)
TestMethodIdentifierProperty ã¯ããã¹ã ã¡ãœããã®äžæèå¥åã§ãã
ç§»æ€å¯èœãªããŒãšå€ã®ã¡ã¿ããŒã¿ãå
¬éããã«ã¯ãMicrosoft.Testing.Platform.Extensions.Messages ã® TestMetadataProperty ãäœæããããã TestNode.Properties ã«è¿œå ããŸãã
var metadata = new TestMetadataProperty("Environment", "Staging");
Dim metadata = New TestMetadataProperty("Environment", "Staging")
MTP ã¯ãJSON æ€åºåºåãšãµãŒã㌠ã¢ãŒãã®æŽæ°ã«ãããŠããããã®ããããã£ãç¹æ§ãšããŠå
¬éããŸãã ä»»æã® IProperty å®è£
ã¯ãããã»ã¹å
ã®å©çšè
ã«ã¯åŒãç¶ãå©çšå¯èœã§ãããå€éšã¯ã©ã€ã¢ã³ãã«å¯ŸããŠã¯èªåçã«ã·ãªã¢ã«åãããŸããã ãã©ãããã©ãŒã ã®å
éš SerializableKeyValuePairStringProperty åã¯ãå
¬éãããæ¡åŒµãã€ã³ãã§ã¯ãããŸããã
MTP 2.4 以éã§ã¯ã倱æãããã¹ã ããŒãã« AssertionFailureProperty ã远å ããŠãäºåãã©ãŒããããããåå¥ã®äºæãããå€ãšå®éã®å€ãæå®ããŸãã ã¬ããŒã ã³ã³ã·ã¥ãŒããŒã¯ããšã©ãŒ ã¡ãã»ãŒãžãè§£æãã代ããã«ããããã®å€ã䜿çšããŠæ§é åãããéããã¬ã³ããªã³ã°ã§ããŸãã å°ãªããšã 1 ã€ã®å€ãnull以å€ã§ããå¿
èŠããããŸãã ã³ã³ã·ã¥ãŒããŒã¯ãã®ããããã£ãåªå
ããŸãããDataã®åŸæ¥ã®assert.expectedãšassert.actualãšã³ããªã«ãã©ãŒã«ããã¯ã§ããŸãã
MTP 2.4 以éã§ã¯ãã€ã³ããã»ã¹å詊è¡ã·ãŒã±ã³ã¹å
ã®ãã¹ãŠã®æŽæ°ã« RetryAttemptProperty ã远å ããŸãã
AttemptNumber 㯠1 å§ãŸãã§ãIsSuperseded ã¯åŸã®è©Šè¡ã«ãã£ãŠçœ®ãæãããã詊è¡ã瀺ããŸãã TRXãJUnitãããã³ããã»ã¹çµäºã³ãŒãã¯çœ®ãæãããã詊è¡ãç¡èŠããŸãããã¿ãŒããã«ãHTMLãCTRF ã³ã³ã·ã¥ãŒããŒã¯å®å
šãªå±¥æŽãä¿æã§ããŸãã ãã®ããããã£ã¯ãããã»ã¹å€ã® --retry-failed-tests 詊è¡ã衚ããŠããŸããã
ãã£ããã£ããããã¹ãåºå
ãã£ããã£ããããã¹ãããã¹ãã«é¢é£ä»ããã«ã¯ãStandardOutputPropertyããMicrosoft.Testing.Platform.Extensions.MessagesãšTestNode.Propertiesããã®ãã¹ãã®StandardErrorPropertyã«è¿œå ããŸãã ãã¹ãçµæãšåãå®å®ãã UID ãšã»ãã·ã§ã³ã䜿çšããŠã TestNodeUpdateMessage ãä»ããŠããŒããçºè¡ããŸãã
ãã®ãã¬ãŒã ã¯ãŒã¯ã¯ã䞊åãã¹ãéã®åé¢ãå«ããåºåã®ååŸãšåž°å±ã管çããŸãã MTP ã¯ããããã£ãåã蟌ã¿ãŸããWriteLine ãžã®ä»»æã®åŒã³åºãã¯èªåçã«ãã£ããã£ãããŸããã æ¬¡ã®äŸã§ã¯ãå®éã®ãã¬ãŒã ã¯ãŒã¯ã«ãã£ãŠãã£ããã£ãããåºåã®ä»£ããã«ãµã³ãã« ããã¹ãã䜿çšããŸãã
var testNode = new TestNode
{
Uid = uid,
DisplayName = name,
Properties = new PropertyBag(
PassedTestNodeStateProperty.CachedInstance,
new StandardOutputProperty($"Output from {name}."),
new StandardErrorProperty($"Diagnostic from {name}."))
};
await context.MessageBus.PublishAsync(
this, new TestNodeUpdateMessage(request.Session.SessionUid, testNode));
Dim testNode As New TestNode With {
.Uid = uid,
.DisplayName = name,
.Properties = New PropertyBag(
PassedTestNodeStateProperty.CachedInstance,
New StandardOutputProperty($"Output from {name}."),
New StandardErrorProperty($"Diagnostic from {name}."))
}
Await context.MessageBus.PublishAsync(
Me, New TestNodeUpdateMessage(request.Session.SessionUid, testNode))
ã¿ãŒããã« ã¬ããŒã¿ãŒã¯ã --show-stdout ãš --show-stderrã§ãããã®ããããã£ã䜿çšããŸãã æšæºãšã©ãŒ ããããã£ã§ã¯ããã¹ãã¯å€±æããŸããããã¹ãã®ç¶æ
ããããã£ã«ãã£ãŠçµæã決ãŸããŸãã
IOutputDevice ãéããŠãåãã¹ãããšã®åºåãã蚺æãã°ãæ¡åŒµæ©èœã¬ãã«ã®åºåãšã¯åºå¥ããããã«ããŠãã ããã TRX ã¬ããŒãã«ããã¹ããå«ããã«ã¯ãTRX åºæã®ã¡ãã»ãŒãž ããããã£ã远å ã§æå®ããŠãã ããã ãã¹ãŠã®ã¬ããŒã ã³ã³ã·ã¥ãŒããŒãåãããããã£ãããããããšã¯èããªãã§ãã ããã
æ€åºæ å ±
public sealed record DiscoveredTestNodeStateProperty(
string? Explanation = null)
{
public static DiscoveredTestNodeStateProperty CachedInstance { get; }
}
DiscoveredTestNodeStateProperty ã¯ãTestNode ãæ€åºãããããšã瀺ããŸãã ããã¯ãDiscoverTestExecutionRequest ããã¹ã ãã¬ãŒã ã¯ãŒã¯ã«éä¿¡ãããéã«äœ¿çšãããŸãã
CachedInstance ããããã£ã§æäŸããã䟿å©ãªãã£ãã·ã¥å€ãæžãçããŸãã
ãã®ããããã£ã¯å¿
é ã§ãã
å®è¡æ å ±
public sealed record InProgressTestNodeStateProperty(
string? Explanation = null)
{
public static InProgressTestNodeStateProperty CachedInstance { get; }
}
InProgressTestNodeStateProperty ã¯ãTestNode ã®å®è¡ãã¹ã±ãžã¥ãŒã«ãããŠãããçŸåšé²è¡äžã§ããããšããã¹ã ãã©ãããã©ãŒã ã«éç¥ããŸãã
CachedInstance ããããã£ã§æäŸããã䟿å©ãªãã£ãã·ã¥å€ãæžãçããŸãã
public readonly record struct TimingInfo(
DateTimeOffset StartTime,
DateTimeOffset EndTime,
TimeSpan Duration);
public sealed record StepTimingInfo(
string Id,
string Description,
TimingInfo Timing);
public sealed record TimingProperty : IProperty
{
public TimingProperty(TimingInfo globalTiming)
: this(globalTiming, [])
{
}
public TimingProperty(
TimingInfo globalTiming,
StepTimingInfo[] stepTimings)
{
GlobalTiming = globalTiming;
StepTimings = stepTimings;
}
public TimingInfo GlobalTiming { get; }
public StepTimingInfo[] StepTimings { get; }
}
TimingProperty ã¯ãTestNode ã®å®è¡ã«é¢ããã¿ã€ãã³ã°ã®è©³çްããªã¬ãŒããããã«äœ¿çšãããŸãã ãŸããStepTimingInfo ãä»ããŠåã
ã®å®è¡ã¹ãããã®ã¿ã€ãã³ã°ãå¯èœã«ããŸã. ããã¯ç¹ã«ãåæåãå®è¡ãã¯ãªãŒã³ã¢ãããªã©ããã¹ãã®æŠå¿µãè€æ°ã®ãã§ãŒãºã«åãããŠããå Žåã«æçšã§ãã
次ã®ããããã£ã®ãã¡ 1 ã€ã ã ã ããšã«TestNodeã§ãããTestNode ã®çµæããã¹ã ãã©ãããã©ãŒã ã«äŒããŸãã
public sealed record PassedTestNodeStateProperty(
string? Explanation = null)
: TestNodeStateProperty(Explanation)
{
public static PassedTestNodeStateProperty CachedInstance
{ get; } = new PassedTestNodeStateProperty();
}
PassedTestNodeStateProperty ã¯ããã® TestNode ãæž¡ãããããšããã¹ã ãã©ãããã©ãŒã ã«éç¥ããŸãã
CachedInstance ããããã£ã§æäŸããã䟿å©ãªãã£ãã·ã¥å€ãæžãçããŸãã
public sealed record SkippedTestNodeStateProperty(
string? Explanation = null)
: TestNodeStateProperty(Explanation)
{
public static SkippedTestNodeStateProperty CachedInstance
{ get; } = new SkippedTestNodeStateProperty();
}
SkippedTestNodeStateProperty ã¯ããã® TestNode ãã¹ããããããããšããã¹ã ãã©ãããã©ãŒã ã«éç¥ããŸãã
CachedInstance ããããã£ã§æäŸããã䟿å©ãªãã£ãã·ã¥å€ãæžãçããŸãã
public sealed record FailedTestNodeStateProperty : TestNodeStateProperty
{
public FailedTestNodeStateProperty()
: base(default(string))
{
}
public FailedTestNodeStateProperty(string explanation)
: base(explanation)
{
}
public FailedTestNodeStateProperty(
Exception exception,
string? explanation = null)
: base(explanation ?? exception.Message)
{
Exception = exception;
}
public Exception? Exception { get; }
}
FailedTestNodeStateProperty ã¯ããã® TestNode ãã¢ãµãŒã·ã§ã³ã®åŸã«å€±æããããšããã¹ã ãã©ãããã©ãŒã ã«éç¥ããŸãã
public sealed record ErrorTestNodeStateProperty : TestNodeStateProperty
{
public ErrorTestNodeStateProperty()
: base(default(string))
{
}
public ErrorTestNodeStateProperty(string explanation)
: base(explanation)
{
}
public ErrorTestNodeStateProperty(
Exception exception,
string? explanation = null)
: base(explanation ?? exception.Message)
{
Exception = exception;
}
public Exception? Exception { get; }
}
ErrorTestNodeStateProperty ã¯ããã® TestNode ã倱æããããšããã¹ã ãã©ãããã©ãŒã ã«éç¥ããŸãã ãã®çš®é¡ã®ãšã©ãŒã¯ãã¢ãµãŒã·ã§ã³ ãšã©ãŒã«äœ¿çšããã FailedTestNodeStateProperty ãšã¯ç°ãªããŸãã ããšãã°ããã¹ãåæåãšã©ãŒãªã©ã®åé¡ã ErrorTestNodeStateProperty ã䜿çšããŠå ±åã§ããŸãã
public sealed record TimeoutTestNodeStateProperty : TestNodeStateProperty
{
public TimeoutTestNodeStateProperty()
: base(default(string))
{
}
public TimeoutTestNodeStateProperty(string explanation)
: base(explanation)
{
}
public TimeoutTestNodeStateProperty(
Exception exception,
string? explanation = null)
: base(explanation ?? exception.Message)
{
Exception = exception;
}
public Exception? Exception { get; }
public TimeSpan? Timeout { get; init; }
}
TimeoutTestNodeStateProperty ã¯ããã® TestNode ãã¿ã€ã ã¢ãŠãã®çç±ã§å€±æããããšããã¹ã ãã©ãããã©ãŒã ã«éç¥ããŸãã
Timeout ããããã£ã䜿çšããŠãã¿ã€ã ã¢ãŠããå ±åã§ããŸãã
public sealed record CancelledTestNodeStateProperty : TestNodeStateProperty
{
public CancelledTestNodeStateProperty()
: base(default(string))
{
}
public CancelledTestNodeStateProperty(string explanation)
: base(explanation)
{
}
public CancelledTestNodeStateProperty(
Exception exception,
string? explanation = null)
: base(explanation ?? exception.Message)
{
Exception = exception;
}
public Exception? Exception { get; }
}
CancelledTestNodeStateProperty ã¯ããã® TestNode ããã£ã³ã»ã«ã«ãã倱æããããšããã¹ã ãã©ãããã©ãŒã ã«éç¥ããŸãã