End-to-end Integration tests for Web Api

Recently I was looking at the NancyFx framework, what found I liked most about the whole thing was the Nancy.Testing library. It allows you to not just test the code inside your API, but actually make the request to the Url, with any headers, body or whatever with it. This means you are testing everything. You can ensure you are sending back the right status codes, content types and that you are handling authorization correctly.

To do this in Nancy, the code looks something like:

 

[TestMethod]
public void GetEmployeesExpectOK()
{
    var bootstrap = new ConfigurableBootstrapper(c => c.Module<EmployeeModule>());
    var browser = new Browser(bootstrap);

    BrowserResponse response = browser.Get("/Employees/", with =>
    {
        with.HttpRequest();
        with.Header("Accept", "application/json");
    });

    Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}

 

As you can see here, you create a “Browser” and use it to request at the specified route. Pretty cool. This was particularly useful for adding some automated acceptance tests for your application – as it allows us to tests all the way from an API request, down to the data storage and back out again. However, we were not using NancyFx for our API, we were using ASP.Net Web API instead – so we needed to replicate this way of testing.

Happily a library exists which allows you to implement tests this way for Web API. This is called WebApi.Testing (http://www.nuget.org/packages/WebAPI.Testing/). The code is very similar, except there are some flaws.

 



[TestMethod]
public void GetEmployeesExpectOK()
{
    var config = new HttpConfiguration();
    config.MapHttpAttributeRoutes();
    config.Routes.MapHttpRoute(
    name:"DefaultApi",
    routeTemplate:"api/{controller}/{id}",
    defaults:new{ id =RouteParameter.Optional});

    Browser browser = new Browser(config);var response = browser.Get("/Employees/",(with)=>
    {
        with.Header("Accept","application/json");
        with.HttpRequest();
    });
    Assert.Equals(HttpStatusCode.OK, response.StatusCode);
}

What I don’t like about this is that we have to re-define the routes for the API project, so we’re not really testing the real routes from our application, which is a shame. The solution we found was to edit the WebApiConfig in the API project, so we can get the routes from out test, like so:


public static void Register(HttpConfiguration config) 
{ 
    // Setup Web API configuration routes 
    config = GetConfig(config); 
} 

//This is added so we can return the HttpConfiguratio
public static HttpConfiguration GetConfig(HttpConfiguration config) 
{ 
    config.MapHttpAttributeRoutes(); 

    config.Routes.MapHttpRoute( 
    name: "DefaultApi", 
    routeTemplate: "api/{controller}/{id}", 
    defaults: new { id = RouteParameter.Optional } 
    ); 

    return config; 
}

Then in the test class:


[TestMethod]
public void GetEmployeesExpectOK()
{
    var config = ApiProject.WebApiConfig.GetConfig(new HttpConfiguration()); //Get the routes from API project
    var browser = new Browser(config); 
    var response = browser.Get("/Employees/", (with) => 
    { 
        with.Header("Accept", "application/json"); 
        with.HttpRequest(); 
    }); 

    Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
}

As you can see here, we just get the route configuration from the application and use it in the test, and now we are testing the routes too.

Writing a Prezi clone with HTML5, SVG, and Javascript

Aditya Bhatt

The idea

The other day, I took it upon myself to write a browser-based Prezi-like app without using flash. Condition: It should run purely client-side.

It was also an experiment in evaluating whether the current APIs available in modern browsers are enough to handle the task. What follows is an account of what works, what doesn’t, and what could be done better.

SVG vs Canvas

When you’re building a rich graphics-intensive app like Prezi, you usually have two ways of rendering content: SVG and Canvas.

1. SVG provides a neat DOM that can be manipulated with existing DOM handling javascript libraries, such as jQuery. Canvas, on the other hand, is just a bitmap buffer. This means that you have to program your own DOM-like scene graph if you wish to use Canvas for handling presentation elements. Libraries for this already exist – most notably, fabric.js, but none…

View original post 963 more words

The SpecFlow Chronicles – Volume 1 : Turning Tests Into Living Documentation

Tester Vs Computer

As I mentioned in last week’s post, part of my focus is to help my team increase its capabilities in the area of test automation.  We would like to increase the scope of our automation and, in particular, we would like to increase the level of collaboration between developers and black-box QA in implementing and maintaining the tests.

Some of the challenges that we’re currently facing:

  • Many black box testers lack the automation experience needed to automate the tests that they want to automate
  • Developers don’t know what the testers want to automate
  • The tests that are currently being run are not transparent to the business side
  • Existing test automation is not being maintained or exploited because it’s only well-understood by those that implemented it

Over the past few months, my team has been playing with an open-source tool called SpecFlow as we try to address these challenges.

What…

View original post 788 more words

More Than Just ‘Passing’ the Sprint

When running a SCRUM process you will have a product backlog with a list of items. Each of theses items will be sized at a planning meeting before they are brought onto a sprint iteration. All pretty standard. The point I would like to talk about is the sizing. Sizing is for everything. The design, the coding, the testing and whatever else you have to do. This means if you do not test the code then that item is not completed.

The problem

A situation arose once where a bunch of code was written to satisfy a product backlog item but it arrived late on the last day of the sprint cycle, no manual testing was done. This was handled not by declaring the backlog item unfinished but by carrying the testing work through to the next sprint as a new item – so it appeared the item had been completed.

The problem with this is not that work was not completed, or that work was carried forward. This happens, it’s fine. The issue is firstly with calling untested work ‘done’ and secondly the de-coupling of the coding with the testing. By doing this you sacrifice collaboration between the developer and tester – this should not happen. Collaboration is key to agile.

What’s the motive?

In my opinion it’s down to the fear of ‘failing’. But what really fails? Ultimately, what we want to achieve is creating great software. Agile/SCRUM are enablers for this. ‘Failing’ a sprint iteration because some work is incomplete does  not mean you fail to create great software effectively. It just means this time round, things didn’t go perfectly (when does it?), and one feature will be slightly later than expected . By measuring the success of your software based on the number of times you get a green tick next to the sprint, you’re likely to fall into some traps. Like in this example where you have had to fudge the principles in order to get ‘results’. Ultimately here you’re sacrificing your software in order for the audits to read well. To me, that’s a huge loss of sight on what’s really important – The software being the best it can be.

The Solution

The SCRUM guide states:

“All incomplete Product Backlog Items are re-estimated and put back on the Product Backlog. The work done on them depreciates quickly and must be frequently re-estimated.”

So there’s your answer. It’s the same backlog item. You re-estimate it. If part of the work is done (yes, that means its tested), then it is likely to be smaller next time around.

To me the solution is to also not to get too hung up ‘passing’ a sprint. If you tinker with the results just to get a result in the now then you will most likely never get a good grasp on your team’s velocity and find yourself in the same situation many more times.

Themes for MVC Views

If you have a MVC application and you wish to be able to configure it to use different views or .css, here is how.

Create the configuration

First things first. You’ll need to set somewhere the configuration which defines which of your themes to use. This part is dependent on what you are trying to achieve. When I used this method, my intentions where to provide some slightly different looking pages to be used when the application was deployed in an iFrame as opposed to when it ran on its own. So, for this purpose I just stuck a setting in the application’s web.config file. Like, so

<appSettings>
<add key="Theme" value="Default_Theme"/>
</appSettings>

Place your themed views into folders

The Next thing to do will be to place your views into sub-folders that are categorised by their theme. Here you will require one folder for “Default” views. In this folder you will need a full set of views (i.e. it has all pages required for the application). All subsequent theme folders will only need a page where it requires a different from the default. By which I mean, if your controller looks up a view and can’t find the file in your configured theme it will fall back and use the related default theme.

ThemeViewFolders

Create your custom RazorViewEngine

The next step is to use your configuration to display the set of views you want.

The standard RazorViewEngine will Get your razor views from the folder structure of “Views/Subfolder/page.cshtml”. However, now we have placed our views a layer down in the folder structure. We could, of course, explicitly define our path as “Views/Theme1/Subfolder.page.cshtml” everywhere but for obvious reasons this can get messy! There is another way, and that is to create a custom RazorViewEngine class. To do this you’ll need to add the following code to your application:


public class ThemedRazorViewEngine : RazorViewEngine
{
   public ThemedRazorViewEngine(string themeName)
   {
       const string defaultThemeName = "Default_Theme";

       MasterLocationFormats = new string[]
       {
        "~/Views/" + themeName + "/Shared/{0}.cshtml",
        "~/Views/" + defaultThemeName + "/Shared/{0}.cshtml",
       };

       PartialViewLocationFormats = new string[]
       {
         "~/Views/" + themeName + "/{1}/{0}.cshtml",
         "~/Views/" + themeName + "/Shared/{0}.cshtml",
         "~/Views/" + defaultThemeName + "/{1}/{0}.cshtml",
         "~/Views/" + defaultThemeName + "/Shared/{0}.cshtml"
       };

       ViewLocationFormats = new string[]
       {
         "~/Views/" + themeName + "/{1}/{0}.cshtml",
         "~/Views/" + themeName + "/Shared/{0}.cshtml",
         "~/Views/" + defaultThemeName + "/{1}/{0}.cshtml",
         "~/Views/" + defaultThemeName + "/Shared/{0}.cshtml"
       };
    }
}

And then add the following two statements in your global.asax in the Applicaton_Start() method to register your custom view engine:


// Gets the theme name from the web.config
string themeName = ConfigurationManager.AppSettings["Theme"];
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new ThemedRazorViewEngine(themeName));

Using a seperate CSS file

As well as altering the layout of your views, you may also wish to apply alternate CSS to your themed views. The infrastructure for doing this is almost there, using the above. All you’ll have to do is create a new _Layout.cshtml file in the folder for your new theme, which renders the desired CSS.

The layout can look almost the same as what you had in your default theme (unless you desire otherwise), except you will need to choose which style you render. For example , by default your _Layout.cshtml will have the following line:

@Styles.Render("~/Content/css")

If you have placed your alternate CSS file in a seperate folder then you will need to replace this with something like:

@Styles.Render("~/Content/Themes/New_Theme/css")

Or if you wish to re-use the existing CSS but add some extra/specific stuff to it you can just choose to render the additional file, like:

 @Styles.Render("~/Content/css")
 @Styles.Render("~/Content/Themes/New_Theme/style.css")

I hope this helps!

Safe Environment For Your Agile Team

 

Creating a safe, enjoyable yet productive team happy can be tricky. Yes we all want everybody smiling at happy whilst at work but what if you think an individual or a team are not pulling their weight? or they are not following what you believe to be the process?

Finger Pointing

One method of raising such an issue I am adamant you should not doing is just to point the finger and blame that individual or team outright, especially in a group and definitely not at the retrospective. But isn’t that what the retrospective is for? I’m not say do not raise issues at your retrospective, I am saying do not make  people feel uncomfortable or unhappy in it.

How It Feels

Imagine going into work feeling down, your childhood pet has just died, or you just lost £1000 in a casino on the weekend. How productive would you feel when you’re feeling down? Let me tell you the answer is: not very productive at all. Directly calling someone out in a group of people is only going to make them feel worse (if, indeed, they were actually bad to begin with).

Are They Really a Problem?

First ask yourself: what actually is it they are doing wrong? Is it just that they generally don’t seem good at their job? If you can’t think of a specific thing they’re doing wrong, the problem is entirely your own. Grow up. If however, it is one thing you dislike about their work then speak to them, like a human being. Let’s say, for example, they are not (in your opinion) giving detailed enough check-in or code comments. Fair enough, its a small issue that is easily corrected.

What Should I Do?

In this example, check what others are doing first. It may be that they give just as much detail as everyone else but for some reason you have singled out this person. Grow up. Your point may, however, still be valid, It may be that everyone should step it up on the detail. That’s fine, raise it at the retrospective. Just say “hey guys, I like to give this much detail on my check-ins. Do you think its beneficial?”. That’s great, its constructive, you’ve not offended anyone and you have actually questioned your own process – so nobody will feel uncomfortable. If , however,  the person is alone in this then just speak to them. Wait for a good opportunity, perhaps the next time you pair on something and you’re about to check-in together. Just say “I like to give this much detail on my check-ins. Which I think is beneficial because of…..”. Once again you’ve not offended anyone, they have seen your point of view and if they disagree they will call you on it and you can have the conversation. If you have set them a good example, they will follow.

Don’t Invent Your Own Rules of Judgement

One thing to remember when you come across issues such as this is to make sure the issue is really an issue in the teams’ eyes. Whenever you think somebody is doing something incorrectly then make sure that is a rule made by (and agreed to) by the team. Just because you believe it should be done one way, does not make it so. Never criticize anyone for doing their work a particular way if it has never been agreed on to do it differently.

Retrieve assigned GUID from SQL insert

When inserting into a Sql table with a Guid assigned using the default of NEWID() you cannot use ‘SCOPE_TO_IDENTITY’ to return the Guid you’ve been assigned into you application (like you would to retrieve an integer ID). It doesn’t work for Guids because they’re not number values and thus cannot be an identity field. The answer was to retrieve the Guid using the following query, for a table that has a column name TableNameGuid and ColumnName:


INSERT INTO TableName (ColumnName)
OUTPUT inserted.TableNameGuid
VALUES (Value)

The key part to this is the OUTPUT, its what returns the value. Then in the C# code I would call something like


using (SqlCommand cmd = new SqlCommand(yourSqlQueryString, connection))
{
     connection.open();
     Guid assignedGuid = (Guid)cmdCheck.ExecuteScalar(); //gets the guid
     connection.Close();
}

Which assigns your new, freshly created, Guid to the variable assignedGuid.