Test automation wants your manual testing job

Automation will leave many people without a job. 

I am not talking about test automation being a danger to many manual testing jobs. 

But about automation in a more general perspective. 

In Canada, in the next 10 - 15 years, up to 7.5 million jobs (out of 18) will be lost because of automation. 

This is what Huffington Post says and I agree with them. 

The key points of the article are below: 

  • Canada faces the loss of up to 7.5 million jobs to automation in the next 10 to 15 years 
  • Even people in high-income jobs won’t be spared, as automation will reduce the demand for doctors, lawyers and engineers, among others. 
  • Autonomous vehicles are already on the road, robo-advisors are dispensing financial counsel and even lawyers and reporters are starting to see automation take over routine functions. 
  • The study’s projections found a broad range in the number of jobs that could be lost — 1.5 million at the lower end, and 7.5 million at the high end. That amounts to between 8.3 per cent and 41 per cent of the 18 million jobs in existence in Canada today. 

So the demand for doctors, lawyers, engineers, reporters, etc will be reduced significantly. 

Should we hope that this will not happen to testers?

Stop being a one-trick pony! Stop focusing only on manual testing!

Manual testing will not go away. 

But it will not be anymore what it used to be. 

Like all things, testing changes and at a rapid pace. 

Companies still need manual testers but less than before. 

Normal testing is something that not only testers can do. 
A business analyst, business user or developer can do it as well. 

With so "many testers" available, companies hire outside testers if they are exceptional. 

Or multi-talented, with diverse skills. 

So do you want to continue to have a career in testing? 

Stop being a "one-trick pony" and stop focusing only on manual testing. 

Manual testing used to be sufficient for a successful career. 

You had a good "trick" and used it over and over. 

While you focused on your trick, everything around you changed and you did not notice. 

One day, you discover that the one-trick does not keep you employed. 

You rush then to learn more tricks and hope that you can do it fast.

Sadly it is too late because learning does not happen over night. 

This is something that applies to many other domains. 

Like sports. 
Take mixed martial arts, for example. 

One of the MMA women divisions had a champion for 3 years in Ronda Rousey who beat soundly (and in many cases under 1 minute) all her opponents. 

She did this with great judo skills. 

Ronda was a true "one-trick pony" since all her skills were only about judo. 

One day came when she fought a true boxer. 

Even with a lot of boxing training, she lost in a dramatic fashion. 

After her first loss, she took a year off and trained more in boxing hoping for a revenge. 

Next time she fought, she lost again but this time under 1 minute. 

What happened then?

While she was enjoying her "one pony trick", the world changed and she did not notice. 

When she realized that serious improvement was needed, it was a bit too late.

Learn automation while you don't need it

I have been a software manual tester for 10 years.

Due to the regression tests that I do every other week, it is imperative that I get this function automated to help me with the rest of my job.

I regression test over 90 custom sites for my company and really need to get this done by February 2017.

Please help.

I received this message from a tester a few weeks ago.

He wanted to learn automation and programming and use these skills successfully in 2 months.

Which is very difficult to do.

I don't know why he did not start learning earlier.

He probably thought that will not need automation and his employer will hire a developer for the automation work.

So he did what many people do in similar occasions: postpone.

We don't like change and avoid it.

Our hope is that somehow things stay the same or we figure them out.

And a moment comes when we need change fast and results too.

This is when we realize the mistake of not starting ahead of time, when we don't need the new skills yet.

Fast change happens in stories and movies only.

Real change takes time and is done in small steps.

So, stop postponing learning programming and get started.

It does not matter if you need it in your job now or not.

You will need it sooner than you think.

Next December, you will be very happy that you started learning automation the year before.

What do you need for a Selenium test automation job?

First, the obvious.

Since test automation is programming, you need to know the basics (more if possible) of a programming language such as Java.

And you need to know the basics of the Selenium WebDriver framework.

But this is not sufficient for getting an automation job.

In an interview, you have to convince other people that you know how different things work in Selenium and Java.

For example, 
  1. what is boxing in Java?
  2. what is the difference between method overwriting and overriding?
  3. what is the page object model?
  4. what are the fastest locators?
This requires practicing explaining how things work, what they are and how they should be used.

You still need more for that new automation job.

You need 500 hours of practicing Selenium and Java.

The number of hours is different from person to person.

Some people may need less, others more.

But it is essential that you put the time in for the practice.

Why so many hours?

Because companies will put you to test.

There are 2 types of tests that you may have to do:

1. JAVA coding test
This test happens before the face-to-face interview and is a condition for it.
It is usually done online on a site like codility.com and it can last around 1 hour.
You are given a problem and have to write code that solves it.


2. SELENIUM automation test
After the face-to-face interview, if the interview went well, you may be asked to do the automation exercise.
This test is about automating a scenario for a site.
You may get 1 day or more to do it.


Going back to the 500 hours practice.

It is very difficult to do well at these exercises if you are not already proficient with Java and Selenium.

Because the time for doing the exercises is limited.

And your solutions have to be very good to get the job.

Best Resource for Improving Selenium Skills? Selenium code

You learned Selenium and Java test automation basics from a book, online course or youtube. 

Page object model is understood, locators are clear, explicit waits and expected conditions are straightforward.

Java concepts such as classes, objects, inheritance, looping, arrays, lists are all covered.

With the new skills, you can write test automation scripts for a variety of websites.

You are wondering now about the next level of test automation.

There is always a next level so what is it for you?

How do you go to it?

What resource should you use for guidance?

Most available books and courses target the beginner and intermediate test automation levels.

There are not many resources available on advanced test automation skills.

There is one place however, often forgotten, that has everything you need in your quest to more knowledge.

The Selenium source code.

It is extremely helpful not only to learn how to use Selenium but also to read the source code.

Doing this provides many benefits such as:

1. it shows how Selenium classes and methods work

For example, how does Selenium find a web element using the findElement() method?
How does Selenium locate an element by css locator?

2. you can learn how a framework is built

Selenium is a framework.

You can learn many things about building an automation framework from studying how the Selenium framework is built.

3. you can learn what good programming is

Selenium was created by professional developers.

What better source of learning than the code that they wrote?

4. you find out what you dont know yet but should know

For example, by reading the Page Factory code, you will learn about annotations.

And reflection.

And design patterns.

And proxy classes.

And generics.

And interfaces.

You will need all these Java concepts (and more) to make the transition to the next test automation level.

So attach the Selenium source code to the project in Eclipse and start reading.

When do you need these new skills?

Lets say that you want to have in your automation project the ability of taking screenshots automatically when an exception happens in a test script.

You use TestNG as the unit testing framework.

TestNG listeners can help but there is a problem.

You need in the test listener the driver object created in the test class or the base test class.

To get this driver object, you will use reflection and generics. 

Another example of using the new skills is creating new locator types.

Selenium provides by default a variety of locator types such as id, class, name, xpath, css.

How about using also Jquery and Javascript locators?

You will need annotations for this.

How to interact with sliders in Selenium WebDriver

Sliders allow users to select a value by dragging and dropping a handle. 

This value can be a price, a quantity, a year. 

The web page could use a textbox for getting the same information from users. 

But with sliders, the page becomes much more interesting.

Read the full article on seleniumjava.com.

Learn Python or Java as your first language?

from http://www.thecrazyprogrammer.com/

There are so many opinions all over the place on what is the best language to learn first.

Is it Python?

Or maybe Java?

To understand better how they compare, I read multiple articles from Quora.com on this topic and selected some opinions.

We start with opinions about Python.

I added the Quora articles links as well in case you want to read more.

Why is Python a good choice for the first language to learn?

FROM https://www.quora.com/Is-Java-harder-to-learn-than-Python

Java is geared better towards applications, where as Python is geared better towards tasks.

Most programmers will eventually need C# or Java under their belt.

Python is generally a language for Sys Admins, mechanical engineers, and other adjacent career paths.

As a first language, Python is arguably easier.

Variables don't need a type, indentation is obligatory so you don't make block mistakes, syntax is very English-like, iteration is very easy, the standard library does a lot of things in very few lines of code, and so on.

Python’s syntax is much more simple and readable than that of Java. 

It also does a much better job of minimizing the amount of code needed to complete a task, which is incredibly convenient for people learning to code as they don't have enormous walls of code to deal with.

FROM https://www.quora.com/Which-is-easier-to-learn-Java-or-Python


Python has surpassed Java as the top language used to introduce U.S. students to programming and computer science, according to a recent survey posted by the Association for Computing Machinery (ACM).

Eight of the top 10 computer science departments now use Python to teach coding, as well as 27 of the top 39 schools, indicating that it is the most popular language for teaching introductory computer science courses

Python has been growing in popularity in the educational realm for at least the past few years, though this survey is the first to show it has eclipsed Java, which has been the dominant teaching language for the past decade.

FROM https://www.quora.com/If-I-had-to-choose-between-learning-Java-and-Python-what-should-I-choose-to-learn-first

Go for Python if you already have a background in computer science and want to apply that knowledge on quickly building something real, that be a web application or software tool. 

Python is very quick and easy to learn, with tons of modules that do any kind of job for you, is less verbose than Java with a great community.

Why is Java a good choice for the first language to learn?

FROM https://www.quora.com/Is-Java-harder-to-learn-than-Python

You can write VERY SIMPLE programs in Python faster than you can write programs of the same length in Java, so in that respect, you can learn Python faster.

For any serious program (longer than a few dozen lines of code), Java is much better because of various safeguards, such as static typing.

Since you spend less time debugging stupid errors in Java, you can spend more time learning the art of programming and software engineering.

FROM https://www.quora.com/Which-is-easier-to-learn-Java-or-Python

To learn, as a first language, I think it's probably Python. I think if you compare a 'hello world' in each language, Python is obviously shorter, and it obviously makes more sense to a complete beginner.

When you get into beginner programs like 100, or 200 line programs, Python is probably still easier, because you're likely using built-in types, and it's obvious what the types and methods do.

When you get into intermediate size of programs, a few thousand lines, or maybe tens of thousands of lines, I think the advantage skews very strongly in favour of Java.

Dynamic typing makes your first few hundred lines of coding very easy, and your next ten thousand lines a complete nightmare.

Learning slows down, and mystery builds. Each object type you add, further increases the mystery (more class types to remember), whereas in Java, it makes things clearer as there is a total rigidity in what everything is.

For learning, I think if you want your first week to be easy, learn Python, if you want your first 6 months to be easy, learn Java.

I've used Python for longer than I've used Java, I've probably written more Python code than I've written Java code.

I was using Python almost before Java was even released, but I strongly (very strongly) prefer Java. Java is just incredibly strict by comparison, and strict means simple, it means not vague, not flexible, not forgiving.

Unforgiving is good, it provides structure and predictability. A forgiving language means it's vague, fragile, and prone to run time errors, which would (and should) be caught at compile time.

FROM https://www.quora.com/If-I-had-to-choose-between-learning-Java-and-Python-what-should-I-choose-to-learn-first

If you've never programmed before, I'd generally recommend Java as a first language. 

Python is a great language, but in its attempt to make things easier, I think it actually makes some things harder for a new programmer. Python hides too much and that makes things confusing for a new programmer.

Python hides this stuff. It all looks like magic.

In Java, it's more explicit what the types of variables are. 
There's much less "magic" that happens.

Unfortunately, if you're relatively new to programming, I'd have to say - Java. 
I say unfortunately because I really, really, really don't like Java. 
Many people will disagree, but, again, some people like washing dishes, too.

The freedom and dynamism that characterize Python are beautiful and powerful things, but they must be earned.

If you start with Python, many a thing will be a mystery and you'll start thinking that all computers work that way. 
Well, they don't. 
It's pretty much quite the opposite. 
So, if you already know how computers work, you'll understand what's going on and know how to appreciate it. 
If you don't, what will probably happen is that you'll lay out your foundations of your programming knowledge wrong and then you're screwed. You'll struggle to find sense in anything.

Go for Java If you are a total beginner and have never learned computer science before.

This may sounds like the opposite of what you've heard, but do it. 

Java will always force you to go down to the understanding of how things really work , instead of Python which tend to hide some technical details in order to make things simpler.

My recommendation would be to learn Java first for many of the reasons others have listed. 

I assume that you have no previous programming experience for the sake of my answer.

Learning Java will force you to learn to think a little more like a programmer as you learn it.

Python is a little oversimplified and while that may seem like the ‘easy’ route, I think it will gain you some false self-confidence. 
Your appreciation for the simplicity of Python can really only be achieved by learning a language like Java first.

Something else to consider is the amount of jobs available to Java developers. Java is pretty much an industry standard for A LOT of applications. 
I think the amount of opportunities out there will be far greater for you by learning Java first. Python will come much easier to you after you know Java and it will be a nice add-on to your resume.

The final decision is yours.

Interested in a Java-vs-Python summary spreadsheet?

Which language seems to be the most predominant in Selenium script development?

60% of all Selenium downloads are for Java. 

This means that companies use mostly Java for Selenium test automation. 

Java is not only the most popular language for Selenium test automation

Source: http://blog.testproject.io/2015/12/03/worlds-most-desirable-automation-skills/

It is also more robust when used in enterprise projects. 

It has mature and powerful IDEs (Eclipse and IntelliJ) too. 

When selecting the language to learn for Selenium, keep this info in mind. 

Don't select the language based only on which is the easiest to learn. 

You may end up learning an easier language that is not really needed on your job market.

How to convert test classes from JUNIT to TESTNG

Everybody that I talk to says that they use TestNG. I am still using JUNIT.
Am I the only person still doing it?

I am using TestNG as well.
I started with JUNIT a while ago and switched to TestNG for a number of reasons.

So you think that TestNG is better than JUNIT?

TestNG is better than JUNIT version 4.

Let me tell you why.

It does not use static methods for setting up and cleaning the test environment.

I am referring to the methods that use the @BeforeClass and @AfterClass annotations.

Oh really? This is awesome. What else does TestNG do better?

You can have dependent test scripts.
Test scripts with priorities.
It is easier to run test scripts based on categories and suites.
It is possible to have multiple data providers with values for parameters.
And test scripts can have parameters.

So many good things. Is it difficult to migrate from JUNIT to TestNG?

It is not difficult.

I will show you how it is done.

We will start with simple JUNIT test class and discuss one by one the elements that need changes.

Great, lets start.

This is our sample test class:
 import static org.junit.Assert.*;
 import java.util.ArrayList;
 import java.util.Collection;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.FixMethodOrder;
 import org.junit.rules.Timeout;
 import org.junit.runners.MethodSorters;
 import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameters;

 @RunWith(value = Parameterized.class)
 public class JUNITClass {
  public Timeout globalTimeout = new Timeout(1000); 
  public CustomTestRule screenshotTestRule = new CustomTestRule();
  private String keyword;
  public JUNITClass(String keyword) {
   this.keyword = keyword;
  public static void setUp() {
  public static void tearDown() {
  public static Collection< Object[] > data() {
   Collection< Object[] > params = new ArrayList<>(100);
   params.add(new Object[] { "java-author-10" });
   params.add(new Object[] { "oracle-date-20" });
   params.add(new Object[] { "microsoft-title-15" });     
   return params;
  public void test1()  {
  public void test2() {                 
   assertTrue(keyword.length() > 0);
   assertEquals(keyword.contains("-"), true);  
  public void test3() {
  public void test4() {  
  @Test(expected = IndexOutOfBoundsException.class)
  public void test5() {  
   throw new IndexOutOfBoundsException();

The test class uses many JUNIT elements such as

  • annotations (@Test, @Ignore, @BeforeClass, @AfterClass, @RunWith, @Rule, @Parameters)
  • annotation attributes (expected = , timeout = )
  • test fixtures (setUp() and tearDown() methods)
  • assertions

So we will change them one by one.

By the way, you can follow along on your computer while I make the changes.

What's the first thing to do?

First, we remove the JUNIT library from the project by
  • displaying the Navigator view in Eclipse
  • opening the project
  • right clicking the project name and selecting Properties
  • selecting the JAVA BUILD PATH option
  • selecting the Libraries tab
  • selecting JUNIT 4
  • clicking the REMOVE button

Next, remove all JUNIT packages from the beginning of the class:

  import static org.junit.Assert.*;
  import java.util.ArrayList;
  import java.util.Collection;
  import org.junit.AfterClass;
  import org.junit.BeforeClass;
  import org.junit.FixMethodOrder;
  import org.junit.rules.Timeout;
  import org.junit.runners.MethodSorters;
  import org.junit.Ignore;
  import org.junit.Rule;
  import org.junit.Test;
  import org.junit.runner.RunWith;
  import org.junit.runners.Parameterized;
  import org.junit.runners.Parameterized.Parameters;

Now, we have lots of errors in the test class because of missing packages.

Second, we add the TestNG library to the project by
  • displaying the Navigator view in Eclipse
  • opening the project
  • right clicking the project name and selecting Properties
  • selecting the JAVA BUILD PATH option
  • selecting the Libraries tab
  • clicking the ADD LIBRARY button
  • selecting TestNG
  • clicking the FINISH button

We also need to install the TestNG plugin for Eclipse:
  • click Help in the Eclipse menu
  • click Eclipse MarketPlace
  • search for Test NG
  • install the TestNg for Eclipse plugin

Done. We still have those errors in the code. Which one should we fix first?

Lets start with @Test.

Click on the error icon to the left of @Test and import the following package:
import org.testng.annotations.Test;

Is the error still there?

No. It is gone.


Now, about @Ignore.

In TestNG, you can ignore a test using the @Test annotation as well.

How do you do this?

By using the enabled attribute.

So replace @Ignore with @Test(enabled=false).

This should get rid of the error for @Ignore.


Very good.

Now, lets make the changes for the setUp() and tearDown() methods.

Click on the error messages and import the following 2 packages:

 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
And then remove the static keyword from the setUp() and tearDown() signatures.

So these methods will not be static any longer in TestNG?

They won't.

How is your code looking so far?

I did all changes. What's next?

Lets continue a bit more with the @Test annotation.

In our JUNIT code, we have a test that tests for exceptions and one that uses a timeout.

For the test with timeout, replace @Test(timeout=1000) with @Test(timeOut=1000)

For the test with exception, replace @Test(expected = IndexOutOfBoundsException.class) with @Test(expectedExceptions = IndexOutOfBoundsException.class).

Do these changes work for you?

They sure do. Everything is simple and smooth so far.


We can work on the assertions now.

In the JUNIT code, we use 2 assertions: assertTrue and assertEquals.

Import the following package:

  import org.testng.AssertJUnit;

And prefix both assertions with the name of the package:
  AssertJUnit.assertTrue(keyword.length() > 0);
  AssertJUnit.assertEquals(keyword.contains("-"), true); 

The assertions should be good now as well.

The assertions have no more errors. We are making lots of progress.


Now, lets deal with the execution order for the test scripts.

In JUNIT, there is not a lot of support for it.

You can run the test scripts alphabetically by name with the @FixMethodOrder(MethodSorters.NAME_ASCENDING).

But if you need the test scripts run in other orders, I am not sure how you can do that.

In TestNG, this is done with the dependsOnMethods attribute of the @Test annotation.

For example,

 @Test(dependsOnMethods = { "test2" })
 public void test1()  {
 @Test(dependsOnMethods = { "test4" })
 public void test2(String keyword) {
In this case, test1() depends on test2() so test2() executes before test1.

test2() depends on test4() so test4() executes before test2.

Wow. This is so much better than @FixMethodOrder().

It is much simpler.

Make sure that you update your code before we move on.

My code is changed.


Now, lets change the code related to parameters.

In TestNG, similar with JUNIT, you need a method that provides the data for the parameter.

This method is annotated with @DataProvider and has a name attribute for the data provider name:

 @DataProvider(name = "data")
 public Object[][] createData1() {
  return new Object[][] {
The package org.testng.annotations.DataProvider; needs to be added as well.

Then, we need to connect the data with the parameter.

We do not need any longer to pass the parameter to the class constructor.
And we dont need a class field for the parameter, either.

The test script uses the parameter in the same way a method uses a parameter.

The test script also uses the dataProvider annotation to specify which dataProvider has the data for the parameter:

 @DataProvider(name = "data")
 public Object[][] createData1() {
  return new Object[][] {
 public void test2(String keyword) {
Still following?


What else is there to change?

JUNIT Rules.


In TestNG, you use listeners instead of rules.

They work in a similar way.

Have a look at this sample listener:

 package TestNG;

 import org.testng.ITestContext;
 import org.testng.ITestListener;
 import org.testng.ITestResult;
 import org.testng.Reporter;

 public class CustomTestListener implements ITestListener {
 public void onTestStart(ITestResult result) { 
 public void onTestSuccess(ITestResult result) {
  System.out.println("PASSED TEST");

 public void onTestFailure(ITestResult testResult) {        
  System.out.println("FAILED TEST");                 
 public void onTestSkipped(ITestResult result) {
 public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
 public void onStart(ITestContext context) {
 public void onFinish(ITestContext context) {
The custom listener class implements the ITestListener interface and overrides all its methods.

The listener can then be attached to a test class using the @Listeners annotation:

 public class TestNGClass {

This is very clear and similar to the JUNIT rules. With the exception that we dont need to create a class field for the new listener object.


Because the test class know what listener to use through the @Listeners annotation.

We missed something in the JUNIT code: categories.

In JUNIT, you can specify a category for a test script or for the whole test class.

This is done through the @Category annotation as follows:

 public class JUNITClass2 { 
In TestNG, groups are used instead of categories.

And they are just another attribute of the @Test annotation.

For example,

 public void test1()  {
 public void test2() {                 
test1() and test2() methods belong to the slowTests group.

OK. So use groups instead of categories.


A good side effect is that in TestNg you do not need to create an empty class for each group.

Remember that in JUNIT, before using a category, you had to create an empty class for it.

Yes, that's right. So we will have less classes now.


The last change that we will discuss is about JUNIT suites.

In JUNIT, you need test suites to run test scripts from multiple test classes based on categories.

For example:

  import org.junit.experimental.categories.Categories;
  import org.junit.experimental.categories.Categories.IncludeCategory;
  import org.junit.runner.RunWith;
  import org.junit.runners.Suite.SuiteClasses;

This test suite runs all test scripts from the 2 classes that are part of the specified category.

And how does TestNG solve this?

TestNG uses an xml file called testng.xml for organizing test classes in test suites.

When running the tests, everything happens as per the structure of this file.

In our case, testng.xml could look like this:

 < suite name="My suite" > 
  < listeners >
   < listener class-name="TestNG.CustomTestListener" />
  < / listeners >
  < test name="test1" >
   < groups >
    < run >      
     < include name="slowTests"  />
    < / run >
   < / groups >
   < classes >
    < class name="TestNG.TestNGClass" />               
    < class name="TestNG.TestNGClass2" />
   < / classes >
  < / test > 
 < / suite >
One thing to notice in the xml file is that a suite is made of tests which are made of test classes.

In a test class, you can specify the groups to be used.

In the xml file, you can also mention the listener to be used for all test classes.

So no more suite classes?

No more.

Everything is controlled by the testng.xml file.

Let have a look at the final code that uses TestNG:
 package TestNG;

 import static org.testng.AssertJUnit.assertTrue;
 import org.testng.annotations.Test;
 import org.testng.AssertJUnit;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Listeners;

 public class TestNGClass {
  public void setUp() {
  public void tearDown() {
  @DataProvider(name = "data")
  public Object[][] createData1() {
    return new Object[][] {
  @Test(dependsOnMethods = { "test2" })
  public void test1()  {
    dependsOnMethods = { "test4" })
  public void test2(String keyword) {
   AssertJUnit.assertTrue(keyword.length() > 0);
   AssertJUnit.assertEquals(keyword.contains("-"), true);  
  public void test3() {
  public void test4() {  
  @Test(expectedExceptions = IndexOutOfBoundsException.class)
  public void test5() {  
   throw new IndexOutOfBoundsException();
We are almost at the end of the conversion process.

Lets run the TestNG tests.

They run correctly.

What do you think about converting a test class from JUNIT to TestNG?

Was it too complicated?

With all these details, I felt that it was very easy. I am looking forward to starting using TestNG in my test automation project.

Good luck!