Unit Testing Training

Unit Testing has been one of the dearest technical subjects for me in the past years. A great influencer was a TDD Workshop lead by J. B. Rainsberger to which I was lucky enough to attend, somewhere in 2010. It was a very good fit with the moment of my career. I was starting to realize that we are quite far in the way we are developing software from the principles and disciplines advocated by different industry leaders. I was looking for concrete methods to improve the way me and my team colleagues w software.

JB not only that has taught us what Unit Testing and TDD are, but he also demonstrated a powerful technique: getting to a modular design driven by unit tests and by some simple rules. He showed how to achieve a design that is inexpensive to change, by minimizing the accidental complexity. This has made me to see in unit testing one of the most efficient tools for assuring a sustainable quality level of the code in the projects I was involved in. It motivated me to teach others to write Unit Tests that benefit them in the quality level of their production code.

I wanted that the next projects I will start to work on to begin with a training on unit testing. I wanted that the entire team writes and cares about unit testing in a consistent manner. This is how my Unit Testing training was born. I have initially developed it for a newly created team that was starting a challenging project on a tight schedule. I knew from the start that it will not be possible for the very few seniors to review enough and do enough pair-programming with everyone, so we can have a sustainable quality level in our code. We needed a flexible design which could accommodate the volatile requirements we were supposed to deal with in a predictable way and at reasonable costs. I thought that if everyone would cover with good written unit tests their code, than we would end up with a design that is good enough. Maybe not the best one, but good enough. And, it worked! Even if we were on a tight schedule, the initial investment in learning and writing unit testing, paid off in the end.

Since then I have redone the training many times for different teams in ISDC and for some of their clients. We have a seen many benefits not only at the project startup, but also for ongoing projects with existent teams. It is always about reading and changing code, rather than writing code. Unit testing, if done the right way, can significantly increase the efficiency and predictability of the changes we do in code.

Another motivation to build this training was to share with others my experiences of learning unit testing. For many teams it is very important to start on the right track with unit testing. When unit testing is done incorrectly it can cause schedules to slip, waste of time, and it can low motivation, and code quality. It is a double-edge sword, which many teams learn to master the hard way. One of the lessons I’ve learned the hard way was: “Never treat your unit tests as second class citizens”. It was in one of the first projects I was learning unit testing on. We’ve ended up after a few weeks with a tests suite, which was breaking at any changes we were doing to the production code. We couldn’t refactor or redesign the production code, because the tests would break. It wasn’t because of poor design of the production code side, it was because of the poor quality of our unit testing code. We have created a too strong coupling in test code, which turned out hurting in the production code as well. I and my team colleague ended up in drawing sticks on who is going to spend the weekend to fix the tests. I wouldn’t want anyone to repeat this painful experience.

In the past few weeks I have taken the time to review, refresh, enrich and restructure the entire training material of my course. I have added the topics and examples for which, until now, I never had the time to detail them as I wanted.

At start, the content was largely built based on Roy Osherove’s The Art of Unit Testing book. Now I have enriched it with new elements from the books and articles of Kent Beck or Martin Fowler and others. I have also taken to opportunity to reshape the training with my experiences from last few years and to add the new things I have learned from pairing with different people at code-retreats or on other occasions.

The training focuses on two main aspects: maintainability of the tests and the benefits on the quality of the production code. The tests code may be a significant amount from all the lines of code forming a project. However, even if it is big in size it is important that it does not increase the complexity, so it has low maintainability costs. The greatest benefit I see from doing Good Unit Tests is in the design of the production code. By learning a few aspects about how to write your tests you can exercise a positive pressure on your production code leading it towards a better design.

UPDATE: I have published a presentation page with the full format of the entire course here.

Advertisements
Posted in Technical, Training, Unit Testing | Tagged , , , , | Leave a comment

Why I Write Isolated Unit Tests

Most of the times when I talk about unit testing or I ask encourage my colleagues to write unit tests, I emphasis on writing GOOD Unit Tests which are easy to write, they test only one thing and they run in isolation. I always make a clear distinction between these very granular and highly isolated unit tests, which I call GOOD Unit Tests and the Integration Tests. I roughly name Integration Tests any automated test that has more than one point of failure or it exercises more external objects (other classes objects, services, databases, etc.). These tests verify that all those pieces work well together. What I want to focus on instead, are the very granular unit tests, which verify the basic correctness of each unit in isolation and they assert only one thing. When such test fails I know exactly where the problem is, from the test name only.

The greatest benefit we get from writing GOOD Unit Tests, which are easy to write, they test only one thing and they run in isolation, is a better code design that results into the production code. These unit tests put positive pressure on the production code making it better. I am not chasing a bug free code, nor a full coverage in regression testing with these unit tests, but a higher quality code design when I am working with teams that are less experienced in doing a good design.

Yes, there are drawbacks as well. We might get into the other extreme and have the production code design suffer from this granular unit testing, resulting into too small classes, with code smells like feature envy or unnecessary complexity. I totally see the point of DHH during the ‘Is TDD Dead?’ debate, that this might lead to creating interfaces or abstract classes only for the sake of mocking. Indeed, it may get to making interfaces which do not create abstractions and which break encapsulation. Yes, granular unit testing will not help in preventing these, on the contrary. When our code design falls into being too granular, practices like eliminate duplication and reduce the dependencies of a class while refactoring, plus a consistent code structure, are helpful to keep things in balance. In the end it all depends on your context: what problem you want to solve, which are your constraints, how experienced is your team and many other aspects.

We couple things by nature. It is more common to put everything in one class or one function rather than thinking about separating the concerns by factors of change. In most of the cases when I am looking over a poorly designed code I am seeing too much coupling (or coupling without benefits) and poor cohesion. Everything is done in one or two big classes. In all most of the cases it is clear that if someone would have tried to write GOOD Unit Tests on that code, it would have been forced to refactor it towards a better design. It wouldn’t be possible to write small unit tests, otherwise. This would have turned the code into a better one. Maybe not the best design, but certainly better. It would break the one thing into more, and the breaking would be driven by test cases, which leads to a good separation of concerns. I often see that the GOOD Unit Tests make the design to move from one like this

One big thing

One big thing

towards one like this

Better design?

Better design?

which is clearly better than the first one, maybe even better than this

Coupled things. Everything is talking to everything

Coupled things. Everything is talking to everything

, and clearly better than this

Very many tiny, small things

Very many tiny, small things

, which is at the other extreme than the first one. We want to balance things and to get somewhere in the middle. (These design examples are copied from Juval Lowy presentation on ‘Modular Application Design’, which I value a lot.)

Another important advantage of the Good Unit Tests is that they are easy to write and to maintain, therefore they have low costs. For example if we consider the following setup:

testing f()

testing f()

where, function f() of class A, calls g() of class B, which in its turn calls h() of class C. After the return of g(), f() may make a call to h’() depending of the result of g(). A quite common setup in an OO program. Now, if we want to write a test to verify the correctness of f() and only f(), it will not be easy. When we write the arrange part of the test, we need to take into account the preconditions and post conditions of all the functions, and find the test data that will make the code flow to be the one we want in our test scenario. This will make our arrange code hard to write. When we assert, things it will also be difficult. The expected result of f() may need to take into account calculations made by the other functions as well. Even if we manage to write the test, it will be hard to maintain. Also, there are high changes for this test to break when refactoring or other changes occur to classes B or C. Another, disadvantage of such integration test is that if it fails we cannot clearly say where the bug is. It may be in classes B or C even though those are not the classes under our test. As a conclusion, this kind of test has high costs (difficult to write and maintain) and low benefits (I don’t know where the bug is, when it fails).

The alternative, is to refactor my code and change B and C with interfaces which abstract them. This will allow me to replace them with fakes (mocks or stubs) in my tests, which are totally under the control of my test code. Now I can easily write many GOOD Unit Test for class A, in isolation to verify its basic correctness. I can write one test to verify ONE thing. Looking more closely to the production code, we’ll see design patterns and SOLID principles that may emerge from this refactoring. For example, we’ll tend to program against interfaces, we’ll depend on abstractions and not on implementation details (partially what DIP says), we’ll have our class dependencies visible, we’ll move towards a more extensible and reusable code (partially what OCP says).

It is good to focus to cover with unit test all the logic and calculations. This means the code that has ifs, whiles, fors, etc. and mathematical or other data structure operations. Covering plumbing code, data conversion or basic variable assignment brings little value. When we strive to achieve a good coverage for the logic, because it is easier to fully cover it with GOOD Unit Test rather than Integration Tests, another positive effect happens: the logic gets pushed away from the external frameworks and libraries. The external libraries tend to get abstracted, and our core logic separated from the plumbing code that integrates them. This leads to a better separation of concerns. Our business logic code tends to be pushed away from the presentation and from the data access towards the middle. Wasn’t this something we’ve always wanted?

Logic is pushed from Presentation, Data Access and Cross-Cutting Concerns

Logic is pushed from Presentation, Data Access and Cross-Cutting Concerns

Another aspect of GOOD Unit Tests is that we can fully and easily test all the scenarios that the code needs to handle in a very detailed way. I usually think of the car running example. If the car does not move, it is clearly broken. However, we don’t know what part is not working, so we need to verify each part separately to find and fix the problem. Moreover, even if the car moves, we can’t say by this integration test only, if all the parts function at correct parameters. It may be that only after driving more than 1000 km without stopping the engine will get overheated, because of a malfunction in the cooling parts. Coming back to code, I rely on Good Unit Tests to verify the basic correctness in detail, with high coverage. Like in the car example, there may be scenarios that I cannot test otherwise or I would just ignore because it is too hard to be done with integration test. For instance how would you test that your code behaves correctly when the hard-disk is full? Would you fill it to run a tests? Can you do that on the CI server?

Therefore, we target a high coverage with unit tests, and we verify that each of the services work well in isolation.  The unit tests can go in detail at lower costs. Then on top we may have few Integration Tests, which do not go in many details because they are costly. They just check that all the services and components can work together and that all the configurations are consistent. The integration tests usually follow some happy flow scenarios and focus that all the components they touch are running. They do not target correctness as the unit tests do. Below figure, shows three classes fully tested in isolation by unit tests (blue arrows) and two integration tests (purple arrows) on top, which touch all the working components, but fewer code paths.

Integration tests touch all classes, but have lower coverage

Integration tests touch all classes, but have lower coverage

In theory both with isolated Unit Tests and Integration Tests we could reach a full coverage of the entire code we write. With unit tests we need to write many pairs of isolated Collaboration Tests and Contract Tests to reach a full coverage. With Integration Tests we need to be able to specify and simulate all the test scenarios. In general, the costs of writing and maintaining such integration tests which cover all the details, grows exponentially and they are very fragile to change. Any change in the system is very likely to break them, which makes them not feasible. That is why we need to test on intermediate results. We break the end-to-end tests in smaller tests, until we get to the Good Unit Tests, which are at the lowest level checking each detail. By doing this, not only that we get to full a high coverage at lower costs, but we also get better production code in the process. Integration Tests rarely bring any benefits to the design of the production code. However, they contribute to the test suite covering the component integration and the configurations consistency.

To conclude, I always treat my unit test code as first class citizen. It is separated from production or other test code. I like my unit tests to be small, easy to write, to test only one thing and to run in isolation. The highest benefit I want from them is to put pressure on my production code to make it of better quality. I write them in very short cycles, with the production code, even if I do code first, because I want to refactor in small steps. I rely on them for basic correctness and I target a high coverage of the code that does logic and calculations. Separately, I write different levels of Integration Tests. They check that more services or components (which I already know are functioning well in isolation) can work together. They may also check interactions with external services, frameworks or data sources. Sometimes, I also have integration tests for regression testing, performance or load testing.

Posted in Technical, Unit Testing | Tagged , , , , , | Leave a comment

The Code Design Training

It was few months ago more than a year ago (22nd of February 2013 in my Trello card, Ideas column), when I came up with the thought of developing a training about how to write good code. At that time I was doing a lot of thinking about how to best use my one extra free day, as I started to work part time. The idea to use part of this time to develop trainings came rather naturally as I was already teaching and coaching colleagues about good code and also holding trainings about good unit tests in ISDC and for some of their clients. I also realized that holding trainings was a really enjoyable experience for me, so the fit was quite perfect.

What I intended with this kind of course is to express and explain, how all the best practices from the object oriented design world are structured in my mind. It is about how my links and connections among these various design principles and patterns results in the code I write. During my previous coaching sessions, I realized that explaining my vision helped more than just presenting the theoretical concepts. It helped both to get to a better understanding of their usefulness and in writing better code. The Code Design training was born from this desire: put in a clear map all the patterns, principles and practices, and present them using code examples from real projects to any team from any company.

The entire training is structured around of the idea of designing code that embraces change. Code that is easy to change. Code that is inexpensive to change. Code with predictable effects of change. Changeable code. Change is the leitmotif of my training. What I want to teach is how to drive all the design decisions to minimize the effect of change. That is why this is not an Object Oriented Design training. It is not only about that. It is a Code Design training that focuses on minimizing the cost of change. Because, at the end of the day, the most important benefit quality code is the low cost of change.

I have started to actually work on developing this training somewhere in October 2013 and I worked regularly in my free days left from the regular part time job. I have taken an interactive approach. First I have put on paper the main ideas and topics I wanted to teach. Then I have defined the learning objectives and I have also summarized what would one learn from this course. Next was to put on paper a draft script for the entire course. After that I have  enriched this draft in an iterative way, by identifying materials that would lead to reaching the learning objectives. I have gathered concepts, examples, explanations and ideas from my favorite books, like: Clean Code: A Handbook of Agile Software Craftsmanshipor Code Complete: A practical handbook of software construction, and others that I have read along the years. It ended up to be a selection of concepts and examples from these books structured, interpreted and explained in my own way shaped by my own experiences of writing code and explaining it to others. At some point the training lessons got the shape I was looking for. Each lesson was targeting roughly one or more of the objectives. In the end the training lessons are:

  • Part 1: Good Code Design and Design Patterns
    • Lesson 1: Why Code Quality and Code Design
    • Lesson 2: Clean Code
    • Lesson 3: Separation of Concerns
    • Lesson 4: Design Patterns 
  • Part 2: Object Oriented Design Principles and Practices
    • Lesson 5: Object Oriented Design Principles
    • Lesson 6: Dependency Injection
    • Lesson 7: From Principles and Patterns to Practices
    • Lesson 8: Application Infrastructure

Somewhere along the way I have started to think more seriously about another important stakeholder in this: the companies that would ask me to hold this training for their employees. I have made a commercial offer for the training, which details the outcomes, the benefits and the costs of the training. I have also considered more carefully how I would customize the training for different needs. The training lessons are built in such way that they can be taught individually and still bring value, or only a part of them can be selected into a shorter version of the course for an audience that doesn’t need to go through all the subjects.  Having the offer done, I have sent it through my contacts, to some companies in Cluj. I have got good feedback, which encouraged me even more to dedicate more time and energy to developing the training.

Once I had the course script complete enough, I have started to build the training materials: power point slides, exercises, code samples, and to select videos which can contribute to the learning experience.

Tomorrow is the first time I will hold it as an internal company training, for Wirtek. A company here in Cluj, which shows high desire to increase the quality of their services by investing in people. In a way I am glad it happened that the first run of the training is not in the company I regularly work for, because it is in a new context, which makes it a better test for me and for the training itself. I am quite confident that it will go well, and that it will help them, because I have put a lot of effort, energy and thought in it. I’m looking forward to a great day tomorrow!

 

UPDATE: I have published a presentation page with the full format of the entire course here.

Posted in Technical, Training | Tagged , , , , , , , , | Leave a comment

IT Camp 14

Tomorrow the 4th edition of IT Camp, starts in Cluj-Napoca. It’s a good time to stop from day to day work and look towards the community to share and to learn from the other fellow developer’s experiences.

This year I am going to add to the story of how to reach a good Quality Code Design, which can sustain your project over the time. Last year I have talked about why quality is important in software and how it can be achieved by benefiting from the positive pressure the GOOD Unit Tests put on our design. This year I am talking about the other part: the Application Infrastructure. They both go hand in hand, by completing each other, in leading your code towards a good quality that can pass the test of time. Usually the Application Infrastructure comes first, but I am saying the story in reverse order.

So, if you’ve seen my last year talk come Friday morning in Verdi room to hear the first part of the story. If you didn’t see it yet, you can see the recording here, after Friday, so you can get the story in its natural order.

See you at IT Camp! Have a great conference!

 

PS:
I hope the title: “Quality Code through Application Software Infrastructure” doesn’t mislead you in thinking that it is going to be an IT Pro talk about servers and operating systems. Noting like that. It’s going to be about Code Design.

Posted in .NET, Technical | Tagged | Leave a comment

IT Camp – A Great Experience

IT Camp happened at the end of this week in Cluj. I am proud that the town I am living in hosts the biggest premium conference on Microsoft technologies in Romania. It gathered almost 400 participants, from which a significant part were from other cities. My impression was that most of them were experienced software professionals. I hope to see in next editions people coming also from neighbor countries. I think it worth the trip. All the sessions are in English, there are a lot of international speakers and there is a great opportunity to meet experienced professionals from Microsoft technologies world.

The first day was opened by two inspirational keynotes given by Richard Campbell and Tim Huckaby. I was impressed about how friendly, open and close to the audience Richard is. I think anyone could approach him during the breaks and lunch for any questions or discussions. Same goes for Tim. It was a rare opportunity to meet and speak to such great guys. Thanks for being here!

I was honored to be one of the speakers. I am glad that I have had the opportunity to speak in front of a large audience and to share my experience. I was a bit nervous to have my session in the 2nd day, on the ‘Architecture and Best Practices’ track, after notorious speakers like: Martin Kulov, Peter Leeson, Richard Campbell and Sergiu Damian. However, my story on how you can get to high code quality by doing good unit tests, fitted well after the talks of Peter, Richard and Sergiu. Peter and Richard touched other faces of quality in software. My good friend and RABS colleague, Sergiu walked us through architect’s challenges. I think, I added to both subjects by talking about code quality and the challenge to get there with the whole team. I had a good time speaking, I liked it and I’ll do it again. I hope I’ve inspired my audience in a way or another, and even if maybe some were not convinced about the technique I presented, I hope that they went away with a new perspective, maybe a new author to read or at least with a good story. I was very happy to hear someone that one of his takeaways from the conference was one of the key points of my talk. It made me to feel good J

My slides are published here. I did not have the time to include a code demo in this talk, but I will do a full demonstration on how good unit tests put a positive pressure on the production code design, next week in Bucharest at I TAKE Unconference as an Open Session.

One of the sessions I liked a lot was the one given by Peter Leeson. It was perfect! I hope to see him at next editions or other similar events in Romania. I hope that some companies active in Cluj or Romania were inspired to pay more attention to improving the quality of their products or services, because in the end this will be the only thing that would differentiate us from cheaper services in eastern countries or Asia.

All the sessions from IT Camp were recorded and will be available soon on the conference web site.

IT Camp was for me a great experience. I’ve met great people and I made some new friends and contacts. Big thanks to Mihai and Tudy for organizing this, thank you for giving me the opportunity to speak and thanks you all for attending. See you next year to an even better edition!

Posted in .NET, Unit Testing | Leave a comment

IT Camp 2013

I will speak this year to ITCamp conference on 23rd of May.

When I have received the invitation (thanks Mihai and Tudy for inviting me) my first thought was whether I should talk about Unit Testing or something else. Then I started to wander why do I like to talk that much about it, so much that I am seen as the unit tests guy by my colleagues, all the projects I’m involved in have a high accent on unit tests, and I even receive birthday cards with: “no unit tests? You’re doing it wrong!”. There are definitely other interesting subjects to talk about. Then I realized it. Unit testing was the only technique with which I managed to persuade one of my teams to write good quality code, which allowed us to easily change it. All the talks about Design Patterns, programming principles didn’t do it. Unit testing did it.

Therefore, this year I will talk at ITCamp about how to drive your team towards quality code, by writing good unit tests. Today I have started to put on paper some ideas on how to structure and build my talk. I have few more free Fridays to refine it and make it a good talk in which to show my view on how to achieve good code and why would you want that. I hope to see you there!

Posted in Technical | Leave a comment

Global Day of Code Retreat

On December the 8th, we had the Global Day of Code Retreat in Cluj-Napoca. We have joined the other 150 cities all over the world in a great global event.

My first contact with a code retreat was almost a year ago when some friends from iQuest invited me to join them for a code retreat organized internally. I loved it. I liked the idea, the format, and the most the fact that I had the opportunity to pair with developers I didn’t know and to experience different programming languages. Since then I had the idea to organize with RABS a large code retreat with a lots of developers. When somewhere in October, I heard that there is going to be a global day of code retreat, I said that this is the best opportunity to organize it, so I’ve registered Cluj, among the other locations in the world. I wanted diversity: many programming languages and many developers with different experiences and views. We’ve succeeded: we had 70 developers who programmed in 8 languages: C#, Java, C, C++, javascript, Ruby, Python and F#.

I needed help. I’ve asked Andrei Olar, who facilitated the code retreat at iQuest to take over the facilitator role. He gladly accepted. Knowing we are going to be more than 50, we have also asked Costin Morariu who facilitated more code retreats, to be another facilitator. Even if he lives in Sibiu, he said yes. I was the third facilitator and Sergiu took over the host responsibilities. We decided at RABS that we are going to organize it, but we wanted to have an event for all developers, regardless the technology or experience, so we asked the major programmers communities in Cluj: Code Camp, JUG, Cluj.rb and RONUA to join us as co-organizers. They all accepted our invitation, so we’ve published the event and started registrations. We’ve chosen Cluj Cowork to be our host. It was perfect for such event (lot of space and more rooms). After a few days we had over 50 people registered. When we’ve reached 80, the maximum capacity, we’ve opened a waiting list. In the end we had 135 registrations. Part of them announced us that they cannot make it and leave the seat to someone else. From 85 confirmed registrations, 70 showed up. Given the large number of people we splat from the beginning in three groups: red team, blue team and green team. Each team had its own facilitator, its own rooms, and basically we had three code retreats which ran in parallel. The facilitators consulted regularly to do the same exercises in each session so we allow people to switch teams after lunch.

The first session was to allow everyone to get familiar with the problem. We also asked them to write tests. Given the fact that most of the participants were not familiar with the format we have chosen Conway Game of Life. The second session asked for TDD, but we did not make anyone to change the pair if he didn’t want to. The third session was also about TDD and pair programming, but now anyone had to pair with someone else. At lunch we were already counting around 7 programming languages. After lunch we started with a ping pong TDD session, meaning that one starts writing the failing test and his/her pair makes it pass and writes the next failing test and then they switch again. The last session was a mute session, no talking with the pair. This forced everyone to make their code very expressive. We had some pairs who also tried the ‘no-ifs’ exercise for the last session.

I have facilitated for the blue team. It was the first time for me as a facilitator and a great experience. The advices from Andrei and Costin helped a lot. Also of great help was the facilitator training registered by Jim Hurne, which I watched a day before on the plane and in the airport. Thanks guys! A large part of the participants didn’t try TDD before, so during the second and third session I insisted that the three steps of TDD are done in very short cycles. I remember that at the beginning of the third session when everyone had to switch the pair, there was a lot of loudly arguing in each pair. Everyone knew a different way to solve it. They all did it two times before. I went down stairs for a few minutes and when I’ve returned it was quite again. They’ve reached the common ground. Pair programming worked. In the last session I had a pair of three who were intrigued by the no-ifs exercise and wanted to try it instead of the mute session. They almost did the implementation in 45 minutes. At the closing circle everyone shared what they’ve learned. If I had asked the same questions at the beginning of the day, I am sure I would have got very different answers then the ones at the closing circle. This proves that it was a good experience for everyone. It was a nice reward, to see developers happy because they have done TDD and pair programming and that they have learned something. Some did this for the first time.

Most of the participants asked to have more code retreats. There were many suggestions to have one each month or one every two months. Given the interest I’ve seen in Cluj for this I think we are going to organize it again and again, but next time I will be also coding. Andrei and Costin said the same, they also want to code in the next code retreat. We all three were a bit jealous on the ones who were having fun coding and experimenting new approaches. So, who wants to facilitate the next code retreat in Cluj?

In the end, I want to thank to everyone who contributed to this great day starting with each participant and ending with Corey who started it. I had a great experience. Thanks!

GDCR 1GDCR 2

You can see some more pictures on our facebook page.

P.S. Special thanks to my girlfriend Georgiana and my brother Mihai for helping me with the organizing work.

P.P.S. A big thanks to our local sponsors: ZenCash.com, ISDC, accesa, TSE Development Romania, Endava, Kno and ULLINK.

Posted in Uncategorized | Leave a comment

Mirrored Unit Tests

I’m not sure if the term of Mirrored Unit Tests actually exists, but I’ll explain in this post what I mean by it.

You get this situation when you have a class under test, which has symmetric public methods, which change the internal state of the class and have logic that depends on the fact that one method was called before or not. To test this for one method, you will have to have tests for scenarios in which the other method was called or not. Then you will have to rewrite the same tests for the other method, in a very similar way, like in a mirror. From where the term: Mirrored Unit Tests. No matter how much you will try to remove duplicate code by extracting it into helper methods, your test code will get messy.

The solution, is an abstraction (of course J ). You make an abstract test class, in which you implement the tests for one method. Then you implement the abstraction for each method you wanted to test and you override the protected members that abstract the method under test. With this test design you get rid of the duplication and it works nicely with most of the unit testing frameworks.

Below I will detail this more, by giving an example.

I have a class which is used in an implementation which builds a lambda expression, from some other representation of code (less important for this example). The class looks like this:

class BinaryExpressionBinder
{
        private Expression left;
        private Expression right;

   	public Expression ResultedExpression { get; private set; }

        public void NotifyForRightNode(Expression rightExpr)
        {
            bool constantExpr = TrySetAsConstantExpression(rightExpr, LeftWasSet);

            if (!constantExpr)
            {
                right = rightExpr;
                SetFieldExpression();
            }
        }

        public void NotifyForLeftNode(Expression leftExpr)
        {
            bool constantExpr = TrySetAsConstantExpression(leftExpr, RightWasSet);

            if (!constantExpr)
            {
                left = leftExpr;
                SetFieldExpression();
            }
        }

        private bool LeftWasSet
        {
            get { return left != null; }
        }

        private bool RightWasSet
        {
            get { return right != null; }
        }

        private void SetFieldExpression()
        {
            if (LeftWasSet && RightWasSet)
            {
                BinaryLogicalExpression be = new BinaryLogicalExpression
                    {
                        Left = left,
                        BooleanOperator = op,
                        Right = right
                    };
                ResultedExpression = be;
            }
        }

        private bool TrySetConstantExpression(Expression memberExpr, bool otherMemberWasSet)
        {
           // some logic which is not relevant for this sample. 
           // This logic may set the result with a constant expression
        }
}

The important thing to notice is the two public methods: NotifyForRightNode() and
NotifyForLeftNode()
. They are symmetric: both in signature and also in implementation. They try to set the result as a constant expression. If that fails it remembers the notification argument and if the notification for the other node was called, then a binary expression is set as result. It is important to remember that the binary expression can be built only when both members are known.

Now let’s see how to test this. I will need to write unit tests against the public interface and not to relay at all on the implementation details. In this case I would need to write tests for NotifyForRightNode() with at least the following scenarios: left node was not set yet, and a constant expression can or (other scenario) cannot be built; left node was already set and a constant expression can or (other scenario) cannot be built. So at least four scenarios for NotifyForRightNode(). Now the same tests have to be for the other method
NotifyForLeftNode()
, but in mirror (configuring that right node was set or not). As I said above, I will write the tests only for one method, in an abstract test class and then I will override just to specify the method under test.

    public abstract class BinaryExpressionBinderTests
    {
        protected abstract void NotifyForNodeUnderTest(Expression expr);
        protected abstract void NotifyForOtherNode(Expression expr);

        protected BinaryExpressionBinder Binder;

        [TestMethod]
        public void NotifyForNode_OtherNodeWasNotifiedAndConstantExpressionCannotBeBuild_ResultIsBinaryExpression()
        {
            //arange
            Binder = ConfigureBuilder();
            Expression dummyExpr = GetDummyExpression();
            NotifyForOtherNode(dummyExpr);

            //act
            NotifyForNodeUnderTest(dummyExpr);

            //assert
            Expression actual = Binder.ResultedExpression;
            Assert.IsInstanceOfType(actual, typeof(BinaryExpression));
        }

        // other tests ...
    }

    [TestClass]
    public class BinaryExpressionBinderTestsForLeftNode : BinaryExpressionBinderTests
    {
        protected override void NotifyForNodeUnderTest(Expression expr)
        {
            Binder.NotifyForLeftNode(expr);
        }

        protected override void NotifyForOtherNode(Expression expr)
        {
            Binder.NotifyForRightNode(expr);
        }
    }

    [TestClass]
    public class BinaryExpressionBinderTestsForRightNode : BinaryExpressionBinderTests
    {
        protected override void NotifyForNodeUnderTest(Expression expr)
        {
            Binder.NotifyForRightNode(expr);
        }

        protected override void NotifyForOtherNode(Expression expr)
        {
            Binder.NotifyForLeftNode(expr);
        }
    }

So, less code, lower maintenance costs. It wouldn’t be right to test only one method, even though the VS (or other measuring tool) would say that I have a good coverage. The good coverage comes only because my implementation avoids duplicates and calls helper methods. What I want is to have a good coverage and this not to depend on the implementation. When I will refactor the production code, my tests have to stay green and valid without the need of being adjusted. Because that’s how good tests are!

Posted in Unit Testing | Leave a comment

Good Unit Tests Ask For Quality Code

I’ve talked this weekend at Code Camp Cluj about good unit tests and quality code.

Here are my slides and  here is the code I’ve demoed.

Posted in Uncategorized, Unit Testing | 2 Comments

Resharper templates for Unit Tests

I am sharing here my resharper templates that I use. You should be able to easily import them.

The most useful one is the TestMethod template:

[TestMethod]
public void MethodUnderTest_Scenario_ExpectedBehaviour()
{
     Assert.Fail("Not yet implemented");
}

It follows the unit test naming convention proposed by Roy Osherove in his book “The Art Of Unit Testing”. Naming your unit tests like this it helps you in writing good unit tests, because it foces you to keep your tests simple and test only one thing. If you cannot name the test method like this either you’re testing more than one thing, either your test is too complex, so you cannot name the test scenario. If you’re in the last case consider to refactor your production code.

Another great advantage I’ve found by following Roy’s convention is that I can easily know, just by looking at the test run report, where the bug is when a test fails. This way I reduce my debug time to almost zero for the code under unit tests and this gives me a higher efficiency.

Posted in Unit Testing | Leave a comment