Wednesday, September 9, 2015

What do software development and Chinese medicine have in common



I am not a fervent fan of Chinese medicine, I could be, but Chinese medicine is so mysterious and so magical that often times I feel lost. But then once in a while, I got to understand Chinese medicine a little bit more, and my fervor with Chinese medicine rises a little higher.  

My official job is about software development, now it seems software development and Chinese medicine is very different, one is very logical, the other, well, as we say in China, can only be understood through “” (googled, couldn’t find English words that translate it well, it is sort of “using your heart to feel”, not “using your brain to analyze”, Chinese culture is full of this stuff, sometimes I feel they are just bullshit, but it is bullshit that only a Chinese can understand). But I’ve found some interesting common things between software development and Chinese medicine.

Think of the big picture

 

The biggest critique for the west medicine is that it “treats the head when the head aches, treats the foot when the foot hurts”. With Chinese medicine, it is completely different, if your head aches, it is very likely not because something is wrong with your head, it could be that your Qi and blood is low, it could be your liver Yang (Yang of Yin Yang) is high, it could be many many other things. A good Chinese medicine practitioner is able to detect what is wrong with your body without the help of so many modern sophisticated medical instruments. In Chinese medicine, that is called “辨证” (again, couldn’t find good English words to translate it, it is sort of “finding out all relevant symptoms, figuring out possible causes, deciding on the true or major causes, considering contributing factors, and working out a recipe to treat the causes and contributing factors”)

As a software developer, you should also think of the big picture. As a sometimes compulsive person, I want to make a feature perfect before moving on to the next, and I have often regretted: the feature I spent so much time perfecting turned out to be either wrong or not required any more. I indulge my compulsion from time to time, but I always remind myself to look at the big picture. 

As a software manager, it is even more important to think of the big picture – it has a more formal word in software management “prioritization”. It is actually a very difficult thing to do. In order to prioritize different agendas, you have to know how to gauge these agendas, which requires you to have an understanding or educated estimation about their prospects, and you need to have good negotiating skills to convince others to agree on the prioritization. If you do not do prioritization, your team will be overwhelmed, lose focus and lose morale. 

It is not an easy thing to think of the big picture in Chinese medicine either. If it was that easy, I should have opened up my little clinic now. The art of “辨证” is very hard to grasp, and “feeling with heart” can be very tiresome.

Step back and take a different look

 

Although I haven’t become a Chinese medicine expert, and it will likely take the rest of my life to hone my skills, several years of self-study and self-treating has yield one benefit: I am now more in tune with the signals my body sends. When I feel more compulsive than usual, when I keep working on some coding problem and can’t drag myself away after several hours of futile trying, I know something is going wrong with my health. I used to think my body and my brain were separate entities, when I felt my brain was a muddle (which was a common experience several years ago), I thought I could sober it up with lots of coffee. Now I know that it is because the moist in my body has accumulated, risen up and clouded my brain – I realize that when I translate Chinese medicine like this, you probably think I am crazy and Chinese medicine is just voodoo. 

Studying Chinese medicine has enabled me to look at myself and the world in a different way. Even with my little Chinese medicine knowledge, I can see some symptoms from some people, and can’t help but feel sympathy for them. 

When coding, sometimes I trap myself into a corner, trying to solve a problem using the same way again and again. Nowadays, I know that I should get out for a walk or run, stop thinking about the problem, let it cool for a while, pick it up and look at it in a different way. Sometimes I get inspiration just by going for a walk. 

Being a software manager it is very important to lead the team to think from users’ point of view. Too many failures are caused because software teams fail to think about users’ pain and impose their likings on their “imaginary” users. 

It is interesting to use two very different ways of thinking: one is very logical and the other is “”. But sometimes when I feel blocked in learning Chinese medicine, I think maybe I can write an application to help me analyze the huge data of Chinese medicine knowledge and provide “辨证”. This is completely against "", so it is a bad idea ...



Tuesday, September 8, 2015

Double automation as performance test



My system under test is so clunky, that I can observe performance differences between builds. That gives me an idea to double automation as performance benchmark test. 

The implementation is very simple: for important actions, automation cases will log their start and end time and save them to a database; a web application will analyze and show reports of performance comparison.



I am fairly new to JavaScript world, if it was in Java, logging time of important actions is a cross-cutting concern and would be implemented through AOP. But in my test framework, I just created a utility class and throw it into places where it is needed.

var ActionRecoder = function () {}

var actionStack=[];


ActionRecoder.
prototype.renew=function(){
   
this.actionList=[];
   
this.caseHardWait=0;
}

ActionRecoder.
prototype.bastart=function(action, actioner){

   
logger.info();
   
logger.info();
    actioner=actioner ||
glue.operator;
   
logger.info("*********************"+actioner+" started "+action+"*********************");

   
this.dostart_(action, actioner, true);
}


ActionRecoder.
prototype.bastop=function(){

   
var lastAction=actionStack.pop();
   
logger.info("*********************"+lastAction.actioner+" exited "+lastAction.action+"*********************");

   
this.dostop_(lastAction);
}


ActionRecoder.
prototype.start=function(action, actioner){

    actioner=actioner ||
glue.operator;

   
logger.info(actioner + " start:" + action+"~~~~~~~~");

   
this.dostart_(action, actioner);
}


ActionRecoder.
prototype.stop=function(){
   
var lastAction=actionStack.pop();
   
logger.info(lastAction.actioner+" stop:"+lastAction.action+"~~~~~~~~");

   
this.dostop_(lastAction);
}

ActionRecoder.
prototype.dostart_=function(action, actioner, isBusinessAction){

    actioner=actioner ||
glue.operator;
    
actionStack.push({actioner:actioner, action:action, start:new moment(), businessAction:isBusinessAction});
}

ActionRecoder.
prototype.dostop_=function(lastAction){
    lastAction.
end=new moment();
    lastAction.
duration=lastAction.end.diff(lastAction.start,"milliseconds");
    lastAction.
start=lastAction.start
   
lastAction.end=lastAction.end

   
this.actionList.push(lastAction);

   
return true;
}

There are two kinds of actions. My automation test framework is built around domain objects so that overtime, it becomes easier and easier to write automation test cases:

A Login.login is a business action, it involves opening up the login page, entering user name and password and clicking on the login button. A login.login.clickBtnLogin is a finer action, it records the time the login button is clicked and the result page is shown.  Recording finer actions helps tracking down performance issues. 

One thing to look out for is that because in Protractor almost all actions on a UI is a promise, ActionRecorder.stop has to be invoked in then . My automation test framework uses generator, so I can just invoke it at the last step of the function. 

3 levels of data are recorded, one is for action:

One is for test case:


The final one is for test suite:


The web application is much more fun, I used React, D3 and Nodejs to build it. This diagram shows the comparison of action “Login.login.clickBtnLogin” between builds 490 and 678.

This kind of comparison serves to give an overview, but it doesn’t make much sense: login of different users will have different performance, even the same user, login in different context will have different performance, so comparison has to be done between apple and apple. 

This configure page allows to configure apple and apple comparison:

And here is the result:

The column underneath the zero is where build 678 is quicker than 490,  above is where build 679 is slower than 490. 

I am thinking now if automation can triple as stress test. Because my automation uses Protractor which uses Selenium, first I need to figure out the stress level of Selenium. Stay tuned.