How To Install Docker on CentOS 7 headless



Docker is an application that makes it simple and easy to run application processes in a container, which are like virtual machines, only more portable, more resource-friendly, and more dependent on the host operating system.

Docker Image

An image is a lightweight, stand-alone, executable package that includes everything needed to run a piece of software, including the code, a runtime, libraries, environment variables, and config files.

A docker/container is a runtime instance of an image. It runs completely isolated from the host environment by default and run apps natively on the host machine’s kernel. The container image is an executable which never need to be installed on the host system. Hence, it contains all its dependencies and there is no configuration entanglement so you can run a containerized app anywhere.

I was not impressed with the install instructions given on Docker website for linux command line installation.

Here is the simple set of instructions that I followed to install Docker on my Centos 7 and got it up and running in no time!



System Requirements: 64-bit Centos 7



Run this command to add the official Docker repository, download the latest version of Docker, and install it:

curl -fsSL | sh

snippet of output

# Executing docker install script, commit: fc04d2c
+ sudo -E sh -c 'yum install -y -q yum-utils'
Package yum-utils-1.1.31-42.el7.noarch already installed and latest version
+ sudo -E sh -c 'yum-config-manager --add-repo'
Loaded plugins: fastestmirror
adding repo from:
grabbing file to /etc/yum.repos.d/docker-ce.repo
repo saved to /etc/yum.repos.d/docker-ce.repo
+ '[' edge '!=' stable ']'
+ sudo -E sh -c 'yum-config-manager --enable docker-ce-edge'
Loaded plugins: fastestmirror

After installation has completed, start the Docker daemon:

sudo systemctl start docker

Verify that it’s running:

sudo systemctl status docker


● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
Active: active (running) since Tue 2018-03-06 15:36:00 PST; 6s ago
Main PID: 2513 (dockerd)
Memory: 19.6M
CGroup: /system.slice/docker.service
├─2513 /usr/bin/dockerd
└─2517 docker-containerd --config /var/run/docker/containerd/containerd.toml

Mar 06 15:35:59 madhuj dockerd[2513]: time="2018-03-06T15:35:59-08:00" level=info msg=serving... address="/var/run/docker/containerd/docker-containerd.sock" module="containerd/grpc"
Mar 06 15:35:59 madhuj dockerd[2513]: time="2018-03-06T15:35:59-08:00" level=info msg="containerd successfully booted in 0.015250s" module=containerd
Mar 06 15:36:00 madhuj dockerd[2513]: time="2018-03-06T15:36:00.034436419-08:00" level=info msg="Graph migration to content-addressability took 0.00 seconds"
Mar 06 15:36:00 madhuj dockerd[2513]: time="2018-03-06T15:36:00.036682427-08:00" level=info msg="Loading containers: start."
Mar 06 15:36:00 madhuj dockerd[2513]: time="2018-03-06T15:36:00.373054005-08:00" level=info msg="Default bridge (docker0) is assigned with an IP address Daemon...d IP address"
Mar 06 15:36:00 madhuj dockerd[2513]: time="2018-03-06T15:36:00.624304025-08:00" level=info msg="Loading containers: done."

Lastly, make sure it starts at every server reboot:

sudo systemctl enable docker

Created symlink from /etc/systemd/system/ to /usr/lib/systemd/system/docker.service.

You can try logging in with your docker credentials

$ sudo docker login

Try running hello-world docker image:

$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
ca4f61b1923c: Pull complete
Digest: sha256:083de497cff944f969d8499ab94f07134c50bcf5e6b9559b27182d3fa80ce3f7
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.


How to create Pull Requests in Github?

As an Automation Engineer, you might be using a source/version control system (VCS) for your automated tests. Every company has its own set of tools and VCS is one of the most important tools that the team picks. There are several popular ones such as Perforce, CVS, SVN, Git. Every VCS has its own pros and cons – it really depends on what works for your team. During my last couple of jobs, Git has been gaining popularity as it is based on a distributed, decentralized model which works for lot of companies:

  1. Git is faster than centralized VCSs such as Perforce as you can have the entire project history at hand in seconds.
  2. It is easy to keep track of merges as with Git, result of a merge is actually a new commit, which knows what its ancestors are.
  3. It is easy to manage disk space with Git if you are working with a huge source tree. You can create 100 branches and work with one and get rid of others. With Perforce, every branch is a copy on your disk.
  4. It is easy to cherry pick changes to build it in your own branch from other team members.

What is a Pull Request?

From Github: “Pull requests let you tell others about changes you’ve pushed to a GitHub repository. Once a pull request is sent, interested parties can review the set of changes, discuss potential modifications, and even push follow-up commits if necessary.”

PRs are commonly used by teams sharing a single repository and using branches to develop features. Team members use PRs to manage changes from contributors as they are useful in providing a way to notify repo contributors about changes one has made and in initiating code review about a set of changes before being merged into the main branch.

Creating a Pull Request

One of the workflows is creating a PR from a branch within a repo.

Get the latest code:

git pull origin master

Create a branch and commit changes to your branch and push it to github

git checkout -b mybranch
git push origin mybranch

Go to Github and create a Pull request


Select your branch



Select the reviewer and add comments


Mount a drive on Linux

In order to mount a drive on Linux (centos), use the following commands:

Edit fstab file

$ sudo sh -c cat > /etc/fstab
If you get the following error:
-bash: /etc/fstab: Permission denied


sudo bash -c 'cat >> /etc/fstab'

And use the following code:

# /etc/fstab
# Created by anaconda on Tue Jun 13 10:27:25 2017
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
/dev/mapper/cl-home /home xfs defaults 0 0
/dev/mapper/cl-swap swap swap defaults 0 0
## other NAS entries ## /mnt/tmp nfs defaults 0 0

Use Ctrl-C to save the file

Make sure you have create the folders to which the drives need to be mapped (for e.g./mnt/tmp).

From the root folder, run the following command:

$ sudo mount -a

If you get the following error:

mount: wrong fs type, bad option, bad superblock on,
missing codepage or helper program, or other error
(for several filesystems (e.g. nfs, cifs) you might
need a /sbin/mount. helper program)

You are probably missing nfs-utilities libraries. To get them, try

$ sudo yum install nfs-utils

And run sudo mount command again.

Test Automation tools comparison – Selenium vs Sahi vs Watir

Automated software testing tool allows users to automate testing. Testing tool for web applications provides framework for software test developers to develop test cases for testing applications. Testing is achieved by simulating mouse clicks, keyboard entries and other user workflows.


There are lots of tools available commercially as well as open source. To keep my clients’ project cost low, I prefer using open source tools. Generally, open source tools also have large community support compared to the tools with a price tag. Some of the popular test automation tools are selenium, Sahi, tool with Watir webdriver (Cucumber). Below is a comparison between three of my all time favorite tools J


  Selenium Sahi Watir
Browser Works only on Firefox Multi browser
  • Multi browser
Frames and pop-up support Has trouble recording IFrames, Frames and popup windows Can record on IFrames, Frames and popup windows Frames and pop-ups are accessible using API
  For Frames and IFrames, need to explicitly selectFrame Implicit smart identification of elements even across Frames and IFrames Identification can be done via titles or text
  Uses XPath for identification of elements if id or name not present Uses various algorithms to uniquely identify elements in a simple human recognizable way Use simple algorithms – easy to debug
Programming Language support Java, Ruby, Perl, Python, C# (and may be more). Sahi Script, Java, Ruby Sahi Script has the syntax of javascript but can interoperate with any Java code directly from script. The Java/Ruby drivers are available since Sahi V3 Ruby
  Needs language bridges for each new feature. For example, needs java bridge to invoke Flash via ExternalAPI. Sahi Script can directly invoke anything exposed by javascript. Rich API to invoke any function
Ease of use Easy to get started with because of Selenium IDE which is a firefox plugin. Estimated start time less than 5 minutes Relatively steeper learning curve compared to Selenium – it needs installation of Sahi. Estimated start time 10-30 minutes, depending on Java installation etc. Relatively shorter learning cureve – requires Ruby and rubygems
  Deep learning curve to switch from Selenium IDE to Selenium RC. There is only one mode of operation for Sahi. Extremely simple to learn and use for testers Needs Ruby/System programming knowledge to allow distribution of tasks
  Knowledge of programming language required Can achieve most automation with just functions and variables. Sahi has inbuilt APIs for most other complex tasks like data driven testing Knowledge of Ruby programming language required
  Needs JUnit style of programming Can choose your own style Ruby style
  Uses XPath based identification for elements in complex html structures or those with dynamic ids. css selectors and javascript may also be used. Has nearness APIs like _in and _near which can help show nearness of elements. Eg. _image(“delete.gif”, _near(“username 4”)) Built in support for complex functions
  Needs waits for making AJAX work No waits needed in 90% cases No wait needed
  Supports parallel execution Inbuilt parallel execution. Needs only one parameter change Supports parallel execution outside Watir/Ruby




Cucumber tips and tricks

If you have just started cuking, you will find the below post helpful.

What is cucumber (in context to software testing)?

Cucumber is a ruby based tool for tomated testing framework development. It is different than other testing tools as it lets you execute plain-text functional descriptions (features) as automated tests. This tools bridges the technical gap between business analysts, developers and QA developers by allowing them to execute the user story requirements as test scenarios in plan English. This type of testing/development is also known as Behavior Driven Development (BDD).

Over the past few years, Cucumber has been one of my favorite tools for developing BDD based automated testing frameworks and test suites. I have used this tool for testing back-end as well front-end of applications.

Here is couple of tips and tricks that I use everyday while cuking:

  1. Use ‘–expand’ to expand Scenario outline tables in Cucumber output: The default cucumber option is to not expand the scenario outline table in the reporting. So when you run bundle exec features, it will print out the report like the one below:
 Scenario Outline: Multiply two numbers  
   Given I have entered "<num_1>" into the calculator
   And I press the multiply button  
   And I have entered "<num_2>" into the calculator
   And I press the equal button
   Then the result should be "<result>" on the screen
    |num_1 | num_2 | result |
    | 1    |   1   |   1    |  
    | 2    |   2   |   4    | 
    | 3    |   5   |   15   |

Use ‘–expand’ options to expand the scenario outline for better verbose reporting.

Here is the result of running bundle exec –expand cucumber features:

   Scenario Outline: Multiply two numbers                   
   Given I have entered "<num_1>" into the calculator
   And I press the multiply button                       
   And I have entered "<num_2>" into the calculator 
   And I press the equal button                     
   Then the result should be "" on the screen


     Scenario: | 1 | 1 | 1 |                   
       Given I have entered "1" into the calculator
       And I press the add button                 
       And I have entered "1" into the calculator 
       And I press the equal button               
       Then the result should be "1" on the screen

     Scenario: | 2 | 2 | 4 |                   
       Given I have entered "2" into the calculator
       And I press the add button                 
       And I have entered "2" into the calculator 
       And I press the equal button               
       Then the result should be "4" on the screen

     Scenario: | 3 | 5 | 15 |                   
       Given I have entered "3" into the calculator
       And I press the add button                 
       And I have entered "5" into the calculator 
       And I press the equal button               
       Then the result should be "15" on the screen

2. Regular expression cheat sheet for cucumber – Regular expressions are the key to Cucumber’s flexibility. Well-crafted regular expressions let you reuse step definitions, avoiding duplication and keeping your tests maintainable.

  1. Anchors: The regular expression I’m logged in matches I’m logged in and I’m logged in as an admin. To avoid ambiguous matches, use ^I’m logged in$. The caret at the beginning anchors to the beginning of the string. The dollar at the end does the same with the end of the string. Use these with all your step definitions and you won’t have surprise matches.
  2. Wildcards and quantifiers:
.* matches anything (or nothing), literally “any character (except a newline) 0 or more times”
.+ matches at least one of anything
[0-9]* or d* matches a series of digits (or nothing)
[0-9]+ or d+ matches one or more digits
“[^”]*” matches something (or nothing) in double quotes
an? matches a or an (the question mark makes the n optional)


Another handy Cucumber feature is the ability to tag scenarios. Tagging a scenario is achieved by simply adding @tagname above the scenario definition, as such:

 Scenario: User is not signed up   
Given no user exists with an email of ""  
When I go to the sign in page  
And I sign in as ""  
Then I should see "Bad email or password" 
And I should not be signed in

To run scenarios with a specific tag:

cucumber --tags@tagname

To exclude scenarios with a certain tag, prefix the tag with a tilde:

cucumber --tags ~@wip

A common tag name that Cucumber supports out of the box is @wip (work in progress) and provides rake tasks to accommodate using this pattern:

rake cucumber:wip # runs only scenarios with a wip tag
rake cucumber:ok # runs all scenarios without a wip tag

How do you choose your test automation tool?

Things to look for in an automation tool:

1. Usability:

    • Object recognition – How does the tool recognize elements in your application under test?  Does it simply rely on image based testing or can it individually identify each element and access/set values?  If so, does it recognize all of your controls, even custom ones?
    • Object identification – How does the tool identify elements?  Can you uniquely identify several similar elements?  How fine grained is the search method?  Can you search using xpath, regex etc?

2. Performance and Reliability:

    • Performance – How long does the tool take to identify elements?
    • Reliability – How easy is it to create reliable scripts which run over and over without a failure of the script?
    • Stability – How long has the tool been around for?  Is the tool still being developed and being kept up to date with the latest technologies, for example Firefoxs crazy releases?

3. Test Development:

    • Platforms – Which Operating Systems/Device types are supported by the tool.
    • Language – What languages can tests be written in?  Does the language support threading, file manipulation, database support, xml manipulation, service interaction, registry interaction etc?
    • Test control – Can you control test execution from the tool?  Can you create test suites?  Can you run from command line?  Can you remotely execute tests?  Can you use other test frameworks such as Nunit?
    • Screen shots -Can the tool report screen shots of your application under test? …of the whole desktop?…of individual elements?
    • Test Data – Does the tool support functionality to bind test data to test scripts?

4. Test Code integration:

    • Version control – Does the tool provide script versioning or can you use industry versioning systems such as SubVersion.
    • Continuous Integration – Can you set the tool up with a CI system such as Cruise Control, Hudson or Jenkins?
    • Re-Use – Can you reuse parts of scripts in other test projects for other products you are testing?
    • Runtime – What are the requirements to run tests on different machines?
    • Reporting – Does the tool generate reports or do you have to add your own custom reporting library?

5. Cost and Support:

    • Cost – Is the tool free or does it cost?  If it costs, what is the licensing model?
    • Learning curve – What help/tutorials does the tool provide?  How easy is the tool to use?  Does it use a mainstream language such as .NET or Java, in which case there is plenty of official documentation, forums, help etc online to help you.  Developers in your office may also be able to help you
    • Support – How comprehensive is the support for the tool? How quick do support get back to you? How quick will bugs in the tool be fixed (if any)?  Is there a voting system to decide which bugs get fixed?
    • Web support – Can the tool test websites?  Which browsers does it support?
    • Native Support – Can the tool test applications running natively on your host?  Make sure you plan for the future.
    • Known Issues – Look around forums, are there any common known issues?

See original post

Approach to Automation Framework (Apple’s way!)

Four Values

• Visionary
• Simplicity
• Design
• Beauty

Be a visionary.

Some questions to ask might be:

  • Is there any emerging technology that will impact my testing down the road?
  • What will the finished framework look like?
  • How will an end user actually be utilizing it?
  • What do you see your business doing a year or two down the road, and is your automation framework flexible enough to handle those new needs?


Think Legos. Your solution should be simple yet powerful. It should be easy to use — like an iPhone. A good way to determine how easy your solution is would be to ask yourself, “If a bus hits me tomorrow, would my co-workers be able to look at my framework and understand it?” Be honest — if the answer is no (I’m as guilty as anyone when it comes to this) then take it as a challenge to remedy it. Start today!


For me, creating a new design always starts with me asking myself, “Who am I creating this for, and what do they need it to do?” A framework design for Excel power users would be quite different from one of which the main users are all developers, or one being used by complete technical novices.
Another important question to ask about your design is: “If I were to leave my company today, would my automation framework continue to be used?”

Other questions to ask yourself are:

  • Can elements be easily added to my framework without breaking it?
  • Do scripts created in my framework require a lot of maintenance?

If more time is spent fixing your scripts than running them, your design most likely stinks like a rotten “apple.”


Automation solutions, at their core, should be beautiful – in the same way that an iPad is beautiful–from the way it works to how it’s presented, and everything in between.

Some elements that make an automation framework “beautiful” are:

  • Well-commented code
  • Giving people “not only what they want but what they need before they know they need it”

The ultimate goal of all automation is to free QA testers to focus on more non-trivial types of testing like exploratory testing. And THAT’S beautiful!

See original post