Automotion – simple solution for complicated problems

Automotion – simple solution for complicated problems

In this article I decided review simple Java library for automation testing that is successfully implemented already for many different projects.

So, let’s start.

What are the main problems that we have when we want to start automation testing on a new project? Usually there are:

  1. Which technologies to choose? Java, Python, C#, Ruby or maybe try with JavaScript? Yeah, each of technologies has benefits and limitations. And usually we don’t know what we will need in the future.
  2. What kind of application do we want to test? Mobile or Web or maybe Mobile-Web? Maybe we will require to test RESTful services or mail services?
  3. Need to write many validators from scratch. Need to organise the structure of capabilities, drivers, getters and setters for configurations.

googley-eye-birdie-has-questions

So, I decided that need to write something that will help me to avoid such questions in the future. This “something” must be universal framework that can be easy connected to each project.

Now Automotion library is available on GitHub here

The main most useful functions that available in Automotion are:

  1. Super easy method for connection of WebDriver to the maven project. Support for Remote Web Driver and Appium Driver as well. Also it allows to run the tests in mobile simulation Chrome mode. You can update Your capabilities in the way You want. Also here is implemented methods for connection with SauceLabs.
  2. Powerful feature for performing HTTP(s) requests with attachments, authorisation, etc.
  3. Functions that allow to perform connection to IMAP mail services and verify mailboxes.
  4. Functions that allow to identify which of the languages are on the web and mobile pages. Support up to 70 languages.
  5. Smart text finder that allows to find even broken text. For example, You need to find the phrase “Try Again”, but You have recognised text like ” gh try gh 6%^7 hjgasd 7^& dfg!44d T@y GaIN#%hjk in”. People are able to find something similar to “Try Again”. It’s “T@y GaIN”. But machine cannot find it. So, this algorithm allows to find such phrases.
  6. Lots of useful helpers for the web and mobile automation testing:
    • Different variations of scrolling and swiping for iOS, Android and Web
    • Function that allow to hide keyboard on Android and iOS devices
    • Different smart functions for clicking on the web or mobile elements. For example, if You need to click on the right top corner of element
    • Functions for manipulating of network and settings on Android devices
  7. Smart functions for validation that elements on the page are aligned correctly. These functions are super useful for the validation of UI, especially header, footer and different static content.

All these functions could easy cover the most complicated cases in automation testing. With Automotion You don’t need anymore to look for the solutions. Everything is ready.

If You’re interesting to know more about Automotion library – feel free to contact with me directly. My email is available on the page About Me. Also, if You know another cases that could be added to Automotion – let me know or feel free to contribute on Github.

Thank You for reading this article and have a good automation!

Smart text finder

This small but smart algorithm allows You to perform intelligent search for the words and phrases in the text. Imagine that You have recognised the text from the image. Usually there are many corrupted characters and it’s impossible to find something directly.

For example, You need to find phrase “Try Again”, but You have recognised text like ” gh try gh 6%^7 hjgasd 7^& dfg!44d T@y GaIN#%hjk in”. People are able to find something similar to “Try Again”. It’s “T@y GaIN”. But machine cannot find it. So, this algorithm allows to find such phrases.

The source code is here on GitHub

Here is algorithm:

public static boolean textIsFound(String pattern, String text) {
    pattern = pattern.toLowerCase();
    text = text.toLowerCase();

    if (text.contains(pattern)) {
        return true;
    } else if (text.replace(" ", "").contains(pattern.replace(" ", ""))) {
        return true;
    } else {
        String[] patternArr = pattern.split("\\W|\\s");
        String[] textArr = text.split("\\W|\\s");

        int matchTime = 0;
        int positionPrev = 0;
        for (String sp : patternArr) {
            for (String st : textArr) {
                if (st.equals(sp)) {
                    int positionNext = Arrays.asList(textArr).indexOf(st);
                    if (positionNext > positionPrev) {
                        positionPrev = positionNext;
                        matchTime++;
                        break;
                    }
                } else if (st.contains(sp)) {
                    matchTime++;
                    break;
                }
            }
        }

        boolean found = false;
        if (matchTime != patternArr.length) {
            String textJoined = String.join("", textArr);
            String patternJoined = String.join("", patternArr);
            String[] patternJoinedArr = patternJoined.split("");

            int position = 0;
            Map<Integer, String> positions = new TreeMap<Integer, String>();

            for (String s : patternJoinedArr) {
                while (position >= 0) {
                    position = textJoined.indexOf(s, position + 1);
                    if (position > -1) {
                        positions.put(position, s);
                    }
                }
                position = 0;
            }

            int count = 0;
            int countInLine = 1;

            for (Map.Entry entry : positions.entrySet()) {
                Integer i = (Integer) entry.getKey();
                if (positions.get(i + 1) != null && count < positions.size()) {
                    countInLine++;
                } else {
                    countInLine = 1;
                }
                if (countInLine >= patternJoined.length() * (1 - DERIVATION)) {
                    found = true;
                    break;
                }
                count++;
            }
        }

        return matchTime == patternArr.length || found;
    }
}

Enjoy it!

Algorithm of looking for “Equilibrium indexes” (Java)

This is small article about how to find all the equilibrium indexes in integer array. This is very efficient solution. Usually time of execution is O(n^2). This is solution for O(2*n)

@Test
public void verifyThatNumbersAreEquilibrium(){
    CodeBase codeBase = new CodeBase();
    int[] arrOfNumbers = new int[]{6,1,1,1,1,1,1,1};
  //int[] arrOfNumbers = new int[]{1,1,1,1,1,1,1,6};
    System.out.print(codeBase.getListOfEqIndexes(arrOfNumbers));
}
public List getListOfEqIndexes(int[] arr) {
    List list = new ArrayList();
    int tempSumLeft = 0;
    int sum = 0;
    for (int i = 0; i < arr.length; i++) {
        sum += arr[i];
    }

    int sumRight = sum - arr[0];

    for (int i = 0; i < arr.length; i++) {
        if(i-1 >=0) {
            tempSumLeft += arr[i - 1];
        }
        if (tempSumLeft == sumRight) {
            list.add(i);
        }
        if (i + 1 < arr.length) {
            sumRight -= arr[i + 1];
        }
    }

    return list;
}

What to use: ArrayList vs LinkedList

I think that this article should be interesting for all who have a question “what data structure to use?”. In this article we will compare  ArrayList and LinkedList. Data type is Integer. List size is 1 000 000 items. We will perform a 10 000 operations with the lists, such as: adding to the front, adding to end, adding to the middle, remove from the head, remove from the end, remove from the middle.
How we will do it:

public void listTimeTest(){
    List<Integer> list = new ArrayList<Integer>();
    //List<Integer> list = new LinkedList<Integer>();

    for(int i = 0; i < 1000000; i++){
        list.add(i);
    }

    long start = System.currentTimeMillis();

    for (int i = 0; i < 10000; i++){
        //list.add(0, i); To the front
        //list.add(i); To the end
        //list.add(list.size()/2, i); Into the middle

        //list.remove(0); From the head
        //list.remove(list.size()-1); From the end
        //list.remove(list.size()/2); From the middle
    }

    long end = System.currentTimeMillis();

    System.out.print("Time of execution is: " + (end - start) + "ms.");
}

Time results are very interesting:

  1. Add to the front:
    • LinkedList – Time of execution is: 5ms.
    • ArrayList – Time of execution is: 4358ms.
  2. Add to the end:
    • LinkedList – Time of execution is: 2ms.
    • ArrayList – Time of execution is: 1ms.
  3. Add into the middle:
    • LinkedList – Time of execution is: 26329ms.
    • ArrayList – Time of execution is: 1703ms.
  4. Remove from the head:
    • LinkedList – Time of execution is: 4ms.
    • ArrayList – Time of execution is: 4220ms.
  5. Remove from the end:
    • LinkedList – Time of execution is: 3ms.
    • ArrayList – Time of execution is: 1ms.
  6. Remove from the middle:
    • LinkedList – Time of execution is: 27737ms.
    • ArrayList – Time of execution is: 1793ms.

So, as You see, ArrayList won everything except operations in the head of the list.

Resolution:

  • If You want to perform operations in the front  of the list – use LinkedList
  • If You want to perform operations in the end  of the list – doesn’t matter what to use because time of execution is almost the same (approx. 1-3ms)
  • If You want to perform operations in the middle of the list –  use only ArrayList. Difference in the time is almost 15x times faster then LinkedList.

Thanks for reading my article.

Cheers.

 

Agile testing

Agile testing

If You want to start with agile testing on Your project – firstly You need to forget that You’re only QA/QC. In agile testing You are agile software development engineer which is involved in development processes from test perspective.
It’s very interesting – what are real responsibilities of agile tester?
Let’s think about usual responsibilities of testers on the project. Tester need to write test documentation, tester need to test application and report a bugs, tester need to prepare release documentation about defects, test process, etc.

But maybe it’s possible to avoid unwanted bugs? No – it’s impossible. But possible to reduce amount of the bugs. How to do it?
First of all – tester need start to think not only on the level of acceptance user. Try to think on unit level of application, on component and integration level. Try to think about behaviour of relationship between component.

Yes, I’m talking about TDD and BDD approaches. For this You need to know another agile testing approaches which are very useful and are required.

Test pyramid

idealautomatedtestingpyramid

As a agile tester You need to make test coverage on Your test application like it’s on image above. If You want to avoid long time verification during GUI testing, UAP testing – try to cover Your application by tests on unit and integration levels. This approach will help You to avoid the verification of a lot of cases on GUI level. This is ideal model.

Another approaches – Agile testing Quadrants (image is taken from http://lisacrispin.com/)

Agile-Testing-Quadrants

Important to divide You project for 4 Quadrants. Each of these quadrants covers another side of the project. You need to remember about importance of Automation testing on the project. Automation testing – it’s not only coverage of application on GUI level. It’s coverage by Unit tests, Behaviour tests.
Each of these quadrants also has priority. I will try to explain more about Agile testing quadrants in the next articles.

Let’s go next.

TDD and BDD

What is TDD (Test-driven development) is a software development process that relies on the repetition of a very short development cycle: first the developer writes an (initially failing) automated test case that defines a desired improvement or new function, then produces the minimum amount of code to pass that test, and finally refactors the new code to acceptable standards (From Wikipedia).

16728

It’s mean that agile tester should really know development process.
What the tools are useful – all the unit-test framework. (JUnit, NUnit, TestNG etc.). It’s depend on platform where You’re working.

But what if You need to join all the created functions? You need to create some real behaviour scenarios and test it too. You need to think from business perspective and from test perspective on development level.
In this case it’s time to bethink about ATDD.
ATDD (Acceptance test-driven development) 
is a development methodology based on communication between the business customers, the developers, and the testers. ATDD encompasses many of the same practices as Specification by Example, Behaviour Driven Development (BDD), Example-Driven Development (EDD), and Story Test-Driven Development (SDD). All these processes aid developers and testers in understanding the customer’s needs prior to implementation and allow customers to be able to converse in their own domain language. ATDD is closely related to Test-Driven Development[TDD]. It differs by the emphasis on developer-tester-business customer collaboration. ATDD encompasses acceptance testing, but highlights writing acceptance tests before developers begin coding. (from Wikipedia)

The most popular practices is BDD. You can describe Your test story in human-readable text or html file and implement it in the code. This is very useful if You want to collect You test documentation and code in one place. It’s called Living documentation.
The most popular tools are JBehave, Cucumber, Concordion.

So, as You see – agile tester it’s a bit different tester from non-agile, because agile tester need to be able with developers on the same code. Don’t scare to use these approaches and practices on Your project. You will see benefits after some times. It will help to save the time of test execution.

Best regards,

Denys

Unit testing as part of QA’s responsibility

Hi folks!
This article is about unit testing in responsibility of QA engineer. As we know – exists different type of testing: unit (module), component, integration etc. Generally  – coverage of code by unit tests is developer’s responsibility. Because for developer it’s easy to do. He knows how some method was implemented and what need to verify here. But in this case a lot different edge-cases could be missed. That’s why now is existing some tendency that test engineers should covers the code by unit tests. Here are some benefits: test engineer will be read each line of the code and can find some gap where not implemented exception or something like this. Test engineer knows a different technique of testing, like boundary values etc. Test engineer will think how to implement DDT in TDD.
Ok, let’s think that You are assigned to the project and You need to do something like this. How to start and what You need to know.

  1. What framework for Unit testing is used. Is it JUnit or TestNG for JAVA.  NUnit or MSTest for C#?
  2. You need to think how much data You need to cover some functionality. You need to know this for choosing format of data saving. If it should be a lot of data for 1 test – better to save it in some *.xsl or *.csv files. If it should be a data for a lot of different tests – better to collect everything in *.xml or json format. Much easier to read file for people (from my perspective)
  3. You can divide the test classes by some logic or better – it’s to have separate test classes for each of classes in application.
  4. As QA – You need to find all the gaps in the code. You need to find where can happens unexpected exceptions and need to cover it.
  5. Remember – that unit test should cover only one unit, not 1 big method, which contains calls to a lot of small methods.
  6. Cover by unit tests everything. Even if You are thinking that here can not be error. Better to cover everything than catch unexpected error on production.
  7. Don’t scare to ask developers if You don’t understand something.

Here are a few useful link which You can read to understand, what You need to do. EasyTest, TestNG (DataProvider).

Thanks to all! And have a good testing!