How to ignore user code when breaking to point of failure in test? - visual-studio-2010

I've created a significant number of methods to help me perform unit test assertions in Visual Studio 2010. I've also enabled "Double-click a Failed or Inconclusive unit test result displays the point of failure in the test" option in the Test Execution options. My issue is that with these helper methods, I'd like the point of failure to be the stack frame calling my helper method, not the exception being thrown within the helper method.
Obviously, I can do "ShowDetails" and click higher in the stack, but that will pretty much cancel out any time saved by using the helper method.
I've tried using the various [Debugger*] attributes on my method without success.
Here's some example code to illustrate my issue.
public void MyTest()
{
// ACT
var res = DoSomething();
// ASSERT
AssertDateRange(res, TimeSpan.FromDays(7));
}
public static void AssertDateRange(DateTime value, TimeSpan range)
{
var difference = DateTime.Now.Subtract(value);
if (Math.Abs(range.TotalMilliseconds) - Math.Abs(difference.TotalMilliseconds) < 0)
{
throw new AssertFailedException("DateTime was not within the expected range from now.");
}
}
I'd like for the double-click to place me on the method call within the MyTest method, while it now places me on the throw within the AssertDateRange method.

Related

Why use Device.BeginInvokeOnMainThread() in a Xamarin application?

My code looks like this:
public void Init() {
if (AS.pti == PTI.UserInput)
{
AS.runCardTimer = false;
}
else
{
AS.runCardTimer = true;
Device.BeginInvokeOnMainThread(() => showCards().ContinueWith((arg) => { }));
}
}
The Init method is called from the constructor. Can someone please explain to me why the developer might have added the Device.BeginInvokeOnMainThread() instead of just calling the method showCards?
Also what does the ContinueWith((arg)) do and why would that be included?
The class where this Init() method is might be created on a background thread. I'm assuming showCards() are updating some kind of UI. UI can only be updated on the UI/Main thread. Device.BeginInvokeOnMainThread() ensures that the code inside the lambda is executed on the main thread.
ContinueWith() is a method which can be found on Task. If showCards() returns a task, ContinueWith() makes sure the task will complete before exiting the lambda.
UI actions must be performed on UI thread (different name for main thread). If you try to perform UI changes from non main thread, your application will crash. I think developer wanted to make sure it will work as intended.
The simple answer is: Background thread cannot modify UI elements because most UI operations in iOS and Android are not thread-safe; therefore, you need to invoke UI thread to execute the code that modifies UI such MyLabel.Text="New Text".
The detailed answer can be found in Xamarin document:
For iOS:
IOSPlatformServices.BeginInvokeOnMainThread() Method simply calls NSRunLoop.Main.BeginInvokeOnMainThread
public void BeginInvokeOnMainThread(Action action)
{
NSRunLoop.Main.BeginInvokeOnMainThread(action.Invoke);
}
https://developer.xamarin.com/api/member/Foundation.NSObject.BeginInvokeOnMainThread/p/ObjCRuntime.Selector/Foundation.NSObject/
You use this method from a thread to invoke the code in the specified object that is exposed with the specified selector in the UI thread. This is required for most operations that affect UIKit or AppKit as neither one of those APIs is thread safe.
The code is executed when the main thread goes back to its main loop for processing events.
For Android:
Many People think on Xamarin.Android BeginInvokeOnMainThread() method use Activity.runOnUiThread(), BUT this is NOT the case, and there is a difference between using runOnUiThread() and Handler.Post():
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);//<-- post message delays action until UI thread is scheduled to handle messages
} else {
action.run();//<--action is executed immediately if current running thread is UI thread.
}
}
The actual implementation of Xamarin.Android BeginInvokeOnMainThread() method can be found in AndroidPlatformServices.cs class
public void BeginInvokeOnMainThread(Action action)
{
if (s_handler == null || s_handler.Looper != Looper.MainLooper)
{
s_handler = new Handler(Looper.MainLooper);
}
s_handler.Post(action);
}
https://developer.android.com/reference/android/os/Handler.html#post(java.lang.Runnable)
As you can see, you action code is not executed immediately by Handler.Post(action). It is added to the Looper's message queue, and is handled when the UI thread's scheduled to handle its message.

visual studio web test error handling

I'm using Visual Studio Ultimate 2013 and have a load test that uses a web test with a number of request and web test plugins.
In my PostRequest plugin, I'm checking the http status code of the response and am flagging an error in a WebTest.Context parameter, when a hhtp code of over 400 is returned. What I want to do is pick this up in the PostTransaction WebTest plugin and update a database table. The problem is, that the test aborts when the framework detects the error and the PostTransaction plugin isn't called.
I've added a PostWebTest plugin, that I thought would be called when the test iteration aborted, but it's never hitting this when a request fails. It does hit it if the test is successful. What am I missing?
public override void PostRequest(object sender, PostRequestEventArgs e)
{
...
statusCode = e.Response.StatusCode.GetHashCode();
If (statusCode > 400)
{
e.WebTest.Context["TransactionFailCount"] = 1;
}
}
public override void PostTransaction(object sender, PostTransactionEventArgs e)
{
int transactionFailCount = Convert.ToInt32(e.WebTest.Context["TransactionFailCount"]);
if (transactionFailCount > 0)
failCount = 1;
else
passCount = 1;
...
base.PostTransaction(sender, e);
}
public override void PostWebTest(object sender, PostWebTestEventArgs e)
{
base.PostWebTest(sender, e);
}
Thanks
A Web Performance Test (WPT) will continue to execute after an error is detected unless the Stop on error property of the test is true. It is possible that some aspects of a the handling of a request are not performed after an error, but I have not seen any such cases.
Be careful of terminology. WPTs use "transactions" as a way of grouping several requests. The context (right click) menu of a request has an "Add transaction" entry that selects a range of items in the test to be included in that transaction. Perhaps you should be using the PostRequest or PostPage plugins rather than PostTransaction.
I recommend that you do some experiments with a simple two or three request WPT plus some simple plugins that just announce that they have been called. For example
public override void PostRequest(object sender, PostRequestEventArgs e)
{
e.WebTest.AddCommentToResult("PostRequest called for url " + e.Request.Url);
}
Additionally, there is a good explanation of how and when plugins are called in pages 32 to 44 of the Visual Studio Performance Testing Quick Reference Guide from Codeplex.
The statement statusCode = e.Response.StatusCode.GetHashCode(); is strange. The value of e.Response.StatusCode is an enum, it integer value can be obtained by casting. The GetHashCode method is not intended to get the numeric value of an enum. The statement would be better as statusCode = (int)e.Response.StatusCode; or the assign and test (note that if is used for conditionals in C#, not If) might be better as
statusCode = e.Response.StatusCode;
if ( e.Response.StatusCode >= System.Net.HttpStatusCode.BadRequest ) { ... }

Unit testing a custom control in a windows store project

I want to unit test the custom controls I create for a windows store project. Just simple things like "there is a button when X is true".
However, I can't seem to even instantiate the controls in a testing context. Whenever I try to invoke the constructor, I get an exception related to not being run in the UI context. I've also been unable to create coded UI test projects that target windows store projects.
How do I programmatically instantiate a control to test? How do I create a WinRT UI synchronization context?
How do I programmatically send "user" command events to a control?
How do I programmatically instantiate/teardown the entire application?
I've found a hacky way to make non-interactive parts work: with the function Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync.
Obvious, right? However, this still leaves open the question of how to emulate user actions.
/// Runs an action on the UI thread, and blocks on the result
private static void Ui(Action action) {
Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
CoreDispatcherPriority.Normal,
() => action()
).AsTask().Wait();
}
/// Evaluates a function on the UI thread, and blocks on the result
private static T Ui<T>(Func<T> action) {
var result = default(T);
Ui(() => { result = action(); });
return result;
}
[TestMethod]
public void SliderTest() {
// constructing a Slider control is only allowed on the UI thread, so wrap it in UI
var slider = Ui(() => new Slider());
var expected = 0;
// accessing control properties is only allowed on the UI thread, so same deal
Assert.AreEqual(expected, Ui(() => slider.Value));
}

Can you record accessed methods in Visual Studio?

I'm retroactively documenting and writing unit tests for some C# code. I would like to determine what code is actually being used and when.
In Visual Studio 2012, is there a way to record all the methods accessed and in what order while walking through specific scenarios?
You could run your application with a profiler attached, which will give you all accessed methods, call chains, counts, etc.
The Visual Studio Profiler will give you the time spent in each method, and let you inspect the call heirarchy. I don't know if it will give you the exact order they were called in though.
EDIT: Apparently attaching the profiler to a running unit test is harder in VS2012.
Are you wanting to execute a test method that make sure that a particular method on a class was invoked ? If so i dont know of a way to do it in VS alone, but you can use a mock framework to create dependency mocks and check values on them. Here is a snippet of a unit test:
[TestMethod]
public void HttpPostPrivacyPolicyFacadeSvcErrorTest()
{
var controller = ControllerHelper.GetRouteController();
controller.Session[SessionVariable.User] = new UserInfo() { UserName = Config.Data.Username };
var idmSvcMock = new Mock<IUserServiceDAO>();
var facadeSvcMock = new Mock<IFacadeSvcDAO>();
//setup the facade mock to throw exception to simulate FacadeServiceException
facadeSvcMock.Setup(x => x.SetPrivacyAcceptanceStatus(It.IsAny<UserInfo>())).Throws<Exception>();
var userCollectorMock = new Mock<IUserInfoCollector>();
userCollectorMock.Setup(x => x.GetUserInfo()).Returns(new UserInfo() { UserName = Config.Data.Username });
controller.FacadeSvc = facadeSvcMock.Object;
controller.UserServiceDAO = idmSvcMock.Object;
controller.UserCollector = userCollectorMock.Object;
controller.DefaultErrorId = "Route_errors_Unabletoprocess";
//action
var res = controller.Privacy(new FormCollection());
//assert
//make sure we go to the right controller, action, with the correct params.
res.AssertActionRedirect().ToController("Errors").ToAction("Index").WithParameter("id", "Route_errors_Unabletoprocess");
//did we call setprivacy once on the mock?
facadeSvcMock.Verify(x => x.SetPrivacyAcceptanceStatus(It.IsAny<UserInfo>()), Times.Exactly(1));
In the test above i check that SetPrivacyAcceptance was invoked once and only once on my facadeSvcMock instance. More on moq here: Moq
this block of code is actually checking how many times SetPrivacyAcceptanceStatus was invoked:
//did we call setprivacy once on the mock?
facadeSvcMock.Verify(x => x.SetPrivacyAcceptanceStatus(It.IsAny()), Times.Exactly(1));
the It.IsAny() is the one parameter to that method, so the line above says basically "For any input parameter of type UserInfo verify that we invoked SetPrivacyAcceptanceStatus exactly once."

Is there a setting in Visual Studio to raise a warning or error when a method is used that can create unhandled exceptions?

Basically at work I commonly run into code like:
double pricediff = 0.0;
if(!string.IsNullOrEmpty(someVariable.ToString()))
pricediff = Convert.ToDouble(someVariable);
Instead of something like:
double pricediff = 0.0;
Double.TryParse(someVariable, out pricediff);
Is there a setting within Visual Studio that can produce a warning whenever a method such as Convert.Double is used that can throw an exception and the method is not contained within a try{} block?
No there is not. Part of the reason why is that practically any method out there can throw an exception. It would have to issue a warning for almost every method as virtually any method can raise the following
StackOverflowException
OutOfMemoryException
Add on top of that the much more likely NullReferenceException and essentially every method would be marked as "can throw".
It would be reasonable though to create a feature that marks for explicitly thrown exceptions. VS does not have this feature but R# does (IIRC). However even that is not foolproof because you can't see through interfaces.
interface IExample {
void Method();
}
class Class1 : IExample() {
void Method() { throw new Exception(); }
}
class Class2 : IExample() {
void Method() {}
}
...
IExample v1 = ...;
v1.Method();
In this same Method may or may not throw. Whether it does or not cannot be definitively determined by static analysis in all cases.

Resources