First, the words written in the front

The rapid iteration speed of Internet products, you have a deep experience. As the guarantee of product quality, testers often worry about the lack of testing time. How to break the status quo to make it better now is a problem we have been thinking about. It is mentioned in software engineering that the sooner testers are involved in the development process, the earlier problems can be found, thus reducing the cost of finding problems. Therefore, “left shift” has become very necessary, of course, there are many ways to move left, for example, a few days ago I read “Talk about testing the” left shift “those things, which is mainly about testers through the control of demand to achieve the effect of the left shift, and TODAY I’m going to talk about the automation of the left shift.

Second, I see automation moving left

So if you think about the UI automation that we did earlier, what did we do? After the release test, we started to write automation so that the main function of automation became regression and smoke. What I would like to say here is that while developing and writing code, we also start writing use-case level code. After we define the interface layout, we can improve the specific code, and when we develop and test, we can run our use cases to test. How can this be done? You need to make your automated use cases highly abstract. Here, my colleague Yoyo suggests using a keyword-driven use case approach. Let’s start by looking at the class diagram:

Explain these modules a little bit

Base Test

The base class of all Test classes, the base class of Test cases, implements ActivityTestRule to start the Activity, and if necessary implements BeforeClass and AfterClass, which are executed only once at the beginning and end of the command lifecycle.

Cases to Test

A specific test case implementation class, which can be understood as a test set, each class has several test functions, each function represents a test case, the use case writing method adopts the keyword driven method.

Key

All keywords are defined with enumerations.

Command

Interface class for Word to implement execute(Obj) method.

FrameCommand

Base class, which is inherited by Word layer, encapsulates only execute(Key, Obj…) , mainly used in AW to call KW realization; Note the difference between execute and Command.

The Word layer

In other words, Login, Enter**Page and so on in the figure need to implement execute function in Command interface and inherit from FrameCommand. Explain why it is Word layer. These implementations need to be abstracted into ActionWord (AW) and KeyWord (KW). The difference between the two is that the KeyWord implements reusable scenarios, while the ActionWord can include the KeyWord to implement some scenarios that are rarely reused.

TestContext

Associate the keywords in the Key with the functions implemented in Word to construct a map so that the corresponding functions can be called directly through the execute keyword.

I won’t go into the details of the implementation code, but let’s take a look at what the code looks like when we use the framework to do the same thing.

The old code

The new code

As you can see, the test case layer is highly abstracted. In testPublish there is no information about the source code or the resource ID, where key. EnterPublishPage is our Key. The implementation is in the EnterPublishPage AW function.

Three, encapsulation framework

Of course, to ensure the stability of UI automation, I also repackaged the framework here. Here I use the two frameworks recommended by Google: Espresso and Uiautomator. If you are interested, please check out these two posts from Google:

So the two frameworks should be added to our test project at the same time how to integrate the code structure, here I use such a structure, feel good can have a look, first look at the class diagram:

As some of you may have seen after looking at the class diagram, there is a simple factory model, a concrete Word layer that uses engineered objects, and a concrete tool that encapsulates the content inside FrameUiautomator and FrameEspresso.

This is mainly about the encapsulation of Uiautomator. If you have read my “How to Be More efficient” chapter in “How to Build Android Automation Framework Uiautomator”, then some ideas in it should be relatively clear.

The main advantages

1. No need to use sleep alone for page jump or asynchronous loading delay; 2. There is no need to deal with some random factors that may affect the App interface (such as the authorization popbox of Android6.0 and phone call); 3. There is no need to deal with some pop-up boxes randomly appearing in the App that may block the normal interface; 4. All operations invoking the encapsulated framework will be logged; 5, the framework itself has the ability to assert, if the framework can not find the specified control after handling exceptions, this time will be screenshots and assert; 6. If a framework needs to be replaced or upgraded, the framework layer can be changed with minimal cost without changing the use case layer and Word layer.

Of course and before the difference is that there is also a reference to the idea of keyword driven, interested can look at the code.

4. Results presentation

Above is primarily concerned with some behavior of the UI automation operation, questions about the assertion, I don’t want to say too much here, BVT do checks on UI elements interface, and the entire process can complete it is ok to go down, if you need to verify accuracy of data and some other complex content, you can use the TMQ. The jar of this component to verify, a reference: https://github.com/r551/TMQ. I’m talking about UI automation and if it fails, how do we troubleshoot the problem? It’s actually very simple and what I did here is log + screenshot.

The most important thing about logging is the timing of logging. I buried it in BaseTest’s execute(), so that every use case call to AW or KW can be recorded, and also buried in the framework’s implementation functions, so that the framework logs every operation. Here’s a little trick. I called the following function where the log was printed:

Thread.currentThread().getStackTrace()[3].getClassName();

This will record the name of the current class that called the Log function at that time. Here is what the Log output looks like:

Is it complete? Basically all the information you want to know can be obtained through the log content. Let’s talk about screenshots. Like log, screenshots support manual calls at key points. Since my tool framework supports its own assertions, I will include screenshots in the tool framework layer for assertions, and you can also manually invoke screenshots elsewhere if you need to pay special attention.

The above diagram is not very intuitive. When abnormal errors occur in our use cases, we can directly locate the problem through the log and log. The test results, finally connected to the internal continuous integration platform and results presentation platform, look like this:

The result in the compiler is guaranteed to be the same as the result display platform.

5. Practical application

Let’s look at how to respond to old and new needs.

If it is a new demand, we can first in the case of demand determine the organization’s own case, specific implementation depend on the development of word layer code can be empty, for sure, we can timely perfect our word layer, so don’t have to wait until the development after the test, we started to design our automated test cases.

Change in demand for the old, too, first of all we can see in the previous cases key reusable things, if can directly reuse, then continue to use, if there are new steps included, so you just need to join the corresponding keywords, as well as the practice of new demand, also in the development of complete case writing before test. Here, in the version iteration, there is a UI change of the release page, which is merged from two pages into one page, and some small parts are also modified, as shown in the figure below:

Changed to:

However, after the new version, the use case does not need to change at all, it is still the same as before, but some code in the corresponding Word layer has been slightly adjusted.

Six, will there be earnings?

I was thinking about this before the whole scheme was launched. So is this going to be profitable? Whether there is profit or not needs to be analyzed to know, so a simple bug analysis was made for the latest version:

As you can see from the data, there are some bugs that can be found in the left shift phase. There are bVT-level use cases and detailed module use cases. BVT level use cases to limit the development of test, test before the development of their own to move this part of the use cases, can be passed test; Detailed module content for specific functionality levels is modified or added specifically for this release.

After implementation, the whole scheme is only in just one version in practice, because of some factors, the project is stopped, only this time practice is in a relatively informal incomplete version, even so left practice since found six bugs effectively, which I also hit a question mark in the title. Although it was a pity in the end, I still learned a lot in the whole process. I share it with you and hope it can help others.

Copyright, prohibit reprint