10/25/2019

How to unit test a private function in C++

Introduction
Automated software tests are becoming more and more popular. Thank for the idea of Test Driven Development (TDD) unit tests are used more often and often.
To implement unit tests first we have to define what is a unit? In object oriented environment usually a class is encountered as a unit. So that in case of unit testing we are testing the behavior of a class.
One way of thinking here is that only the public interfaces needs to be tested, since the private ones are only used by the public functions of the class, so if someone if using are class from outside, only uses the public interfaces and don’t have knowledge about the private ones. This is also true.
On the other hand one important KPI is the code coverage and to reach 100% code coverage the easiest way is to test the private functions separately. In some cases the private functions are really complex and it is difficult to test all they corner cases through the public functions.
So there is a need for testing private functions. But it is not so trivial to do it, since private functions are not callable from outside of the class.
I collected some possible solutions for testing them. The solutions are dedicated to C++, but most of them can be also used with other object oriented programming languages.

Possible solutions



  1. Friend class


In C++ a friend class of a class can also see its private attributes and functions. So make your test fixture class friend to the tested class and you can unit test its private functions.
However it has the disadvantage that you have to modify the code of your tested class (by the line adding the friend class). So this solution is not too elegant.


#include


class UnitTestClass;


class ToBeTested
{
private:
    int Calculate() { return 0; }
    
friend UnitTestClass;
};


class UnitTestClass
{
public:
    void RunTest()
    {
        ToBeTested object_under_test;
        if (object_under_test.Calculate() == 0)
        {
            std::cout << "Test passed" << std::endl;;
        }
        else
        {
            std::cout << "Test failed" << std::endl;;
        }
    }
};


int main()
{
  UnitTestClass unit_tester;
  unit_tester.RunTest();
  return 0;
}


  1. Define private public


In c++ preprocessor directives gives you a lot of chances to cheat. You can just put such a code into your test file:

#define private public
#include
#undef private

Ugly, right? But it works...

  1. Make it protected and inherit


You can change your private functions to protected, so that they have the same behavior until you are not inheriting from your class. And now you can inherit your test fixture class from you class under test, so that you can reach all its protected functions.
The dark side of this solution that you are changing your production code only for testing purposes and you are making it less safe in case of inheritance.


#include


class ToBeTested
{
protected:
    int Calculate() { return 0; }   
    
};


class UnitTestClass : ToBeTested
{
public:
    void RunTest()
    {
        if (Calculate() == 0)
        {
            std::cout << "Test passed" << std::endl;;
         }
        else
        {
            std::cout << "Test failed" << std::endl;;
        }
    }
};


int main()
{
  UnitTestClass unit_tester;
  unit_tester.RunTest();
  return 0;
}


  1. Move it to a separate class


The solution which in letting your code done in the most object oriented and in the most clean way is to move the function to be tested into a new class. So if you have for example a complex Calculate private function in your class, which should be unit tested, just move it to a new Calculator class. Or to a class which is a collection of helper functions. And add a private member of your new class to your old class. In this way your code will be more testable, reusable and thanks to technologies like dependency injection you can exchange your algorithm in a more elegant way in the future and you can also easily mock it to unit test the other parts of your class. This is the solution which I prefer, since in this way you will have smaller classes, with clear, well-defined responsibility.

#include


class UnitTestClass;


class Calculator
{
public:
int GetResult() { return 0; }
};


class ToBeTested
{
private:
    Calculator calculator;
    
};


class UnitTestClass
{
public:
    void RunTest()
    {
        Calculator calculator_under_test;
        if (calculator_under_test.GetResult() == 0)
        {
            std::cout << "Test passed" << std::endl;;
        }
        else
        {
            std::cout << "Test failed" << std::endl;;
        }
    }
};


int main()
{
  UnitTestClass unit_tester;
  unit_tester.RunTest();
  return 0;
}

Summary
There are several other hacks which makes you able to test private functions, like playing with preprocessor directives, or use FRIEND_TEST option of GTEST, but at the end of the day these are all just versions of the solutions which I previously mentioned.

The best and most preferred solution is absolutely language independent: make your architectecture clean. This is always a good way to create nice software.

10/10/2019

Experiences with Large Scaled Scrum - Part 2

Introduction

In my previous post I already went through several points regarding my experiences with LargE Scaled Scrum. In this post I would like to extend that with some additional topics, like how do self-organized teams work, when to use LeSS and how to be a perfect developer in a LeSS structure.

Self-organized teams

In the LeSS process developers are working in self-organized teams. One team consists around 7-8 developers. Each team is supported by a scrum master. Based on my experience working as a team is at least as important here as being self-organized. I used to work at several places, but I have never experienced such a close teamwork yet.

Becoming a team from individuals

Earlier wherever I worked teamwork meant that we were several developers working different tasks which are connecting to each other in a way. So everyone did their own tasks and sometimes we synced up about our status and if someone got stuck we helped each other.
But in fact it is not a team work, just a synchronization between individuals who are working on their own tasks.
In case of LeSS it is slightly different. First of all, the team can decide which items they are taking for the upcoming sprint, they can decide what is the amount of work they can overtake. Usually the amount of items is less than the size of the team, so that multiple people are working on the same item. In extreme cases the whole team is working on one item.
The tasks are not assigned to one individual, everyone is working on them and the related responsibility is also shared within the team members. So there’s no “my task” and “your task” only “our task.
How is it done in practice?
One radical way of doing it is mob-programming. So that the whole team (or at least several members of the team) is sitting in front of one big display and they are solving the tasks together. Someone is handling the keyboard and the mouse (leading the mob-session), the others are telling them what to do. After a certain time the leader of the mob-session should be changed.
To be really honest in practice we are rarely using this method.
In our case we rather prefer pair programming, or individuals who are taking really small pieces of the big task.
If the team is doing well that has the following consequences: everyone is aware about the whole code base and all technical decisions, everyone can overtake the tasks from another without long ramp up time (it is really useful in case of a sickness), everyone can do technical discussion about any item being done in the team (because the needed background knowledge is given).
Of course it sounds too idealistic and we also can not always reach this state, but we keep on tending in this direction. Regular technical knowledge transfer sections are also required.

Unofficial roles within the team

Within the team officially everyone is equal. There are no leaders, no dedicated persons for different kind of tasks (software design, testing etc.), everyone is free to take part in any meeting (LeSS ceremonies, discussions with the customer, etc.).
However with time some unofficial roles are being set up within the team, even if noone is talking about that clearly. The team will realize with time who has the best knowledge in a dedicated field, who is the best candidate for fast bug fixes, who is the best in conceptual work, who is the best at communication with the customer, who can motivate the team members, who can help to resolve personal conflicts etc. And with time these people will be preferred to overtake specific tasks.
I think this is pretty fine, just the team should make sure that other team members also get a chance to take part in such activities to be able to improve themselves in that direction. The best is such activities are overtaken by the “expert” and some less experienced team members, so that their knowledge level will get closer to each other.

All-days reality show

Most likely until know you realized that this way of working requires a lot of interacts between the team members. Most software developers prefer to sit alone, listen to their favourite music and deep into their work while avoiding any communication with the others.
In case of the working model it can not work like this. Since the tasks and responsibilities are shared you have to communicate frequently with the others. In can of pair of mob programming sessions you are basically communicating all day long.
Most of the software developers are not really prepared for so many interpersonal contact. I was also not really prepared, I did not expect it. But fortunately most of the developers can adapt themselves, even if it is not so easy. It requires a big improvement of several soft skills (communication, time management, conflict handling etc.).
If you are working so close with the others you will know their personality very well after a short period. You will know both their strengths and weaknesses. And most of the people have some weakness which is difficult to tolerate: being self-fish, self-driven, not accepting different opinions, aggressive communication etc. Facing with the characteristics often leads to conflicts within the team, especially during the first period.
So very often I feel myself like watching the Big Brother reality show. But this time I’m also part of that. It is not easy to resolve all the conflicts and keep a balance inside the team.
I’m pretty sure that it would be a good research topic for a psychology student.
To resolve these issues good retrospective meetings are needed with a very open manner.

Life without home office

To work in such a close cooperation is only possible if the whole team is placed in the same office. Of course there are a lot of modern tools available, but pair or mob-programming sessions can not be really done in an efficient way if the participants are not sitting next to each other.
It also means the doing home office regularly is not really possible with this working model. I encounter it also as a big disadvantage, since home office opportunity is a really common and comfortable benefit if someone is working as a programmer.

Different knowledge level within the team

It is also challenging that the different team members have different experience and level of knowledge. It differs topic by topic and also overall. In the way of work the junior developer with only a few months of experience and the senior developer with decades of experience is working together on the same tasks. And it can be challenging for all participants. The team should always pay attention on the members with lower knowledge level to give them the base knowledge which is needed to understand the current tasks and the less experienced ones needs to make a lot of effort to extend their knowledge.
Regular knowledge session meeting are helping a lot on this issue.
And if you are working in such a team and you don’t clearly understand your task: don’t be shy to ask the others, don’t stay without a clear background knowledge. You have to learn always something new. One hand you can just read after the topics, on the other hand you can turn to your teammates.

How to be a perfect member of an agile software team?

As I joined the team there were a lot of things which were pretty strange for me, it is really different than anything I worked with earlier. It took me some time to figure out how to be a useful member of such a team. I collected some suggestions you should do if you find yourself in a LeSS team:

  1. Find some tasks for yourself always in a proactive way
In a LeSS team you don’t have dedicated tasks assigned to you. So if you have nothing to do noone will go directly to you to give some tasks. Be proactive, always ask your teammates whom you can join or support. It also helps a lot if you are aware of the status of the others.
  1. Always share you task and knowledge with the others
If you know something that others don’t know: just tell them. And always let the others know what you are doing and how you are doing it. Ask them for their suggestions accept their ideas. It is even better if you are not the only one working on the task.

  1. Always give a clear feedback about the status of your work
    On the daily stand up meeting always tell your real status. Don’t tell that you are almost done if it is not true and don’t tell that you know everything if it is not true. It would just mislead your team and make it unable to close the items until the end of the sprint.
  2. Always try to understand all topics which are being in progress in the team
    It can be that you are not strongly involved into all items, but you should have at least an overview: pay attention to daily stand ups, check the commits of the others in the version control system and ask if something is not clear.
  3. Always try to understand your team mates
    If your teammates have an idea or solution which is not clear to you you should always take the time to understand it. You will never be able to discuss technical topics if you are not on the same page.
  4. Let’s accept the ideas of other if you not strongly disagree.
    It is really typical that different teammates have different solutions for the same problem. But it is not good if you are sticking to your idea. Always accept the idea of others if you don’t see any big issue with that.
  5. Be chilled and patient
Don’t be stressed. That just makes the life of your and the team more difficult. Always be patient with your teammates.

Agile and future

Is it really the future?

I heard many times that classical development frameworks (Waterfall, V-Model etc.) are the past and agile is the future. First of all we have to see that most of the companies and teams calling themselves agile are not agile at all. They are just renaming the roles and the meeting of the classical processes.
The world of programming is becoming faster and more flexible. Requirement changes becoming more frequent and due dates becoming shorter. Agile methods provides good solutions for these problems. From this purpose they are pretty clear the future.
But there is still the other side: one popular point against agile frameworks if that quality management is much more difficult in such frameworks. It is exactly because of the frequent change of requirements. But we have to see that software are becoming more and more safety critical: they are driving cars and aeroplanes, they are responsible for transferring of dollar billions etc. I see it as a big challenge to reach the quality which is required by such functionalities in an agile framework.
The other point that the scale of programming languages, methods and frameworks is getter wider and wider. It is really challenging to keep yourself up to date as a programmer with all the changes in such an environment. That means it is really challenging to be a generalist software developer, specialization into a certain direction is becoming more and more necessary to be able to keep up to date with the changes. But the whole SCRUM and other agile frameworks are based on developers with general knowledge and not on specialists.
So in my view there’s a place for agile, but there is still need for classical software development methods.  

Summary

After 6 months of working in a LeSS team I really have a lot of topics to write about. That is good, it means that I learned a lot during this period. I found new ways of working and I collected more experience in cooperating with others.

I think every developer should try out this way of working and it could help for a lot of projects, but it is not the best for everyone and not for every project.

How I prepared my first online course

Since long I didn't publish anything here. It's because I was busy with some other topics, but now it's time to share the result...