I currently trying to find a solution, how to ensure that a test fails if an exception occurs in a thread which is spawn by the test method.
I DON'T want to start a discussion about more than one thread in a unit test. => "unit test".Replace("unit","integration");
I already read a lot of threads in several forums, I know about CrossThreadTestRunner, but I'm searching for a solution whichs integrates into nunit, and does not require to rewrite a lot of tests.
The reason that exceptions on non-test threads (i.e. other spawned threads) do not cause tests to fail is that NUnit is configured by default to use legacyUnhandledExceptionPolicy which is a .Net process level setting which can be applied via app.config, i.e.:
<legacyUnhandledExceptionPolicy enabled="1"/>
Enabling this setting (i.e. setting it to "1") causes exceptions which do not occur on the main thread to be ignored.
I wrote an article which goes into more detail in reference to this issue with the ReSharper test runner, but it applies equally to the NUnit test runner:
https://web.archive.org/web/20101006004301/http://gojisoft.com/blog/2010/05/14/resharper-test-runner-hidden-thread-exceptions/)
ReSharper test runner – hidden thread exceptions
By Tim Lloyd, May 14, 2010 4:31 pm
We use the ReSharper test runner here at GojiSoft to run NUnit tests
from within Visual Studio. It’s a great test runner, but doesn’t play
nicely with multi-threaded components where exceptions may occur on
non-test threads. Unhandled exceptions on non-test threads are hidden
and tests which should fail, instead pass.
...
The problem lies in the fact that the ReSharper test runner is
configured to behave in the same way as .Net 1.0 and 1.1 apps where
unhandled exceptions on non-main threads were swallowed. The situation
improves from .Net 2.0 where all unhandled exceptions flatten the
process. However, Microsoft had to allow existing .Net 1.0 and 1.1
apps the option of behaving as before on new .Net frameworks. They
introduced the app.config setting: legacyUnhandledExceptionPolicy.
The ReSharper test runner is configured by default to use the .Net 1.0
and 1.1 policy, so if there is an unhandled non-test thread exception
it does not bubble up and cause the test to fail – the test passes,
and we get a false positive instead.
If unhandled exceptions on non-test threads should fail tests, the
app.config for the ReSharper test runner has to be updated.
...
Turn the legacy unhandled exception policy off by editing legacyUnhandledExceptionPolicy: <legacyUnhandledExceptionPolicy enabled="0" />
Now multi-threaded tests fail as expected when they raise exceptions on non-test threads:
Buyer beware…
There is a caveat to this. Exceptions on non-test threads will now
flattened the test runner and test suite execution will be halted when
they happen. This is in contrast to normal test runs where failed
tests are marked as failed, and the test runner continues. ...
I just had the same problem, my solution is to catch the exception and increment an exception counter, so the Test method just have to assert the exception counter is 0 to confirm no thread got an exception.
An extract of my test code once specific environment stuff is removed:
const int MaxThreads = 25;
const int MaxWait = 10;
const int Iterations = 10;
private readonly Random random=new Random();
private static int startedThreads=MaxThreads ;
private static int exceptions = 0;
…
[Test]
public void testclass()
{
// Create n threads, each of them will be reading configuration while another one cleans up
Thread thread = new Thread(Method1)
{
IsBackground = true,
Name = "MyThread0"
};
thread.Start();
for (int i = 1; i < MaxThreads; i++)
{
thread = new Thread(Method2)
{
IsBackground = true,
Name = string.Format("MyThread{0}", i)
};
thread.Start();
}
// wait for all of them to finish
while (startedThreads > 0 && exceptions==0)
{
Thread.Sleep(MaxWait);
}
Assert.AreEqual(0, exceptions, "Expected no exceptions on threads");
}
private void Method1()
{
try
{
for (int i = 0; i < Iterations; i++)
{
// Stuff being tested
Thread.Sleep(random.Next(MaxWait));
}
}
catch (Exception exception)
{
Console.Out.WriteLine("Ërror in Method1 Thread {0}", exception);
exceptions++;
}
finally
{
startedThreads--;
}
}
private void Method2()
{
try
{
for (int i = 0; i < Iterations; i++)
{
// Stuff being tested
Thread.Sleep(random.Next(MaxWait));
}
}
catch (Exception exception)
{
Console.Out.WriteLine("Ërror in Method2 Thread {0}", exception);
exceptions++;
}
finally
{
startedThreads--;
}
}
I solved the problem by creating an addin for nunit, which "installs" an ITestDecorator.
Related
I was trying to update the recycler view content from a background thread in Kotlin. I am not using AsyncTask.
Here is my code, i want to know if there is any better way than this:
In my MainActivity, i have progressThread as a member variable.
var progressThread = Thread()
Then in my method where i want to run the thread first i am defining it...like
progressThread = Thread (
Runnable {
kotlin.run {
try {
while (i <= 100 && !progressThread.isInterrupted) {
Thread.sleep(200)
//Some Logic
runOnUiThread {
//this runs in ui thread
}
i++
}
}catch (e:InterruptedException){
progressThread.interrupt()
}
}
})
after that i am starting it in the same method as
progressThread.start()
and for stopping it, i have a listener to cancel the progress and in the callback of that listener, i have written:
progressThread.interrupt()
Updated
Coroutines are stable now,: https://kotlinlang.org/docs/reference/coroutines-overview.html
Old Answer
Yes, you can do this using doAsync from kotlin anko library that is fairly simple and easy to use.
add following line in module level gradle file:
compile "org.jetbrains.anko:anko-commons:0.10.0"
Code example:
val future = doAsync {
// do your background thread task
result = someTask()
uiThread {
// use result here if you want to update ui
updateUI(result)
}
}
code block written in uiThread will only be executed if your Activity or Fragment is in foreground mode (It is lifecycle aware). So if you are trying to stop thread because you don't want your ui code to execute when Activity is in background, then this is an ideal case for you.
As you can check doAsync returns a Future object so you can cancel the background task, by cancel() function:
future.cancel(true)
pass true if you want to stop the thread even when it has started executing.
If you have more specialised case to handle stopping case then you can do the same thing as in your example.
You can use Kotlin Coroutines also but its in Experimental phase, still you can try it out: https://kotlinlang.org/docs/reference/coroutines.html
This a simplification and narrowing to another of my questions: Need help parallel traversing a dag in D
Say you've got some code that you want to parallelize. The problem is, some of the things you need to do have prerequisites. So you have to make sure that those prerequisites are done before you add the new task into the pool. The simple conceptual answer is to add new tasks as their prerequisites finish.
Here I have a little chunk of code that emulates that pattern. The problem is, it throws an exception because pool.finish() gets called before a new task is put on the queue by the worker thread. Is there a way to just wait 'till all threads are idle or something? Or is there another construct that would allow this pattern?
Please note: this is a simplified version of my code to illustrate the problem. I can't just use taskPool.parallel() in a foreach.
import std.stdio;
import std.parallelism;
void simpleWorker(uint depth, uint maxDepth, TaskPool pool){
writeln("Depth is: ",depth);
if (++depth < maxDepth){
pool.put( task!simpleWorker(depth,maxDepth,pool));
}
}
void main(){
auto pool = new TaskPool();
auto t = task!simpleWorker(0,5,pool);
pool.put(t);
pool.finish(true);
if (t.done()){ //rethrows the exception thrown by the thread.
writeln("Done");
}
}
I fixed it: http://dpaste.dzfl.pl/eb9e4cfc
I changed to for loop to:
void cleanNodeSimple(Node node, TaskPool pool){
node.doProcess();
foreach (cli; pool.parallel(node.clients,1)){ // using parallel to make it concurrent
if (cli.canProcess()) {
cleanNodeSimple(cli, pool);
// no explicit task creation (already handled by parallel)
}
}
}
When I analyse code coverage in Visual Studio 2012, any of the await lines in async methods are showing as not covered even though they are obviously executing since my tests are passing. The code coverage report says that the uncovered method is MoveNext, which is not present in my code (perhaps it's compiler-generated).
Is there a way to fix code coverage reporting for async methods?
Note:
I just ran coverage using NCover, and the coverage numbers make a lot more sense using that tool. As a workaround for now, I'll be switching to that.
This can happen most commonly if the operation you're awaiting is completed before it's awaited.
I recommend you test at least synchronous and asynchronous success situations, but it's also a good idea to test synchronous and asynchronous errors and cancellations.
The reason the code is not shown as being covered has to do with how async methods are implemented. The C# compiler actually translates the code in async methods into a class that implements a state machine, and transforms the original method into a stub that initialized and invokes that state machine. Since this code is generated in your assembly, it is included in the code coverage analysis.
If you use a task that is not complete at the time the code being covered is executing, the compiler-generated state machine hooks up a completion callback to resume when the task completes. This more completely exercises the state machine code, and results in complete code coverage (at least for statement-level code coverage tools).
A common way to get a task that is not complete at the moment, but will complete at some point is to use Task.Delay in your unit test. However, that is generally a poor option because the time delay is either too small (and results in unpredictable code coverage because sometimes the task is complete before the code being tests runs) or too large (unnecessarily slowing the tests down).
A better option is to use "await Task.Yield()". This will return immediately but invoke the continuation as soon as it is set.
Another option - though somewhat absurd - is to implement your own awaitable pattern that has the semantics of reporting incomplete until a continuation callback is hooked up, and then to immediately complete. This basically forces the state machine into the async path, providing the complete coverage.
To be sure, this is not a perfect solution. The most unfortunate aspect is that it requires modification to production code to address a limitation of a tool. I would much prefer that the code coverage tool ignore the portions of the async state machine that are generated by the compiler. But until that happens, there aren’t many options if you really want to try to get complete code coverage.
A more complete explanation of this hack can be found here: http://blogs.msdn.com/b/dwayneneed/archive/2014/11/17/code-coverage-with-async-await.aspx
There are situations where I don't care about testing the async nature of a method but just want to get rid of the partial code coverage. I use below extension method to avoid this and it works just fine for me.
Warning "Thread.Sleep" used here!
public static IReturnsResult<TClass> ReturnsAsyncDelayed<TClass, TResponse>(this ISetup<TClass, Task<TResponse>> setup, TResponse value) where TClass : class
{
var completionSource = new TaskCompletionSource<TResponse>();
Task.Run(() => { Thread.Sleep(200); completionSource.SetResult(value); });
return setup.Returns(completionSource.Task);
}
and the usage is similar to the Moq's ReturnsAsync Setup.
_sampleMock.Setup(s => s.SampleMethodAsync()).ReturnsAsyncDelayed(response);
I created a test runner that runs a block of code multiple times and varies the task that is delayed using a factory. This is great for testing the different paths through simple blocks of code. For more complex paths you may want to create a test per path.
[TestMethod]
public async Task ShouldTestAsync()
{
await AsyncTestRunner.RunTest(async taskFactory =>
{
this.apiRestClient.GetAsync<List<Item1>>(NullString).ReturnsForAnyArgs(taskFactory.Result(new List<Item1>()));
this.apiRestClient.GetAsync<List<Item2>>(NullString).ReturnsForAnyArgs(taskFactory.Result(new List<Item2>()));
var items = await this.apiController.GetAsync();
this.apiRestClient.Received().GetAsync<List<Item1>>(Url1).IgnoreAwait();
this.apiRestClient.Received().GetAsync<List<Item2>>(Url2).IgnoreAwait();
Assert.AreEqual(0, items.Count(), "Zero items should be returned.");
});
}
public static class AsyncTestRunner
{
public static async Task RunTest(Func<ITestTaskFactory, Task> test)
{
var testTaskFactory = new TestTaskFactory();
while (testTaskFactory.NextTestRun())
{
await test(testTaskFactory);
}
}
}
public class TestTaskFactory : ITestTaskFactory
{
public TestTaskFactory()
{
this.firstRun = true;
this.totalTasks = 0;
this.currentTestRun = -1; // Start at -1 so it will go to 0 for first run.
this.currentTaskNumber = 0;
}
public bool NextTestRun()
{
// Use final task number as total tasks.
this.totalTasks = this.currentTaskNumber;
// Always return has next as turn for for first run, and when we have not yet delayed all tasks.
// We need one more test run that tasks for if they all run sync.
var hasNext = this.firstRun || this.currentTestRun <= this.totalTasks;
// Go to next run so we know what task should be delayed,
// and then reset the current task number so we start over.
this.currentTestRun++;
this.currentTaskNumber = 0;
this.firstRun = false;
return hasNext;
}
public async Task<T> Result<T>(T value, int delayInMilliseconds = DefaultDelay)
{
if (this.TaskShouldBeDelayed())
{
await Task.Delay(delayInMilliseconds);
}
return value;
}
private bool TaskShouldBeDelayed()
{
var result = this.currentTaskNumber == this.currentTestRun - 1;
this.currentTaskNumber++;
return result;
}
public async Task VoidResult(int delayInMilliseconds = DefaultDelay)
{
// If the task number we are on matches the test run,
// make it delayed so we can cycle through them.
// Otherwise this task will be complete when it is reached.
if (this.TaskShouldBeDelayed())
{
await Task.Delay(delayInMilliseconds);
}
}
public async Task<T> FromResult<T>(T value, int delayInMilliseconds = DefaultDelay)
{
if (this.TaskShouldBeDelayed())
{
await Task.Delay(delayInMilliseconds);
}
return value;
}
}
We are developing a WPF application using TDD. As we're already working on this solution for almost two years, we've written a huge bunch of tests (almost 2000 Unittests right now).
There are some classes, that need to implement functionality multithreaded and asynchronously. For example a communication-component that can both send and receive messages and parse them. The dependencies are always mocked using RhinoMocks.
Our Test-Methods targeting these classes look very similar, as following:
[TestMethod]
public void Method_Description_ExpectedResult(){
// Arrange
var myStub = MockRepository.GenerateStub<IMyStub>();
var target = new MyAsynchronousClass(myStub);
// Act
var target.Send("Foo");
Thread.Sleep(200);
//Assert
myStub.AssertWasCalled(x => x.Bar("Foo"));
}
As you can see, this test runs at least for 200 ms due to the Thread.Sleep(). We optimized the test replacing the AssertWasCalled with a active polling method, s.th. like this:
public static bool True(Func<bool> condition, int times, int waitTime)
{
for (var i = 0; i < times; i++)
{
if (condition())
return true;
Thread.Sleep(waitTime);
}
return condition();
}
We can now use this WaitFor.True(...) Method by changing the AssertWasCalled to:
var fooTriggered = false;
myStub.Stub(x => x.Bar("Foo")).Do((Action)(() => fooTriggered = true)));
WaitFor.True(() => fooTriggered, 20, 20);
Assert.IsTrue(fooTriggered);
This construct will terminate earlier if the condition matches, but anyway - this takes too long for us. Running all of our 2000 Tests need about 5 Minutes (building and running them).
Is there any smart trick how we could optimize code like this?
You can use a monitor. I'm making this up so please excuse me if it isn't quite compiling, but it'll look something like:
[TestMethod]
public void Method_Description_ExpectedResult(){
// Arrange
var waitingRoom = new object();
var myStub = MockRepository.GenerateStub<IMyStub>();
myStub.Setup(x => x.Bar("Foo")).Callback(x =>
{
Monitor.Enter(waitingRoom);
Monitor.Pulse(waitingRoom);
Monitor.Exit(waitingRoom);
}
var target = new MyAsynchronousClass(myStub);
// Act
Monitor.Enter(waitingRoom);
target.Send("Foo");
Monitor.Wait(waitingRoom);
Monitor.Exit(waitingRoom);
//Assert
myStub.AssertWasCalled(x => x.Bar("Foo"));
}
Code written within the Monitor can't run until it's free. The test will cause the acting thread to wait until Monitor.Wait has been called. Then the callback can enter and pulse the Monitor. The test then "wakes up", and once the callback has exited the monitor, it gets control back and exits too, allowing you to Assert.
The only thing I haven't covered is that if Bar("Foo") doesn't get called it will hang, so you might want to have a timer pulse the thread too.
You can create a class which does the complex monitoring bits for you if you use it a lot. This is one I wrote to deal with asynchronous checks in UI automation; adapting it for what you're doing might help you.
I'm having a very frustrating problem. I have a c# win application. When I have clicked the button, the program closes itself after executed the click event handler. Even if I have debugged the code unfortunately I can't see any error, It just quits the program.
Where am I going wrong?
Here is the Code:
private void btnOpenFolder_Click(object sender, EventArgs e)
{
DialogResult dg = fd1.ShowDialog();
if (dg == DialogResult.OK)
{
lblInput.Text = fd1.SelectedPath;
btnOpenFolder.Enabled = false;
timerCallback = new TimerCallback(tmrQualityEvent);
tmrQuality = new System.Threading.Timer(timerCallback, null, 0, 1000);
Thread qualityThread = new Thread(new ThreadStart(QualityMapOpenFolder));
qualityThread.Start();
QualityMapOpenFolder();
}
}
void QualityMapOpenFolder()
{
fileList.Clear();
string path = lblInput.Text;
if (Directory.Exists(path))
{
foreach (var file in Directory.GetFiles(path))
{
if (Path.GetExtension(file) != ".kml")
{
fileList.Add(file);
}
}
SetProgressBarValue(0);
ChangeFileNameLabel(fileList[0]);
FileName = fileList[0];
}
else
SetText("Please make sure you have correctly set the open folder path!", true);
dataListQuality = GetInputData();
SetText("Calculated Data has been created, please click process files...", false);
SetProcessButtonStatus(true);
}
Attach an event handler to the UnhandledException handler and log it. Should help you to find out why your application is crashing.
Update: Now that you have posted some code:
You seem to update UI elements from another thread which you start. You should access UI components only from the thread on which they were created (usually the main thread). Consider using a BackgroundWorker
You start the QualityMapOpenFolder method on a thread and then you also call it after you started the thread - this seems a bit weird and has probably some unexpected side effects.
The common reason for this kind of behavior is unhandled exception in background thread. To prevent program.
#ChrisWue wrote on how to detect this kind of exceptions.
Also, often Windows Application log provides an insight on unhandled errors.
See here how to prevent killing app in this case.