-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OSOE-935: Upgrade to xUnit 3 and handling test cancellations gracefully #432
base: dev
Are you sure you want to change the base?
Conversation
# Conflicts: # Lombiq.Tests.UI/CompatibilitySuppressions.xml
|
||
// While there may be some common code between local and remote tests, they cannot be the same, and the common code must | ||
// be in a project independent of the web app (which is not the case here for the sake of simplicity): | ||
// - In local tests, you have a much lower-level access to the app: E.g., you can access the Orchard Core log, use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean "higher-level"?
// - In local tests, you have a much lower-level access to the app: E.g., you can access the Orchard Core log, use | |
// - In local tests, you have much higher-level access to the app: E.g., you can access the Orchard Core log, use |
@@ -48,6 +48,8 @@ public static Task TestWorkflowsAsync(this UITestContext context) => | |||
By.XPath("//div[@class = 'jtk-endpoint jtk-endpoint-anchor jtk-draggable jtk-droppable']"), // #spell-check-ignore-line | |||
By.XPath(taskXPath)); | |||
|
|||
context.WaitElementToNotChange(By.ClassName("jtk-connector")); // #spell-check-ignore-line |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this change is necessary?
public ITest XunitTest { get; } | ||
public string Name => XunitTest?.DisplayName; | ||
public ITest XunitTest => TestContext.Current.Test; | ||
public string Name => XunitTest?.TestDisplayName; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can TestContext.Current.Test
null
here?
public ITest XunitTest { get; } | ||
public string Name => XunitTest?.DisplayName; | ||
public ITest XunitTest => TestContext.Current.Test; | ||
public string Name => XunitTest?.TestDisplayName; | ||
public Func<UITestContext, Task> TestAsync { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -369,7 +369,7 @@ protected virtual async Task ExecuteTestAsync( | |||
Func<UITestContext, Task<Uri>> setupOperation, | |||
Func<OrchardCoreUITestExecutorConfiguration, Task> changeConfigurationAsync) | |||
{ | |||
var testManifest = new UITestManifest(_testOutputHelper) { TestAsync = testAsync }; | |||
var testManifest = new UITestManifest { TestAsync = testAsync }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comment for UITestManifest.TestAsync
.
@@ -61,7 +61,7 @@ async Task BaseUriVisitingTest(UITestContext context) | |||
await testAsync(context); | |||
} | |||
|
|||
var testManifest = new UITestManifest(_testOutputHelper) { TestAsync = BaseUriVisitingTest }; | |||
var testManifest = new UITestManifest { TestAsync = BaseUriVisitingTest }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comment for UITestManifest.TestAsync
.
@@ -61,6 +61,12 @@ public UITestExecutionSession( | |||
|
|||
public async Task<bool> ExecuteAsync(int retryCount, string dumpRootPath) | |||
{ | |||
_configuration.TestCancellationToken.Register(() => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure, but I think System.Threading.CancellationTokenRegistration
returned by CancellationToken.Register
needs to be disposed.
Is this really necessary?
Testing _configuration.TestCancellationToken.IsCancellationRequested
also wellcome before starting the whole ceremony.
if (timeoutTask.IsCompleted) | ||
{ | ||
// If the EnterInteractiveModeAsync() extension method has been used, then timeout should be ignored to | ||
// make the debugging experience smoother. Note that EnterInteractiveModeAsync() should never be used in | ||
// committed tests. | ||
if (!ShortcutsUITestContextExtensions.InteractiveModeHasBeenUsed) | ||
{ | ||
throw new TimeoutException($"The time allotted for the test ({timeout}) was exceeded."); | ||
} | ||
|
||
await testTask; | ||
} | ||
|
||
// Since the timeout task is not yet completed but the Task.WhenAny has finished, the test task is done in | ||
// some way. So it's safe to await it here. It's also necessary to cleanly propagate any exceptions that may | ||
// have been thrown inside it. | ||
await testTask; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case when a cancellation is requested on the _configuration.TestCancellationToken
, the timeoutTask.IsCompleted
will be true
.
@@ -75,11 +60,6 @@ private static async Task ExecuteOrchardCoreTestInnerAsync( | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The _configuration.TestCancellationToken.IsCancellationRequested
can also stop the loop.
OSOE-935
Fixes #430
Fixes #82
Test cancellation can be tried when running the exe of a test: run it from the CLI, wait like 10 seconds, hit Ctrl+C (only once), and you should see "Test execution was cancelled. Shutting down the test execution session." at one point (only once the tests actually started).
To be added to the release notes:
Upgraded xUnit to v3 with breaking changes
This version of the UI Testing Toolbox uses v3 of xUnit, which brings many updates. However, it's also a breaking version, requiring you to adapt your test projects, see the official guide.
Migrating UI test projects consuming the UI Testing Toolbox should be simpler, though, with you requiring to do roughly the following steps:
xunit.runner.visualstudio
package reference to latest (currently 3.0.0).<OutputType>Exe</OutputType>
to the firstPropertyGroup
in the test project's csproj). These are all the projects withxunit.runner.visualstudio
references.xunit
package references toxunit.v3
with the latest version (currently 1.0.0). If a test project lacks such a reference then add it (currently<PackageReference Include="xunit.v3" Version="1.0.0" />
). Only test projects should referencexunit
.Microsoft.NET.Test.Sdk
references in the test projects to latest (currently 17.12.0) too while we're at it, or add it if it's missing (currently<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
).ITestOutputHelper
is now in theXunit
namespace instead ofXunit.Abstractions
. Fix the namespace imports inUITestBase
classes first and then anywhere else; they'll show up as build errors.unit.v3
. You might need to do a recursive git clean to be sure to start with a clean slate.