C#7: Tools

I have spent the first couple of months of 2017 learning about the new features in C#7. This would not have been possible without some tools to help me play around with the new language syntax and associated types. Since we have to wait a little longer until Visual Studio 2017 is released, I thought you might like to know what tools I have been using to tinker in all things C#7.

LINQPad Beta

Link: http://www.linqpad.net/Download.aspx#beta

While early releases of Visual Studio 2017 (scheduled for release on March 7th) support the language, I initially found the release candidate to be unstable and frustrating. Not only that, but it can be cumbersome to spin up a quick example using Visual Studio, so I turned to my trusty friend, LINQPad.

LINQPad Beta showing me my return is missing a ref
LINQPad Beta showing me my return is missing a ref

I cannot recommend LINQPad enough, it is a fantastic tool for prototyping, poking around data sources, and more besides, like tinkering with language features you don't yet understand. While LINQPad's current release only supports the C# language up to version 61, the beta release also supports C# version 7. Not only can you use the language, but with the fantastic analysis window, you can see how Roslyn breaks down each part of the code. If you want to get started quickly, easily play around with the cool new features, and have a powerful tool for digging deeper as the need arises, the LINQPad beta is the tool to get.

Visual Studio 2017 RC

Link: https://www.visualstudio.com/downloads/

Visual Studio 2017 RC splash
Visual Studio 2017 RC splash

Yes, I know I said it was unstable and frustrating, but that was before, way back in January. These days the RC is much, much better and with the release date set for March 7th, there was never a better time to install Visual Studio 2017 RC and get a head start on getting to know some of the new things it can do, including C# 7. Tuples are fun, but poking around with them in the debugger is funner.

OzCode

Link: https://oz-code.com/

Pattern matching in OzCode
Pattern matching in OzCode

It is no secret that I love OzCode, the magical debugging extension for Visual Studio. It is so well-known that they asked me to be part of their OzCode Magician community program. So, it should come as no surprise that I have been using OzCode in my exploration of C#7. As the Visual Studio 2017 RC has matured, the clever people over at CodeValue have been creating previews of OzCode version 3, including amazing LINQ debugging support. Recently, I got to try an internal build that included support for all the cool new things in C#7.

OzCode 3 will be released on March 7th, the same day as Visual Studio 2017.

Documentation

Link: https://docs.microsoft.com/dotnet/articles/csharp/csharp-7

Never underestimate the power of reading documentation, it is one of the best tools out there. For my C#7 posts, I relied heavily on the new docs.microsoft.com site, specifically the .NET articles on C#. Not only is this a fantastic resource, but it has built-in support for commenting on the documentation so that you can ask questions and contribute to their improvement.

In Conclusion

This is the entire list of tools I used for my C#7 investigations. Try them out and get an early start on C#7 fun before the March 7th release of all the C#7 goodness. Happy tinkering and if you stumble on any useful tools, please share in the comments!


  1. It also supports SQL, F#, and VB 

C#7: Out Variables

Last time, we started to look at the new features introduced in C#7. Here is a quick refresher of just what those features are:

In this post, we will look at one of the simplest additions to the C# language; out variables.

int dummy

How often have you written code like this?

Or this?

Sometimes you use the out value retrieved, sometimes you do not, often you only use it within the scope of the condition. In any case, there is always the variable definition awkwardly hanging out on its own line, looking more important than it really is and leaving space for it to accidentally get used before it has been initialized. Thankfully, C#7 helps us tidy things up by allowing us to combine the variable definition with the argument.

Using the out variable syntax, we can write this:

In fact, we do not even need to declare the type of the variable explicitly. While often we want to be explicit to make it clear that it matters (and to ensure we get some compile time checking of our assumptions), we can use an implicitly typed variable like this:

In Conclusion

out variables are part of a wider set of features for reducing repetition (in written code and in run-time execution), and saying more with less (i.e. making it easier for us to infer intent from the code without additional commentary). This is a very simply addition to C# syntax, yet useful. Not only does it reduce what we need to type, it also improves code clarity (in my opinion), and reduces the possibility of silly errors like using a variable before it has been initialized, or worse, thinking that it being uninitialized was a mistake and hiding a bug by initializing it.

Until next time, if you would like to tinker with any of the C#7 features I have been covering, I recommend getting the latest LINQPad beta or Visual Studio 2017 RC.

 

Running XUnit Tests, Using Traits, and Leveraging Parallelism

We have arrived at the end of this little series on migrating unit tests from MSTest to XUnit (specifically, XUnit 2). While earlier posts concentrated on writing the tests and the XUnit counterparts to MSTest concepts, this post will briefly look at some non-code aspects to XUnit; most importantly, we will look at getting the tests to run.

Do not depend on test order
One thing to watch out for after migrating your tests is the order in which tests are run. MSTest allowed us to abuse testing by assuming that tests would run in a specific order. XUnit does away with this and will run tests in a random order. This can help to find some obscure bugs, but it can also make migration a little tougher, especially when tests share a data store or some other test fixture. Watch out for that.

Visual Studio

Running tests inside Visual Studio is really simple. Following in the footsteps of web development trends, rather than requiring an extension to the development environment, XUnit uses package management1. All you need to do is add the Visual Studio XUnit test runner package to your project and Visual Studio will be able to detect and run your XUnit tests just like your old MSTests.

Of course, if you're like me and absolutely loathe the built-in Visual Studio test explorer, you can use Resharper (or dotCover), which has built-in support for XUnit.

Command Line

More often than not, our continuous integration setups are scripted and we're unlikely to be running our unit tests via the development tool, such as Visual Studio. For situations like this, you can add the XUnit command line test runner package to your project. This provides a command line utility for running your tests with arguments to control exactly what tests and how2.

Once the package has been added, you can browse to where Nuget is storing packages for your particular project. In the tools folder of the console runner package folder, you will find xunit.console.exe. If you run this with the -? argument, you will get some helpful information.

The three options I use the most are -trait, -notrait, and -parallel.

Traits

The two trait options control what tests you are running based on metadata attached to those tests. This is really useful if you have some tests that are resource heavy and only used in certain circumstances, such as stress testing. In MSTest, you could attach arbitrary metadata onto test methods using the TestProperty attribute. XUnit provides a similar feature using Trait. For example, [Trait("Category", "ManualOnly")] could be used to put a method into the ManualOnly category. You could then use the following line to execute tests that lack this trait.

If you wanted to only run tests with a specific trait, you do the same thing but with -trait instead. Both of these options are very useful when combined with -parallel.

Parallelism

XUnit can run tests in parallel, but tests within the same collection are never run in parallel with each other. By default, each test class is its own collection. Test classes can be combined into collections using the Collection attribute. Tests within the same collection will be executed randomly, but never in parallel.

The -parallel option provides four options: no parallelism, running tests from different assemblies in parallel, running tests from different collections in parallel, or running tests from different assemblies and different collections in parallel.

The difference between assembly parallelism, collection parallelism, and both together

Let's assume you have two assemblies, A and B. Assembly A has three collections; 1, 2, and 3. Assembly B has three collections; 4, 5, and 6.

No Parallelism
-parallel none

XUnit will run each collection in one of the assemblies, one at a time, then run each collection in the other assembly one at a time.

Collections 1, 2, 3, 4, 5, and 6 will never execute at the same time as each other.

Parallel Assemblies
-parallel assemblies

XUnit will run each collection in assembly A, one at a time, at the same time as running each collection in assembly B, one at a time.

Collections 1, 2, and 3 will not execute at the same time as each other; Collections 4, 5, and 6 will not execute at the same time as each other; but collections 1, 2, and 3 will execute in parallel with 4, 5, and 6, as the 1, 2, and 3 are in a different assembly to 4, 5, and 6.

Parallel Collections
-parallel collections

XUnit will run each collection within an assembly in parallel, but only one assembly at a time.

Collections 1, 2 and 3 will execute parallel; collections 4, 5, and 6 will execute in parallel; but, 1, 2, and 3 will not run at the same time as 4, 5, and 6.

Parallel Everything
-parallel all

XUnit will run each collection in parallel, regardless of its assembly.

Collections 1, 2, 3, 4, 5, and 6 will run in parallel, each potentially running at the same time as any other.

Beware running tests in parallel when first migrating from MSTest. It is a surefire way of finding some heinous test fixture dependencies and you risk thinks like deadlocking on resources. Usually, running assemblies in parallel is a lot safer than running collections in parallel, assuming that tests are collocated in assemblies based on their purpose and the resources they interact with.

In Conclusion…

That brings us to the end of the series. I have focused primarily on migrating from MSTest, leaving out a lot of the nuances to XUnit. I highly recommend continuing your education with the XUnit documentation and through experimentation; having personally migrated several projects, I know you won't regret it.

 


  1. I love this approach to augmenting the development environment. It requires no additional tooling setup to get your dev environment working. The source itself controls the tooling versions and installation. Wonderful 

  2. You can control how tests run under MSBuild too by using various properties. This is discussed more on the XUnit site 

OzCode: Reveal With Reveal

In my last post, I revealed that I am a magician; an OzCode magician1. I also revealed the new LINQ support currently in EAP. Since that was two reveals in one, I thought that I would look at another OzCode feature today coincidentally called Reveal.

I remember this specific feature as "favourites for properties" although I am reliably informed by the OzCode team, their website, and their documentation that it is in fact called "Reveal"2. Reveal was the feature that first lured me into regular use of OzCode and if it is the only feature you use, you will still wonder how you really survived without it.

When debugging, we can spend lots of time drilling down into objects to find the value of various properties and sub-properties. This can get especially tiresome when we're looking at a few similar objects since we repeat the same steps. Although pinning certain values is helpful, it does not really solve the initial issue of drilling down to find the thing to pin.

With Reveal, we can make life much simpler by elevating the details of an object to its summary; like an on-the-fly custom ToString implementation. Not only does this help with looking at one item, but it really helps with collections of similar items. For example3:

Animated GIF showing how to use Reveal in OzCode
Animated GIF showing how to use Reveal in OzCode

Any properties that are "revealed" carry across to the rest of the debug session and beyond; once you have revealed some properties, they stay revealed until you decide you do not want them to be anymore, even across debug sessions.

Animated GIF showing how the revealed properties remain revealed
Animated GIF showing how the revealed properties remain revealed

You can even see (and change) your revealed properties directly within the LINQ analysis window.

Animated GIF of using Reveal inside the new LINQ analysis feature of OzCode
Animated GIF of using Reveal inside the new LINQ analysis feature of OzCode

Finally, revealed properties propagate up the object hierarchy allowing you to surface values from deeper in your object tree. This can really be a huge time saver, especially since the revealed properties are remembered across sessions. No more hovering over multiple things to find what you're looking for and no more writing custom ToString overrides, debug visualizers, or other workarounds.

Hopefully, this overview of Reveal in OzCode has demonstrated not only why I love it so much, but also how valuable it can be. I genuinely believe OzCode to be an essential tool in any .NET developer's kit, but since you may mistake me for some corporate shill, you should not take my word for it; try OzCode out for yourself with a free trial (or take part in the EAP). Stop performing workarounds and start performing magic.


  1. Read as Sean Connery as James Bond 

  2. and apparently it doesn't matter how often I tell them they are wrong 

  3. To demonstrate, I am using the handy demo app from OzCode, which you can find on GitHub 

Signing GitHub Commits With A Passphrase-protected Key and GPG2

GitHub recently added support for signed commits. The instructions for setting it up can be found on their website and I do not intend to rehash them here. I followed those instructions and they work splendidly. However, when I set mine up, I had used the version of GPG that came with my Git installation. A side effect I noticed was that if I were rebasing some code and wanted to make sure the rebased commits were still signed (by running git rebase with the -S option), I would have to enter my passphrase for the GPG key for every commit (which gets a little tedious after the first five or so).

Shows some commits on GitHub with the Verified indicator showing those that have been signed
How GitHub shows signed commits

Now, there are a couple of ways to fix this. One is easy; just don't use a passphrase protected key. Of course, that would make it a lot easier for someone to sign commits as me if they got my key file, so I decided that probably was not the best option. Instead, I did a little searching and found that GPG2 supports passphrase protected keys a little better than the version of GPG I had installed as part of my original git installation.

Using the GPG4Win website, I installed the Vanilla version1. I then had to export the key I had already setup with GitHub from my old GPG and import it into the new. Using gpg --list-keys, I obtained the 8 character ID for my key (the bit that reads BAADF00D in this example output):

Which I then used to export my keys from a Git prompt:

This gave me two files ( privatekey.txt and publickey.txt) containing text representations of the private and public keys.

Using a shell in the GPG2 pub folder ( "C:\Program Files (x86)\GNU\GnuPG\pub"), I then verified them (always a good practice, especially if you got the key from someone else) before importing them2:

And rather than give me details of the key, it showed me this error:

What was going on? I tried verifying it with the old GPG and it gave me a different but similar error:

I tried the public key export and it too gave these errors. It did not make a whole heap of sense. Trying to get to the bottom of it, I opened the key files in Visual Studio Code. Everything looked fine until I saw this at the bottom of the screen.

Encoding information from Visual Studio Code showing UTF16
Encoding information from Visual Studio Code

It turns out that Powershell writes redirected output as UTF-16 and I had not bothered to check. Thinking this might be the problem, I resaved each file as UTF-8 and tried verifying privatekey.txt again:

Success! Repeating this for the publickey.txt file gave the exact same information. With the keys verified, I was ready to import them into GPG2:

With the keys imported, I ran gpg --list-keys to verify they were there and then made sure to delete the text files.

Finally, to make sure that Git used the new GPG2 instead of the version of GPG that it came with, I edited my Git configuration:

Now, when I sign commits and rebases, instead of needing to enter my passphrase for each commit, I am prompted for the passphrase once. Lovely.


  1. You could also look at installing the command line tools from https://www.gnupg.org/download/ though I do not know if the results will be the same 

  2. Note that I am not showing the path to the file here for the sake of brevity, though I am sure you get the idea that you'll need to provide it