I hear a lot about model based testing the latest few months. I must say that I like the idea a lot. Just generate all your tests out of pictures. These pictures describe the system that is unter test. And so this is our model.
Still there are no decent tools to perform such automatic tests. There are runners that will do something with your picture (or graph). This are the test runners. I see it as a kind of robot framework or other tools, that will run something.
The creation of images, that is a problem too. There are no decent tools in open source that can draw easily such images. At least not that I am aware of. DotEditor is a tool that can be used, but is missing some extras like sequence diagrams.
And then the combination of both, does not exist in open source. As I know at this moment. As a lot can be changed in a few days, I hope that in a few months, such opensource tools do exist.
Let's talk about the graphs itself. It is difficult to create a decent model of the product we are testing. Suppose we have a button in a user interface that shows us the word "START". If we press the button, the word will change to "HALT". If the "HALT" button is pressed, the word of the button is "START" again. If we do nothing, after a short time, the button also will change again to "START".
This is a part of our system. We take an image grab. Because our user wants to cancel that operation, the interface allows it. And after a timeout, the action is aborted anyway. This action can be modeled in a few states.
This model can now be imported in a runner framework. That will run through this graph, maybe also generates code for this. The latter does not exist yet I think. So time to create some frameworks ourselves?
I created this blog because of a discussion that I found on a wiki in our company. The situation is as follows. A developer has done a code review of another developer and just added a review comment with a tag [wtf]. Because of the tag wtf the other developer wrote a blog post that some persons could be offented by the wtf word.
I do agree on that, but some developers did not see the problem. It was just for mentioning a trivial problem that everybode knows. But is this the case? When does a problem is trivial, what is in a programming language something that everybody knows?
Purpose of reviews
Before continuing of my own opinion, let's have a look at what the purpose of a code review can be, because there is no one-answer-to-rule-them-all. A couple reasons are:
- Finding defects or opportunities for improvement. Code and data can be examined to find weaknesses.
- Education of other (new) developers. Ensure that everyone sees the modification associated with a defect fix or enhancement so that they can understand the rest of the software.
Moral of the team
When a code review is introduced, some people see it as a thing that will ruin the team culture. They say that some people will be jerks about code review and use the opportunity to terrorize others.
The goal of code review is to make the software as bug-free as possible, and to teach and learn in the process. When the right attitudes are set up front, most teams unite around the concept of becoming a better team, learning from others to become better developers, and producing better products. It gives developers a framework for communication, which is a very good thing. Once they start communicating online, it’s amazing how much better they work together in person.
Of course, occasionally team members use code review as an opportunity to try to establish superiority over others. I found bugs in your code! That must mean I’m smarter than you! In fact, clearly you’re an idiot. This attitude is obviously not productive. By fostering a culture of respect and open communication, you can set the tone for more positive attitudes. Everyone makes mistakes, and these mistakes should be viewed as opportunities to learn and mentor.
Another common problem team member is the control freak, who uses his or her seniority or greater experience to terrorize less knowledgeable team members. A good technique for getting this personality type to play nice is to explain to the tyrant that he is a teacher, a guru, a guide, a mentor to everyone else. Teachers don’t berate their pupils, they take pride when pupils learn at their knee. This approach lets your control freak retain control and status, but in a helpful way.
If you set the stage right, code review doesn’t ruin your team culture, then it improves the culture!
Be careful of your tone
That leads me to a lesson that is mentioned in Cem Kaner's book Lessons learned in Software Testing. It is about a bug report, but it can be applied to code reviews too.
Lesson number 86 is stating:
No benefit is gained by adopting a blaming or patronizing tone in your bug report. It never pays to call the programmer unprofessional, closed-minded or a fool. It might feel good in the moment, but you lose credibility invite micromanagement of your work and will be les likely to get many of your bugs fixed. Watch your formatting too. For example, reports written in ALL CAPS read as though you were screaming. If you're not sure how the report wil be read, have someone else read it and LISTEN carefully to their comments. If tone has been an issue for your or for some programmers in your company, try reading your report to yourself out loud. Use your voice to make the words sound threatening, sarcastic or callous. Another approach to checking tone is to hand the draft report to someone youtrust for their review.
This is the same for code reviews, be polite. I want to say more, say also something good about the code. Even if you find a lot of problems in someone's code, there is always some nice and very good things too. Make comments on that good part too. Positive comments remind the coder that there is still a lot to learn, but that he still adds value to the system.
That leads me to my point. The WTF word can be offensive that's for sure and it is not helping the moral of the team. Some nice tips from my point of view are:
- Be respectufull and patient, rememeter that not every team member has the same knowledge or experience as you. At other domains, that same team member has more experience as you. Would you be treated that you where a stupid person on that domain?
- Remember, everybode make mistakes, even you.
- Ask a question instead of making a three or four letter word. Ask the author to explain the reasoning behind something. This will acknowledge that you respect him or her.
- But be aware, do not ask accusatory questions. It is better to ask What did you have in mind when ... than Wy didn't you ... The first question opens a door for dialog and learning.
This are a few tips that I can give on code reviews and bug reporting. Remember, all team members are on the same boat. If the moral on the crew is getting down, the boat never reaches new lands.
Our repositories have a lot of branches, which is good. Because every branch is the result of a new feature or bug fix. When the code in that branch is ready to merge, our process is to create a merge request on our gitlab server.
That branch will be deleted after a merge has been accepted. Gitlab provide us with a check box in the window where we can accept a merge request. But because it is not set by default, it can be forgotten though and then the branch will not be deleted. In that case, you as user of the repository should delete it yourself.
To delete that branch after it is merged can be done with a simple command:
git push origin :the-merged-branch-name git branch -d the-merged-branch-name
If this is not done directly, we forget about it. Which remote branches are already merged in the master branch? Git has also a command for that of course:
git branch -r --merged master
There is also a command that shows the remote branches that are not merged:
git branch -r --no-merged master
In python you can have a class with variables. Sometimes you can have logic behind some variables. For that reason, I assume the property decorator is invented. I was not happy with it, because I wanted some code in a seperate class, so I needed the descriptor syntax:
class MyProperty(object): def __init__(self): self.name = "" def __get__(self, instance, owner): return self.name def __set__(self, instance, name): self.name = name class Container(object): name = MyProperty()
This is the syntax of a property. Now an instance of the Container class can access the property name and then the logic in MyProperty is called. Simple. But.
That is not what I wanted. I wanted that the properties where created dynamically. This is because the program I write is a wrapper around a kind of language to talk to our backend service. I had to test the backend service. The service has a kind of list function and that function, which returns the complete interface towards the backend itself. So I can easily generate my own classes to interact with the backend at run time.
After a long search, I found the way to create the properties in a dynamic way. The build in function setattr is our rescue:
class Container(object): def create_dynamic(self, name): setattr(self.__class__, name, MyProperty())
Now I can create some things and the property is dynamically named. In this way, I can send different names and different commands to our backend with code that is generated at run time.
If for a reason the descriptor needs to be deleted, delattr is a nice function too.
The first time you set up git, you should identify yourself and set your user name and email address, because every commit contains this information.
It can be done in a system wide configuration by:
git config --global user.name "My name" git config --global user.email email@example.com
Sometimes you have a different mail adress for different repositories, then you can change the setting of the mail adress in that specific repository by:
git config user.email firstname.lastname@example.org
Now the new mail adress is only valid in the second repository. Most of the time I personally forget to change my mail adress on some repositories. I keep work related and open source related code separate, so I do have more than one mail address.
What if I forget to change my mail address and have already committed some commits? In that case there are options, depending on the situation.
Suppose only the latest commit should change from author. This is the easy one. Just enter:
git commit --amend --author="My New Name <email@example.com>"
Now you should just save your commit message and everything is al right.
Suppose that for example some other commits should change too. There is where interactive rebasing becomes important:
git rebase -i HEAD~5
An editor pops up and you can change the pick to edit, save and exit the file editor. Now the process begins and stops with some message that if you are done, you can continue with a command. At this time, the first command becomes in mind again. Just enter again:
git commit --amend --author="My New Name <firstname.lastname@example.org>"
Save it all and afterwards continue the rebase with:
git rebase --continue
After the rebase, the author has been changed. It is a little more work if you have more than one commit to change, but it is possible.
Note that it is also possible to do this all in a script that uses filter-branch, but I did not try that one (yet).
In git there is an option to disable fast forwarding during a merge:
git merge --no-ff <branch>
It could sometimes usefull if for all merges this fast forwarding is disabled by default. This can be done per branch:
git config branch.master.mergeoptions "--no-ff"
Now all merges are done without fast forwarding. I personally prefer that fast forwarding is enabled because after merging, the original branch is deleted anyway. But in some projects I am part of, the default is to disable fast forwarding.
We had already a few months a problem on the machines touchscreen that our interface behaved differently with a finger swipe as with a mouse drag and drop. The problem was that swiping from left to right was navigating to the previous page. And swiping the other way around was taking us to the next page.
Because a customer does not need to know that our interface is in fact a html page, this is unwanted behavior from user testings point of view. In the options of Chrome itself I could not find any options that could explain this behavior.
But there is a solution. Just start chrome or chromium with a command line switch:
Did you know that chrome has a lot of command line parameters? Look at Peter Beverloo’s page for an overview. You see, as a tester you also need to think how we can solve bugs, because not all bugs are code related.
During the process of setting up a protractor test framework, I had some problems about our system. It was again the same problem as I had before. The intension of the test framework is that the testing framework can run on our integration server. So this means after each build or maybe only at night, because this contains end to end tests and running them can take a lot of time in the future.
To run on the GUI, the protractor tests need to start up a backend. That seems logical, isn’t it? Then the tests are running. Afterwards, the backend needs to be shut down. This is where the problems begin. Our system is not setup with automated testing in mind. This means that there is no way of shutting down the backend. How do I shut down or kill that process then?
There seems to be a solution. In windows, there might be a command that is called taskkill. This program acts like the kill command in unix environments. It is not that good, but it can kill the cronos.exe backend from a batch file when the tests are done.
The command I placed in my scripts are like this:
taskkill /F /IM cronos.exe
After that I can run my test script again and again without worrying about remaining processes.
Sometimes I want to know which is the current revision in a repository that I am on. I always did just git log and watched the output. But log has some nice features, it can almost output everything you like it in the way you want. To show the short revision number, just running:
git log --pretty=foramt:'%h' -n 1
is enough. Of course you can create an alias for it:
git config --global alias.revision "log --pretty=format:'%h' -n 1"
I hope this is a usefull tip.