tools, UI Testing

Resharper template for unit test method (replacing spaces in the test name with underscore sign)

Resharper live templates are great to automate repetitive work. An example of such work is unit test method. In the first part I’ll show how to create a basic template that will build the structure of a unit test. In the second one I’ll show how to make R# give a correct name to such test based on human-readable description.

Test template

Below we have an example of a test method in AAA style:

[Test]
public void when_doing_something_then_expect_something()
{
   //ARRANGE
   var x = 100;

   //ACT
   var result = this.Calculator.Sqrt(100);

   //ASSERT
   Assert.AreEqual(10, result);
}

As we can see to create a nice structure of AAA unit test we need to remember about three comment labels, attribute, correct test name. Such structure can be easily extracted as resharper live template. To do it:

1. Go to Resharper –> Templates explorer

2. In “Templates explorer” select “C#” section and click “New template”:

image

 

3. Fill in live template form – edit shortcut and content:

image

After that the new template is ready to be used. Just type the shortcut entered before, click ENTER and this is it!

image

Converting a sentence into a valid test name

Another problematic thing in writing unit tests is naming the test. We want to give self-describing names to tests. Sometime it’s a rule, to name tests like “When something then something”. This way we use a human-readable sentence in a place, where spaces between words are not allowed. Thus we are forced to replace them with underscore (‘_’) sign, or capitalize each word – both ways are highly uncomfortable and drive developers mad.

However it is possible to use resharper macros to do additional logic for template fields. We can choose a macro for each field (look at the picture of the template form). Unfortunately here is a first disappointment – there is no bult-in macro to achieve this. It’s even worse, because there is a macro called “Value of another variable, where spaces will be replaced with ‘_’”, but this one cannot be applied to the same variable (test name in our case).

 

To overcome this disadvantage it’s needed to create custom macro applied as a plugin. Below there is a code of the macro:

    [Macro("chsreplacespacewithunderscore",
            LongDescription = "Replace spaces with '_' (i.e. \"should return nothing\" into \"should_return_nothing\")",
            ShortDescription = "Replace spaces with '_'")]
    public class SpacesToUnderstrokesMacro : IMacro
    {
        public static string Evaluate(string text)
        {
            return text.Replace(" ", "_");
        }

        public ParameterInfo[] Parameters
        {
            get { return EmptyArray<ParameterInfo>.Instance; }
        }

        public HotspotItems GetLookupItems(IHotspotContext context, IList<string> arguments)
        {
            return null;
        }

        public string GetPlaceholder(IDocument document)
        {
            return "sentence with spaces";
        }

        public string EvaluateQuickResult(IHotspotContext context, IList<string> arguments)
        {
            if (context.HotspotSession == null || context.HotspotSession.CurrentHotspot == null)
            {
                return null;
            }
            var currentValue = context.HotspotSession.CurrentHotspot.CurrentValue;
            return Evaluate(currentValue);
        }

        public bool HandleExpansion(IHotspotContext context, IList<string> arguments)
        {
            context.HotspotSession.HotspotUpdated += this.CurrentHotspotUpdated;

            return false;
        }

        public void CurrentHotspotUpdated(object sender, System.EventArgs e)
        {
            var hotspotSession = sender as IHotspotSession;
            if (hotspotSession != null)
            {
                hotspotSession.CurrentHotspot.QuickEvaluate();
            }
        }

To compile, it is needed to reference the following R# libraries (from the installed version of R#, in my case R# 7.0):

JetBrains.Platform.ReSharper.DocumentModel.dll
JetBrains.Platform.ReSharper.Shell.dll
JetBrains.Platform.ReSharper.Util.dll
JetBrains.ReSharper.Feature.Services.dll
JetBrains.Platform.ReSharper.ComponentModel.dll

Most of the code is about implementing the standard IMacro interface. Most important here is the method EvaluateQuickResult that evaluates the value of the current field (hotspot) in a template. The same function is invoked each time the HotspotUpdated event is triggered.

Newly build plugin can be now added to resharper. Just copy it to “C:\Users\some.user\AppData\Roaming\JetBrains\ReSharper\v7.0\Plugins” folder and restart VisualStudio. After that the new macro can be added to the template and the test name will be transformed to the valid identifier on the fly.

Download

Instead of building your own plugin, you can also download it from here

Update

I also highly recommend creating another macro just to replace spaces with ‘_’. I’ve got ‘testn’ = ‘test name’ and it’s used extensively for renaming unit tests

Advertisements
Web

Chrome tips part 1 –selectors

 

Howdy! After some time I’d like to start with some JavaScript stuff.

Today’s browsers give us excellent opportunity to debug our pages with the one and only Web language which is JavaScript. Best example of that tool is Chrome console which gives us more than could be described in any post. As probably each of us knows, the console opens after pressing F12.

image

$$ alias

The most common usage for the console is jQuery programming – we can easily traverse the page searching appropriate element or just testing selectors before scripting. The scenario complicates when there is no jQuery included.

Google Chrome console treats $ as an alias for document.getElementById and the result of such queries are far from the desired outcome. Fortunately there is a nice alternative for it which is “$$” alias.

$$ is alias to document.querySelectorAll function that does pretty similar work as jQuery.find method. So everytime I feel the lack of jQuery I use this thing with success. Remember that it doesn’t implement all the selectors that jQuery has (like :first, :even) for argument/classes queries it is enough.

image

As jQuery.find method replacement we can also use “querySelectorAll” method.

$x alias

Another great tool traversing the document to find some element is $x method. It uses XPath istead of css selectors. It’s good new especially for people who can do more with XPath than with jQuery.

image

How about ability to deal with iframe’s?

$$ and $x does not search for the content of “iframe” element. To do it you have to switch the search context. To do it with $$ once more you have to use the full name of querySelectorAll method but in context of specific “iframe” document:

image

In case of $x it’s is slightly different – you have to pass context as a parameter:

image

You have to remember, that this kind of scripting have to adhere crossframe-scripting policy – domain of the frame should be the same as parent context’s domain.