As I mentioned in my post about best practices, automating the early stages in the game is crucial for me. I’ll share how I use Appium with Image Recognition to make sure everything works fine in the tutorial of Heroes of Paragon.

First – the platform. I use Testdroid. On their website you can find also a zipped package of everything else you need to do what I do – Appium with Akaze and OpenCV for image recognition, all with an example script already.

Why Image Recognition? Simply put, testing the game requires a lot of user input, most of which is clicking the right part of the screen at the right time. Using X/Y coordinates is not optimal – it limits you to testing only one resolution at a time. Same goes for using screen percentage – screen ratio can vary. Also, what if the element you want to click is not there for some reason? You won’t know and the test will just go on, even though it should fail already.

So what to do? Rather than clicking blindly, give Appium a picture of something to look for in the game (a button, a character, building…). If it’s found – take an action (click, press back, wait – whatever you need). If it’s not found, your call – you can stop the script or you can log this information and go on. Depends on the game you’re testing and the specific scenario.

Let’s move to Heroes of Paragon.

The first screen we see is the asset downloading.

01_screenshot0

This can be tricky, as depending on the device’s performance and the internet connection, the download time can differ drastically. So just waiting for a fixed amount of time will simply not cut it. To fix this, at the beginning of the test I call a function that looks for the Heroes of Paragon logo at the top, my query image:

hop_logo

The function looks like this:

public boid waitForAssets()

{

     if (findImageOnScreenNoAssert("hop_logo") != null)

     {
          driver.getPageSource();
          sleep(10);
     }

     else 

     { 
          assetsDownloaded = true;
     }

}

If the logo’s visible on the screen, wait 10 seconds and try again. If it’s not there, that means the assets are downloaded – changing the assetsDownloaded to true lets the test go on. Why do I use driver.getPageSource()? Any actions with image recognition, such as finding the image, comparing and so on are not visible for the server. So I call driver.getPageSource() every once in a while to avoid server timeout.

So in @Test I have:

while (!assetsDownloaded && counter < 25) { waitForAssets(); counter++; } if (!assetsDownloaded && counter >= 25)

{
    log("Assets not downloaded correctly, test failed");
    driver.quit();
}

Which I think is pretty self-explanatory. The counter is how long we wait for the assets to be downloaded. I decided a maximum of 25x10sec is right for me.

Next, the battle begins.

25_tutorial_loaded

First we have to select the Curse spell and use it on enemy troops. The image we’re looking for:

spells_1

I decided to use an image of all three spells, because it lowers the chances of a failed recognition – usually the smaller the image, the harder it is to find.

tapImageOnScreen("spells_1");

After the image is found, the script calculates the coordinates of it and, by default, clicks its middle. Now, when the spell is selected, we have to use it. I decided not to use image recognition on this one – middle of the screen always works, so I just use tapMiddle(); . Finding an image to click takes some time, tapping at coordinates works instantly.

The bad guys are killed, good. Now we have to select and use the Quake spell.

spells_2

The image is the same size, but now we have to click its left part. The best way to do it is to use the offset.

tapImageOnScreen("spells_2", 0.15, 0.5);

The numbers after the filename is the mentioned offset, which is used to determine which part of the image you want to click. First one – 0.0 being the left border of the image, 1.0 being the right. Analogically with the second one – 0.0 is the top, 1.0 is the bottom. After I select the spell, I use it on the battle the same way as the Curse – tapMiddle();.

So the battle is over, we move to the village. We have a few screens with an animated character and “Press anywhere to continue”. So I cut out the static part of the character, look for it and if it’s found, use tapMiddle(); again.

So for this screen:

41_after_battle

The image to look for would be:

king_right

if(findImageOnScreen("king_right") != null)
{
    tapMiddle();
}

So that’s pretty much it. Later on it’s just the same thing again, just different images. There are some small buttons to click – be careful with those. Sometimes the script may fail to find them, especially on low-res devices. If you can, prepare a bigger query image and use offset. Example:

play_build

I use this to click the “Build” button.

tapImageOnScreen("build", 0.68, 0.13);

Just using the small “Build” button would be risky. Adding the “Play” button to the image lowers the chances of a fail drastically.

 

So here it is. After you do this for all the steps in the tutorial, it’s ready to run in the cloud on as many devices as you want. Later on, you need to allocate some time to review the results – just watch the screenshots (I use takeScreenshot(“screenshot_name”); after every other action I take) to see if everything is fine. If one of your screenshot suddenly shows Android home screen or an error, download the log file and send it to the developers. On Testdroid, you can also monitor the RAM and CPU usage:

7e905df2fee99b812a7b9d495840393f

 

At some point, we used this to run the game on about 80 Android and iOS devices and it helped us track down crashes in over 20 of them and many more less critical issues in pretty much most of those devices. More is to come, battle automation being the main theme. But that’s for another post, soon.

Feel free to leave any questions you might have in the comments below.

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInEmail this to someoneShare on Reddit