Friday, October 15, 2010

Asynchronous Silverlight Unit Tests

So, after beginning to do some unit testing of View Models in Silverlight, I discovered that there have not been that many articles written about how to do this. Fortunately, I did find http://www.jeff.wilcox.name/2009/03/asynchronous-testing/ but other than that, most of what I have learned has been by trial and error. Therefore, here are my findings. Hopefully this will help someone else.


1. "Asynchronous" is a bit of a misnomer. Think of all of the "Enqueue" commands as "Do this later". In traditional asynchronous processing, if you fire off something like an "EnqueueConditional" command, it will fire off a new thread that will begin executing immediately. This is not the case with the Silverlight unit tests. Here is what I did as an example:


[TestMethod]
[Asynchronous]
[Description("Whatever")]
public void TestMethod()
{
int x = 0;
EnqueueConditional(() => x == 2);
EnqueueCallback(() => { method1(); });
x = 1;
EnqueueConditional(() => x == 1);
EnqueueCallback(() => { method2(); });
x = 2;
EnqueueTestComplete();
}


Now, what I would expect would be that method2 would be called before method1. After all, x == 1 as soon as the 2nd condition is enqueued. However, as I said earlier "Enqueue" should be thought of as "do this later". Therefore, what actually will happen is that method1 will be called (because at the end of the method's synchronous processing x == 2), and method2 will never be called (because x != 1 ever again in the method - also, this will never get to the TestComplete, and so will be an infinite test, just so you're warned).



2. "EnqueueConditional" basically means "wait until". This seems to be the most important piece of the processing. This is the key that will allow you to ensure that a condition is met. After this happens, all of the EnqueueCallbacks (including EnqueueTestComplete) are executed until the new "EnqueueConditional", which will then perform another wait until the condition is completed.


3. "EnqueueCallback" just allows code to be done later. The "later" is driven based off of the EnqueueConditionals. Consider the following code snippet:


[TestMethod]
[Asynchronous]
[Description("TestMethod2")]
public void TestMethod2()
{
int x = 0;
EnqueueCallback(() => x = 2);
x = 1;
EnqueueConditional(() => x == 2);
EnqueueTestComplete();
}


In this situation, the EnqueueCallback has nothing that it has to wait on, but since it is an "EnqueueCallback", it will not execute until the end of the method. It will function the same as if I had written the code this way:


[TestMethod]
[Asynchronous]
[Description("TestMethod2")]
public void TestMethod2()
{
int x = 0;
x = 1;
EnqueueConditional(() => x == 2);
EnqueueTestComplete();
x = 2;
}

Wednesday, September 1, 2010

The Importance of Unit Testing

So, a while back, a friend and I started working on developing a game in a new language, mainly as a means of learning that language. Because of this, it didn't really matter how well the code was written, or if we tested it all that thoroughly. However, once our code seemed pretty stable, we decided to go ahead and open it up to the Open Source community. At this point, we started getting reports of some weird errors that we had never seen.

As it turns out, we had tested our game within the confines of what "normally" happens in a game, and in those situations, everything worked out fine. What we did not test is what happens when something "abnormal" happens, ie, the game runs out of money, the game is especially high scoring, etc. Now, of course, these do not often happen - in fact, we did not even think about them. Also, since we simply had a stack trace, it was at first confusing to try to hunt these bugs down, as the piece of code looked correct. Had we written unit tests to test both positive and negative test conditions, then theoretically, we would have caught this and our users wouldn't have had to report it. Realistically, however, you can't catch everything. Needless to say, there are unit tests for these conditions now.

Friday, July 30, 2010

REST Services in WCF and ASP.NET MVC

So, recently my team has started a project with a large base of legacy code, causing us to switch from the Java world, in which we have a large amount of experience to the .NET world in which we are much more limited. In doing this, one of the first things we needed to determine was how we were going to create Web Services, and if they were going to be in REST or SOAP. After some banter about SOAP and REST, we decided to use REST for now, delivering the responses in JSON. The next obvious question was, how are we going to implement the REST services. Here are the two ways that we have gotten them implemented so far:

ASP.NET MVC:
To do this, we simply created a new ASP.NET MVC 2 Application. From here, it was a simple matter of adding a Controller to the Controllers folder, and viola, we had a REST Service. The next thing we had to do was to make it return the response in JSON. This was another fairly simple matter, and eventually, we had a method returning an "ActionResult" and ending with this line:


return Json(result, JsonRequestBehavior.AllowGet);


We were disappointed that result had to be an actual object instead of a dynamic object, however (unless we just haven't figured out how to get around that).

We did run into a couple of lessons on this, though:

1. This works great with IIS 7 (and much less great with anything before it). To get around this, we have used wildcard extensions for now. If you are getting 404 errors when trying to hit your Controllers in IIS, but everything works while debugging, Google this, as it will help.

2. Our controller's method really likes being called "Index". I'm sure there's a configuration where we can change this, but we have realized that configurations can be hard to find in .NET.

3. When deploying, there seem to be a large number of files that are always necessary, instead of neatly bundling into a single artifact.




WCF:
To create a service in WCF is just as simple as creating one in MVC. Just create a new WCF project, and *poof* you have a Web Service. Unfortunately, it's SOAP. To get around this, you have to perform some configuration of your Web.config file. I don't understand all of it, but in the end, this is what I came up with that worked for ours (note that this is just the Services and Behavior tags inside of the system.serviceModel tag - this is not the whole file):



<services>
<service name="RestLayerInWCF.Service1">
<endpoint
behaviorConfiguration="webby" binding="webHttpBinding" bindingConfiguration=""
name="Rest" contract="RestLayerInWCF.IService1" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="webby">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>



Also, we had to mark our services with an extra line:


[WebGet(UriTemplate = "/", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = System.ServiceModel.Web.WebMessageFormat.Json)]


We had some observations about this one, too:

1. The Web.config is a pain to figure out the first time.

2. You have to maintain both an Interface and an implementation of each Service.

3. You seem to have to type the .svc to navigate to the service instead of having the freedom to name your service whatever you want.

4. An interesting thing we noticed is that the return of JSON is smarter than I thought. I had a problem here where my method signature returned a string, and so I was converting things to Json to return. This caused them to all return the quotes as \". Instead, I should have just let the method "do it's thing" and return the original object - it converts it to Json for me.

Anyway, now we have the tough decision to make - which one are we going to use? I have no idea....

Wednesday, August 5, 2009

Dangers of setTimeout in Flex

So, after fighting a memory leak in Flex for the last week, I have learned a valuable lesson that hopefully will help. The setTimeout method in Flex is dangerous. It turns out that it is not automatically garbage collected when your Flex app is in operation (indeed, I don't even know of a manual way to force it to be garbage collected). Here was my situation:

I needed a clock that would increment itself every second. To do this, I created a little method called runClock that simply updated the time on the clock face and then had a setTimeout(1000, runClock). Without realizing what I had done, I was now creating a new Object every second that was never reclaimed by the Flex garbage collection process.

What I should have done (and what I now have) is a Timer. I have simply set my Timer to fire every 1000 ms, to call runClock and to run indefinitely. Problem solved and memory leak patched!

Friday, June 19, 2009

A Pragmatic look at the Groovy-ness of Groovy

So, now that I've been familiar with Groovy for a while, I figured that I would post a blog about my opinions of it from a pragmatic perspective.

First off, I think that Groovy is an awesome language, and development in it allows code to be much more streamlined, and it is wonderful to finally be able to give up on some of the nuisances of Java. My favorite part is the ?, but I also enjoy only writing try-catches when I actually intend to catch an Exception, not writing getters and setters, and the metaClass ability is like finding a superpower. However, life is not all good in Groovy-land.

There is another tool in my development arsenal that is at least as powerful as Groovy, and which also enhances my development speed. This tool is code complete. Unfortunately, these two tools are currently mutually exclusive. I know that Groovy is dynamic, but when I specifically set a variable type declaration, you would think that my IDE should at least be able to kick into Java mode and tell me what the methods of String are without me having to type them manually or look up the oft-forgotten ones in the JDK. But lo and behold, it appears that none of the IDEs have found a way around this hicup yet.

The grand conclusion! Again - I like Groovy. But in a real world environment, before I develop a new class, I have to look at which tool will help me develop my code faster and maintain it more easily in the long run. So far, it appears that the main purpose of Groovy in my life will be to writing very brief classes, writing unit tests, and working with XML. Hopefully my IDEs will develop, and I'll be able to use both of these tools at the same time sometime in the near future.

Tuesday, November 11, 2008

Spherical Mercator - Because the World Really is Flat

So, recently I have been working with OpenLayers and KML, just learning each of the technologies, and I discovered something odd. When I added a KML path as a Layer on my OpenLayers, my path liked to move around. No matter where the map was centered, the path was in the same place in the window. That is when I started investigating spherical mercator. Its not too tough to add, and it will quickly fix this problem. Basically, what is happening is that your map is round, but your KML is flat. You will need to fix this by making both of them flat.

Here are the basics that you need:

var map = new OpenLayers.Map(('map'),
{projection: new OpenLayers.Projection("EPSG:900913"), displayProjection: new OpenLayers.Projection("EPSG:4326"), units: "m",
maxExtent: new OpenLayers.Bounds(-20037508, -2003750, 20037508, 20037508.34)});

var mapService = new OpenLayers.Layer.Google( "Google", { sphericalMercator: true, type: G_PHYSICAL_MAP } );

map.addLayer(mapService);

map.addLayer(new OpenLayers.Layer.GML("KML",
"http://youraddress/kmlFile.kml",
{projection: map.displayProjection,
format: OpenLayers.Format.KML,
formatOptions: {extractStyles: true,
extractAttributes: true}}));

Once you've added this, now your path (or whatever KML you want to use) should stay in place, and you're done.