Montag, 18. Mai 2015

C# 6 in action: Null propagation applied

Just another nice everyday example on how C# 6 can reduce verbosity. In case you don't let ReSharper teach you, be sure to spend 8 minutes on C# 6.

Samstag, 9. Mai 2015

.NET's bad relatives: On native dependencies



I have a love-hate relationship with native dependencies. As a developer i love quickly boosting my app with features from native code libraries using e.g. P/Invoke. However, when it comes to deployment we need to make sure that the native dlls will be 1) correctly deployed to the target environment and 2) correctly loaded at runtime.

Freitag, 8. Mai 2015

Yes, you can test it (1) - Prerequisites

Before you start with unit testing, you must fulfill one prerequisites ... you need to create a unit. Sounds logic, but what does this mean?

NEdifis: How we test if something got traced

Sometimes we have the requirement that something needs to be logged. Lets take some examples.
  • a csv importer gets an invalid file. Although the app can handle it, a warning should be logged.
  • an exception got caught and is not re-thrown, an error should be logged.
We use a "log4net trace listener" to get our traces logged (which is another story) so tracing and logging is technically the same for us. 

NEdifis provides an easy to use trace listener to receive all traces or logged messages. It uses the dispose pattern to register and deregister itself, therefore you need to dispose the TestTraceListener.

using (var ttl = new TestTraceListener())
{
    Trace.TraceError("here is a message");

    ttl.MessagesFor(TraceLevel.Error).Should().Contain("here is a message");
}
Fortunately, debug uses the same listener collection than tracing (but Debug has a System.Console like interface). So for debug, you can use the same trace listener and code.

using (var ttl = new TestTraceListener())
{
    Debug.WriteLine("nice debug");

    ttl.MessagesFor(TraceLevel.Verbose).Should().Contain("nice debug");
}

Keep in mind that "System.Debug" only works if you app was compiled with "Debug". For "Release" this list is empty (see unit test).

Mittwoch, 6. Mai 2015

NEdifis: How we organize our test classes

For the past decade I read a lot of articles about unit testing. There are thousands of best practices, do's, don'ts and especially workarounds. I remember a "trick" of a friend of mine who tried to find a way testing internal classes methods in a separate test project. His idea: he made these methods protected and created a derived class to wrap these methods in another internal method to access these methods from a test class. Yes, it is as complicated as it sounds.

In our project we started to add our unit tests to the same project and kept them together. This gave us the ability to keep things internal which should stay internal. After some iterations we ended up with two conventions:

  • Each test class ends with "_Should" so we can read tests easily
  • The test stays along with the class in the same namespace (folder)

The second point avoids the annoying duplication and maintenance of a folder structure or a huge namespace "Tests" with dozens of tests. In addition, you can see at a glance which classes don't have a test.

For this cross-relation, NEdifis provides two attributes for this relation.
[TestedBy(typeof(TicketAttribute_Should))]
public class TicketAttribute : Attribute
{
}

[TestFixtureFor(typeof(TicketAttribute))]
// ReSharper disable once InconsistentNaming
public class TicketAttribute_Should
{
}
This makes e.g. a navigation between these classes easier using "go to definition" and gives the opportunity for convention tests to check e.g. if each class has a test or a test fixture is properly named.

How we organize branches and releases in GitHub


After some experience with Git Flow & GitHub Flow, AppVeyor as Continous Integration tool, our OneClickBuild to simplify the build & deploy process and a bunch of other tools, we finally came up with the following workflow.

AppVeyor automatically builds and tests the master branch and publishes the package to nuget. We need to increase the (semantic) version number manually in two files (appveyor.yml and solution.targets), otherwise the publish step will fail.

Note that we switched to GitVersion which automates versioning.
Therefore we don't want to get each typo, minor pull request or a change in a readme be reversioned and published to NuGet.

So we created the develop branch as the default branch used for pull requests. If we decide to create a new version, we increase the version number and do a pull request to the master. This reduces the number of NuGet versions but we still can manage as many pull requests as we want.

Finally we use a simplified version of Git Flow but a more "complex" version of GitHub Flow. We don't create release branches in favour of pull requests. On the other hand we use a develop branch for pull requests.

Dienstag, 5. Mai 2015

GitHub: Boosting your README.md with status badges



One great thing about web-based repository hosting services like GitHubBitBucket and others is their ability to directly render Markdown documentation as Html. Although typically used for static documentation you can easily enhance the web representation by referencing dynamic content by url.

These days, a very common practice is to include status images, also known as badges, at the top section of your README.md to indicate current quantities and metrics related to your repository, e.g.
  • current build status (e.g. Jenkins, Travis CIAppVeyor and others),
  • package download count, total or per month (e.g. NuGet, npm, gem, etc...), 
  • code quality stats like test coverage (e.g. Coveralls) or technical debt (e.g. with SonarQube)
  • average time to close issues or accept pull requests (e.g. Issue Stats for GitHub)
This is a great and very simple way to improve the first impression of visitors and to show your professional working style.

How does it look? Head over to GitHub and explore some popular repositories. For example, i like Microsoft/TypeScript or elastic/elasticsearch-net.

Here are some badges of our own projects

Popular badge providers seem to be shields.iobadge.fury.io or issuestats.com.

So, get badging!