Getting up to speed with Unit testing with Xunit

For years now I have been wanting to learn how to do unit testing. I have read articles about it, watched online training courses, and started several projects, but I have never quite gotten there. Part of the problem is that I switch between architectures a lot in my day job, and the testing frameworks really need a modern coding platform to be effective. I guess you could use tests on your service classes in web forms, but as a novice, I haven't tried that. I have also been bouncing between learning different coding techniques that also use different testing frameworks, and I am always more focused on learning the new code than how to test it.

There are a number of advantages to using an automated test framework. One of the things that always impressed me when going to user group meetings was seeing a presenter showing a new coding library or plugin and using a testing framework to give a live example of how the code works. Unit testing allows you to execute a single method without having to wire up an entire application to see if it is working.

Unit testing improves quality in several ways. The first is obviously the ability to test your code under various circumstances, and retest when you have made a change. Another way it improves code which I think is more important, is that it forces you to write testable code. To be able to test code properly, you have to have your code separated properly. You have to code to interfaces, and your code cant be tightly coupled. Years ago I owned a coffee shop, and I used to encourage the baristas to learn to do latte art. One of the main reasons was if you could get the milk frothed right for latte art, then the milk frothing had been done right. The ability to do art was a quality control mechanism for me. Coding in a way that allows you to do unit tests improves your quality.

Right now I have a number of greenfield projects I am working on which is really exciting for me because I am going to get to use a lot newer technologies that I have been learning about. Putting knowledge into practice is the only way to really know something. I am going to be using Asp.Net Core, Json Web Tokens, Entity Framework Core, Web API and Angular. I have worked with most of these before, but they are all new versions, and with these projects I am going to be using Xunit for the unit testing. Well except for the Angular pieces, I am looking into a JavaScript framework for that. Xunit seems the be the hottest framework in the .Net area right now especially if you are using Core.

From what I have learned so far, I am really excited about using Xunit in my projects. Writing basic tests is pretty easy. In writing a unit test, you have the AAA principle which means A-Arrange, A-Act, and A-Assert. Arange is where you do your setup. You create objects, set parameters, etc. Act is where you call your method. And Assert is where you do a comparison. You can check the result of a method, test a property based on the constructor, or verify the result of a private method coming back to the public method. The recommendation is not to change the accessibility of private methods, but really test the overall behavior instead.

In Xunit, there are two types of methods you can create. The first is the decorated by the [fact] attribute. This method runs once and gives you a pass or fail. The other attribute you can use is called a [theory]. With this decoration, the method can be run several times with different parameters. Your parameters can come from another attribute called [InlineData(parameter1,parameter2)], and you can have multiples of these. You can also create your own attribute, and pass data that way. You can also use an external file, database table, or even a rest service to pass test data to your tests. This has really powerful potential because the data you use could be created by the end user who actually knows the data.

The other side of unit testing is how you implement them. When I first started hearing about unit testing, people kept referring to TDD or Test Driven Development, now I hear it more described as BDD or behavior driven development. The idea is this, before  you start to write your code, you create your test. When you start out your test immediately fails because there is no code to satisfy it. Then you create the code necessary to satisfy the test, then you create more tests, then more code, and so on. You also refactor your code along the way as your tests pass, then test again to make sure you refactoring didn't break anything.

I can really see the value in behavior driven development, but I am not sure I am disciplined enough to follow it as a purist. The other way to develop is to create your method then create the unit test to test the method. There are a couple of potential drawbacks to this method. First you may not end up writing tests that fully test the functionality of the method. The other issue that I can see happening very easily, is that you get in a hurry, and you start skipping tests. It would be very easy to think that a really simple method isn't worth testing. This could be an issue down the road if that method gets changed. There no tests to validate it.

As I get further into my projects, I will post some more real world examples of how my testing is working. Right now I just wanted to give an overview of what I have learned so far. How about you? What unit testing platform do you use? Do you follow TDD or BDD principles, or do you write your code first then design your tests around them? Let me know in the comments. 

Comments

Popular posts from this blog

Asp.Net Core with Extended Identity and Jwt Auth Walkthrough

File Backups to Dropbox with PowerShell

Dynamic Expression Builder with EF Core