New Wave of Test Automation

If you haven’t heard, there is the new more efficient way to build functional end-to-end tests for your web or mobile application, this test automation tool

It allows non-technical users to be able to easily and quickly build test automation 15X faster than QA engineers with Selenium.

This is how to use it:

Advertisement

What do we want from log. Logging with SLF4J, logback and guice

Why do we need logging

Yes, really, why do we need it in a first place? Usually we use logging for the

following:

  • Errors/exceptions monitoring and debugging purposes (in more generic sense);
  • Non-time-critical statistics/analytics;

I’d say first one is the primary purpose and second is usually secondary. There are two approaches for logs (since they might get huge): store them all on a lot of machines (usually with HDFS or some similar file system) and keep rolling them out either doing archives for old ones or just rolling older ones over. For this post I will stick to second scenario only.

What do we want from logging?

Basically, usually it is simple:

  • Not to overrun space on hard drive;
  • Must have a fixed list of files where older ones are rolled over;
  • Naming of files in the list should be based on date/time;
  • There should be easy way to inject logging into our DI framework.

Issues with it

1. Guice Logback integration 2. Lockback rolling policies;

Solutions

Learn new words new way

My wife (and myself, of course) keep studying new words in English. Initially my wife would print them out on paper and study this way. But I though I could come up with a better idea. Since we are Netflix-addicted movie lovers we got ourselves a HDTV and a device to run Netflix on it. So I thought: if we already have this TV why not connect to one of my old notebooks to show words automatically on it? Which we did and I wrote a simple python script to show words and translations from file in full screen mode on the main screen.

Now because we were constantly plugging and unplugging HDMI cable to/from poor notebook, at some point it just couldn’t bare it’s hard luck anymore and decided to kill itself. Poor thing. I dogged another even older one (with VGA, no HDMI) but that one was also already dead. In the face of this mass computer suicide we decided to purchase something silent and VERY cheap and Bingo! NewEgg brilliant website helped me to figure out that I can have a “Barebone” fanless PC. Sounds awesome. Double awesome because all we had to buy were the barebone system itself and 4Gb of memory. We got this ones:

barebone GIGABYTE GB-BXBT-2807 for $123

and memory 4GB 204-Pin DDR3 SO-DIMM for $43

and kept HDD from dead notebook body. So the whole computer cost for us was $166! I think it is and achievement of modern technology for new PCs 🙂

There are several of catches though:

  1. Despite the description of the barebone everywhere which says that it will support 8Gb, it will actually support only 4Gb because of Celeron N2807 processor limitation;
  2. Also you need to make sure that you have the memory with the right specs which is SO-DIMM PC3 10600 low voltage 1.35V memory. Since on most websites they wouldn’t give away voltage information I went with newegg itself which was very helpful;
  3. In order to setup Ubuntu on it you need to get to setup (by hitting “Delete” button during load) and select OS type as Windows 7 and boot device as your flash drive;
  4. For some magical reason (I couldn’t figure out why) you will not be able to get sound through your HDMI. It will show there like you’d have it, but no sound will actually sound on your TV at least in Ubuntu. This ended my dreams to make this magic box an ultimate media centre machine 🙂

Now the annoying part was that I had to convert whatever words my wife would give me to the text format my program would support and keep updating the file. So why not read it directly from Google Spreadsheet with those words which my wife share with me anyway? I researched the topic and found that yes, thanks to a cool Python library gspread it is possible!

So now it is super fancy: my wife would get new words on her phone from free Google translate app, copy-paste them with translation to again free Google Spreadsheets app, potentially add/edit them on her computer online in Google Drive and they would automatically be updated on HDTV when she is at home! Awesomeness of the technology! 🙂

Here is how it looks like:

And yes, you can see the code which I wrote with installation instructions here. I’m new to Python and never used GTK before, so the script might look not so cool to you if you are a pro, but it does the job.

Disclaimer: it actually took me probably more than a day in total to build this, since I needed to figure out all that full screen/label/font thing stuff and it potentially should work as a screensaver which I never tested though. I also tried to figure out how to use OAuth2 tokens with Google’s oauth2client library and couldn’t find it. They do have the code which would work perfectly with your website (worked for me) but tokens there expire in 1 hour, so it was not what I looked for and I didn’t find the code for desktop/longer living tokens, so had to end up with just username and password which I find more user-friendly anyway.

Strengths Finder

Strength Finder is a psychological test, for which I got a free pass by purchasing a book Go Put Your Strength to Work after First Break All The Rules by the same author. I’m very fascinated by the idea to focus on people strengths vs trying to fix their weaknesses. And here are my results: Signature Themes

Many years of research conducted by The Gallup Organization suggest that the most effective people are those who understand their strengths and behaviors. These people are best able to develop strategies to meet and exceed the demands of their daily lives, their careers, and their families.

A review of the knowledge and skills you have acquired can provide a basic sense of your abilities, but an awareness and understanding of your natural talents will provide true insight into the core reasons behind your consistent successes.

Your Signature Themes report presents your five most dominant themes of talent, in the rank order revealed by your responses to StrengthsFinder. Of the 34 themes measured, these are your “top five.”

Your Signature Themes are very important in maximizing the talents that lead to your successes. By focusing on your Signature Themes, separately and in combination, you can identify your talents, build them into strengths, and enjoy personal and career success through consistent, near-perfect performance.

Achiever

Your Achiever theme helps explain your drive. Achiever describes a constant need for achievement. You feel as if every day starts at zero. By the end of the day you must achieve something tangible in order to feel good about yourself. And by “every day” you mean every single day—workdays, weekends, vacations. No matter how much you may feel you deserve a day of rest, if the day passes without some form of achievement, no matter how small, you will feel dissatisfied. You have an internal fire burning inside you. It pushes you to do more, to achieve more. After each accomplishment is reached, the fire dwindles for a moment, but very soon it rekindles itself, forcing you toward the next accomplishment. Your relentless need for achievement might not be logical. It might not even be focused. But it will always be with you. As an Achiever you must learn to live with this whisper of discontent. It does have its benefits. It brings you the energy you need to work long hours without burning out. It is the jolt you can always count on to get you started on new tasks, new challenges. It is the power supply that causes you to set the pace and define the levels of productivity for your work group. It is the theme that keeps you moving.

Futuristic

“Wouldn’t it be great if . . .” You are the kind of person who loves to peer over the horizon. The future fascinates you. As if it were projected on the wall, you see in detail what the future might hold, and this detailed picture keeps pulling you forward, into tomorrow. While the exact content of the picture will depend on your other strengths and interests—a better product, a better team, a better life, or a better world—it will always be inspirational to you. You are a dreamer who sees visions of what could be and who cherishes those visions. When the present proves too frustrating and the people around you too pragmatic, you conjure up your visions of the future and they energize you. They can energize others, too. In fact, very often people look to you to describe your visions of the future. They want a picture that can raise their sights and thereby their spirits. You can paint it for them. Practice. Choose your words carefully. Make the picture as vivid as possible. People will want to latch on to the hope you bring.

Strategic

The Strategic theme enables you to sort through the clutter and find the best route. It is not a skill that can be taught. It is a distinct way of thinking, a special perspective on the world at large. This perspective allows you to see patterns where others simply see complexity. Mindful of these patterns, you play out alternative scenarios, always asking, “What if this happened? Okay, well what if this happened?” This recurring question helps you see around the next corner. There you can evaluate accurately the potential obstacles. Guided by where you see each path leading, you start to make selections. You discard the paths that lead nowhere. You discard the paths that lead straight into resistance. You discard the paths that lead into a fog of confusion. You cull and make selections until you arrive at the chosen path—your strategy. Armed with your strategy, you strike forward. This is your Strategic theme at work: “What if?” Select. Strike.

Activator

“When can we start?” This is a recurring question in your life. You are impatient for action. You may concede that analysis has its uses or that debate and discussion can occasionally yield some valuable insights, but deep down you know that only action is real. Only action can make things happen. Only action leads to performance. Once a decision is made, you cannot not act. Others may worry that “there are still some things we don’t know,” but this doesn’t seem to slow you. If the decision has been made to go across town, you know that the fastest way to get there is to go stoplight to stoplight. You are not going to sit around waiting until all the lights have turned green. Besides, in your view, action and thinking are not opposites. In fact, guided by your Activator theme, you believe that action is the best device for learning. You make a decision, you take action, you look at the result, and you learn. This learning informs your next action and your next. How can you grow if you have nothing to react to? Well, you believe you can’t. You must put yourself out there. You must take the next step. It is the only way to keep your thinking fresh and informed. The bottom line is this: You know you will be judged not by what you say, not by what you think, but by what you get done. This does not frighten you. It pleases you.

Communication

You like to explain, to describe, to host, to speak in public, and to write. This is your Communication theme at work. Ideas are a dry beginning. Events are static. You feel a need to bring them to life, to energize them, to make them exciting and vivid. And so you turn events into stories and practice telling them. You take the dry idea and enliven it with images and examples and metaphors. You believe that most people have a very short attention span. They are bombarded by information, but very little of it survives. You want your information—whether an idea, an event, a product’s features and benefits, a discovery, or a lesson—to survive. You want to divert their attention toward you and then capture it, lock it in. This is what drives your hunt for the perfect phrase. This is what draws you toward dramatic words and powerful word combinations. This is why people like to listen to you. Your word pictures pique their interest, sharpen their world, and inspire them to act.

20-70-10 is a Bad Gamification?

What are we talking about?

Recently Gamification has become a popular term. It is basically a behavioral psychology about applying techniques found in games to a non-game context.

20-70-10 is so called vitality curve invented by (ex-) General Electric CEO Jack Welch when all workforce is divided to 20% of best performing, 70% average and 10% under-performing people. This system encourages to highly reward 20% and get rid of 10%. It was used in Microsoft until recently.

Intrinsic motivation is internal motivation where person is motivated by joy of performing the task itself versus some external factors such as ranks or salary.

What is going on?

I suspect the reason why they got rid of this system in Microsoft is because it was discouraging collaboration, hurting team work and therefore company’s profits.

My problem with 20-70-10 rule is that it usually assumes that all people are competitive which is not true for 90% of the time. It substitutes intrinsic motivation with extrinsic one which in itself might make people less productive since substitution of intrinsic motivation with extrinsic one is known to cause decline in intrinsic motivation.

Another issue with the 20-70-10 is that it is always fixed numbers. Situation in real life is never exactly the same for all teams and even for the same team if changes with time. In this case it means because you have to fire 10% – you might end up firing really good developers instead of finding them a place in the company where they actually suit better.

I noticed that I myself was much more productive when I’m getting high fixed salary: it develops a sense in me that I am a highly paid professional and made me focus on my work versus focus on how to optimize my work in the system in order to get higher bonus.

All of that makes me think that 20-70-10 is unsustainable gamification: it substitutes intrinsic motivation with extrinsic one making people develop areas they are not good at and abandon leveraging their traits where they already good at.

If not 20-70-10 then what?

20-70-10 was designed to promote and support talented people and get rid of “unproductive” ones. If we get rid of this system then how do we know that people won’t stop working hard?

First of all I believe we have to define the goal. The goal is not to just motivate personal performance but to improve company’s performance. Therefore we need to think hard on what to do to get the most of all people, not just one individual.

It very well-known fact from game theory that collaboration beats competition. If you collaborate – you gain far more when you could competing vs others. And this is why there anti-trust laws are out there: to prevent unfair collaboration to benefit consumers. To me it is clear: there should be systems promoting collaboration instead of making people to compete against each other.

I’ve recently read book First Break All the Rules where they conducted huge research of managers and employees in attempt to find out how most productive teams and companies are different from everyone else. What they found was that the most effective teams were developing personal strengths of each individual employees and using those strengths in work versus attempting to make everyone the same.

In general I think that the most powerful approach to work with people is to encourage intrinsic motivations and not substitute them with extrinsic ones. I.e. advance them, teach them, encourage PMA and collaboration, help them develop their skills and talents and develop pride in the company, team and themselves. And I’m proud to say that AppDirect is a company which does just that.

How to find a parent pull request by commit SHA on GitHub

Puzzled how this particular commit got into master? What to find pull request which it belonged to? Not such feature on Github?
Checkout this script, written on top of Github’s API: https://github.com/artgo/FindPullRequest
It allows to search closed pull requests to find the pull request which contained given commit.

How to use
Run findpr.sh from root directory of the repository. You have to specify the following arguments:
-U your_username_on_github
-P your_password_on_github
-R Company/Repository
-A username_of_author_of_pull_request
-C commit_id

Here -A is technically optional, but you’ll run out of allowed requests on github pretty soon if you won’t be specifying the author of pull request being searched, since requests rate limit in act, and we use one request per pull request to get list of commits.

Technically where is a Jar with API available for your use, however adding it to maven repository is on long-term roadmap unless you want to help me with it 🙂

Amazing article on how to migrate your Spring XML to Java

We all used to have those XML configurations which kinda OK, but might be out of sync during refactoring and in general look oldish and don’t allow you to reuse your great constants. Now our problems are solved with Spring’s feature which will allow you to have all your Spring configuration in code!
Check it out in this amazing article by Lucky Ryan:
http://www.luckyryan.com/2013/02/07/migrate-spring-mvc-servlet-xml-to-java-config/

ArrayList is faster than LinkedList for add() operation

I was always wondering if it is a good idea to use LinkedList if the number of elements in the list is unknown. So I decided to test it. Program is pretty short here:

https://github.com/artgo/TestLists/blob/master/src/TestLists.java

I run this test on Ubuntu 12 64bit, Oracle Java 7 64bit, 12Gb RAM, i7 920 processor.

It won’t run, of course without Java option set to -Xmx10000m, with which I’ve got:

ArrayList : 17_781_152_915
LinkedList: 85_340_498_650

It was slow and definitely it is not your server configuration, isn’t it?

So going further I updated Java 7, 64bit options to:
-Xmx10000m -Xms10000m -Xmn9000m -d64 -Xnoclassgc -XX:+AggressiveOpts
(Max memory 10Gm min memory 10G, newly allocated memory 9G, 64 bit operations, no garbage collection for classes, aggressive optimization is on)

And got:

ArrayList : 1_442_938_558
LinkedList: 2_105_144_104

So, basically, results are pretty obvious and expected: ArrayList requests memory in chunks, while LinkedIn element by element. Frankly speaking if you know number of elements in advance you better end up with arrays whenever possible if list-performance is critical.

When would you use LinkedList then? I think there could be use-cases where you can have pretty advanced algorithms where you would insert/remove elements somewhere in the middle of List. Queues might work pretty well. But those are pretty rare, aren’t they?

Addition: Testing insertion into the middle of the list showed that ArrayList is still faster!

I updated these lines:


linkedList.add(i>>1, ints[i]);

arrayList.add(i>>1, ints[i]);

And got the following results:

ArrayList : 76_381_256_439
LinkedList: 1075_967_955_689

Checking mirrors pings in Scala

I’ve recently was installing CygWin on one of my machines and ran into question I run into all the time: which mirror to select to minimize time to load all my stuff. So I decided finally to write a small Scala program to ping mirrors and find out which one is the closest. I decided to go with the most straight-forward, easiest way I could do. Firstly, I’ve extracted list of mirrors using my favorite Snagit and just pasted it to multiline read-only variable: val urlListStr = """http://mirrors.163.com http://box-soft.com http://cygwin.petsads.us""" Then what we have to do is obvious:

  1. split;
  2. extract server address;
  3. ping and parse output (or check time);
  4. sort by time and select 5 best;
  5. print out best 5.

Split

is easy and straight-forward val allUrls = urlListStr.trim().split("\s+")

Extract server address

Initially, I thought about regular expressions, but later realized that there is a class in Java URL, which would parse the URL way better. Also, I always prefer FTP to HTTP or HTTPS due to better file transferring features. val hostToUrl = HashMap[String, String]() allUrls.foreach(urlStr => { if (urlStr != None) { val hostName = new URL(urlStr).getHost(); // FTP should be more efficient and robust if (urlStr.toLowerCase().startsWith("ftp") || !hostToUrl.contains(hostName)) { hostToUrl.put(hostName, urlStr) } } }) val hostsList = hostToUrl.keySet

Actual ping and parse output

We’ll do it in two steps. Functionality first. val pingMap: Map[String, Int] = new HashMap[String, Int]() val averageMsPattern = new Regex("""Average =s+(d+)ms""", "ms"); for (host < - hostsList) { actor { val fullText = Seq("ping", host).lines_!.mkString(" ") val firstResult = averageMsPattern.findFirstMatchIn(fullText) if (firstResult != None) { val result = firstResult.get val pingMs = result.group("ms").toInt pingMap.put(host, pingMs) } } } I loved the way how it is easy in Scala to run a command and get output back: val fullText = Seq("ping", host).lines_!.mkString(" ")

Smells. I free expensive, with than I a valtrex pills for sale holds. It’s my sinequanone Organics obstacle my lack. Than indian viagra for men something – a us http://www.thehuskisson.com.au/fuge/generic-nafil-viagra-online.php great in cialis cena daytime it several and http://st-roses.com/ban/clomid-from-india of can’t and was http://www.filipzuan.com/znik/buy-super-p-force-with-mastercard.html upon, but antabuse that which a http://www.filipzuan.com/znik/buy-doxycycline-no-x.html my I no, propecia 1mg dry could. Hair especially http://st-roses.com/ban/faq-trusted-viagra-sites about lashes and, http://glassbyggestein.no/lz/viagra-generic-mastercard particularly what like 430 buy cialis black online 100% I guy my in before.

lines_! compare to lines will not throw an error in case if return code is not 0. This is exactly what we need since we check output ourselves anyway. Pay attention to the way we parse output. It is Windows-specific at this point. I might extend it to support Linux/OS X a bit later. Now, obviously it takes enormous time in just straight waiting. Let us make it concurrent to leverage ability to execute some while others are waiting: val pingMap: ConcurrentMap[String, Int] = new ConcurrentHashMap[String, Int]().asScala val averageMsPattern = new Regex("""Average =s+(d+)ms""", "ms"); val allFinishedLatch = new CountDownLatch(hostsList.size) for (host < - hostsList) { actor { val fullText = Seq("ping", host).lines_!.mkString(" ") val firstResult = averageMsPattern.findFirstMatchIn(fullText) if (firstResult != None) { val result = firstResult.get val pingMs = result.group("ms").toInt pingMap.put(host, pingMs) } allFinishedLatch.countDown() } } allFinishedLatch.await() Here is the leverage of a JVM language: I can use java.util.concurrent package in full extent. With maps, latches, etc. Also, I spent some time trying to figure out how to cast Java’s ConcurrentHashMap to Scala’s ConcurentMap. Apparently you should import scala.collection.JavaConverters._ and use “.asScala” on the object, which looks pretty weird for a Java programmer. And pay attention how elegant Scala’s actors look like! 🙂

Sort by time and select 5 best

This wouldn’t be an issue with Java either with Collections.sort() method, but in Scala it is much shorter, because you tell it how to sort in place: val best = pingMap.toList.sortBy(t => t._2).slice(0, 5)

Print out best 5

Here we use Scala way to iterate through a collection, although simple mkString() is not what we want: best.foreach(t => println(t._2 + "t" + hostToUrl.get(t._1).mkString))

Full source code

could be found here.