An overview of the

Bee is a UI automation tool developed by Uzan QA, and realizes the automation of the core business of web and WAP. Designed to simplify the interface provided by open source tools and facilitate the design of UI automated test cases.

The whole Bee framework is designed based on Selenium and Selenide. The framework encapsulates the interfaces provided by Selenium and Selenide twice to meet the needs of daily use case design. The interface after the second encapsulation solves some problems such as element loading, element positioning and resolution, which makes use case design more convenient. Bee can support element location and operation of Web and Wap pages. Selenide mainly supports element operation of Web pages, and Selenium supports element operation of Wap pages.

Why Bee adopts Selenide+Selenium mode? First, the framework was designed to rely entirely on Selenide to automate the Web and Wap. Selenide is a new open source framework for the author, who wanted to take a peek. Second, Selenium is seamlessly accessible. In practice, Selenide does not support Wap pages and does not meet the daily testing requirements. Fortunately, the framework can be easily embedded in Selenium to automate Wap pages, which is why Selenide and Selenium have this feature. So at the beginning of the framework design, I dared to use Selenide; The third reason is that Selenide’s handling of page elements is much smoother than Selenium’s in practice, because Selenide itself is a secondary encapsulation of Selenium, and the interface of Selenium has been optimized a lot.

Bee currently supports MAC and Chrome environments, and the entire framework supports extensibility.

The principles of Selenide and Selenium are not described in this article, you can learn about them online. Bee open source address: Beeyz, welcome to exchange.

Use case design

The flexibility of designing use cases depends on the granularity of pageObject package. The smaller the granularity is, the easier it is to design test cases of the new process at the use case layer. The use case layer uses Testng to flexibly design a test case based on actual requirements. When encapsulating the pageObject interface, it is recommended to define the granularity as small as possible to facilitate the extension and maintenance of use cases. The interface encapsulated by pageObject is like an atom, and the smaller the atom, the easier it is to assemble new use cases. On the contrary, if the granularity is too coarse, it will be inconvenient to maintain. Reference code:

The screenshot is a split-kill use case. Before creating an activity, you need to login to the background of Youzan Micro mall, login operation has been encapsulated into loginService, directly call the interface of the Service layer, do not need to care about the details of this step; After login, specify an item to participate in the seckill activity. The common item creates an interface that is encapsulated in goodsService and directly calls the Service layer, regardless of the details of this step. The next step is to create a seckill activity. All the business steps of creating a seckill activity are encapsulated in the seckillPage, which is the implementation of a pageObject and the most important step in use case design. Finally, these steps are strung together to form a test case for a splice activity. Use cases are clearly structured and simple to assemble.

The framework is introduced

1. Engineering structure

The whole project is based on Selenide & Selenium, using pageObject mode to build up. Selenide + Selenium + Testng + Reportng + Spring Several important modules in the project are introduced below.

1.1 DataProvider – Data layer

In order to separate test data from test cases, the data model is defined in the Model and the specific test data is initialized in the DataProvider.

1.2 Driver – Interface layer

This is where the interface is defined and implemented for all elements of the Web page. The Driver encapsulates the interfaces provided by Selenide&Selenium and provides encapsulated interfaces externally. Common implements some common methods related to interfaces, such as emulated keyboard buttons. Currently, common encapsulates few methods, and most functions can be implemented through Selenide&Selenium. The driver layer encapsulates the open source tool interface. If you want to drive a browser, there is also an essential tool — the browser driver. This driver is placed in resources, and the version of the driver must match the version of the browser under test.

1.3 Listeners – Listeners

Listen for events to improve the fault tolerance of the framework itself. At present, the following are achieved: 1. Monitor the test results of use cases, and do different processing for different test results listeners; 2. 2. Listening for retry of failed test cases. A failed test case can be retried for a maximum of three times.

1.4 Model — Data model

A method adopted to separate test data from test cases in which specific test data is initialized in the DataProvider. Elements of a business process that require test data can be defined in a model for easy management and code reading.

1.5 pageObject – Business layer

PageObject mode, the interface form encapsulates each page needs to use the element, the realization of only two steps: to determine the positioning of the element; Invoke the corresponding operation interface in the driver. The interface implementation of Driver contains a certain fault-tolerant capability, but it is not comprehensive. The uniqueness of some pages or components simply calling the interface of driver cannot guarantee the stability of test cases. In this case, it is necessary to add some fault-tolerant algorithms into the interface implementation of pageObject to ensure the stability of use cases. The practical experience is that the less granularity pageObject encapsulates the elements, the more flexible it is to design test cases at the use-case design layer, and to assemble a new test case like an assembly tool. Reference code:

1.6 Service – Provides service functions

Many times a business process relies on other business module functions. To facilitate the design of a test case and to avoid duplication of wheels, the Service layer provides some common business functions, such as logging in, creating goods, and so on. The dependent party only needs to call at the Service layer.

2. Function optimization

Bee encapsulates Selenide&Selenium and optimizes the interface. The framework is designed to make designing a UI use case as easy to design, read, and maintain as possible.

2.1 Interface Optimization

The interface that directly calls selenide or Selenium often encounters some headache problems. For example, network problems cause the page to load too slowly, and the elements that need to be operated on are not displayed. In this case, errors are often reported that the elements cannot be found, and use cases fail to execute. But this error is not actually a bug, and the test results are invalid. To improve false positives, the driver layer interface implements the function of waiting for elements to load, using the key interface: Selenide.$(elementLocator).waituntil (Condition. Appears, timeout). Reference code:

'/** ** Check element loading * @param elementLocator * @param timeout * @return
     */
    private boolean checkElementLoad(By elementLocator, long timeout){
        try {
            Selenide.$(elementLocator).waitUntil(Condition.appears, timeout);
            return true; }catch (Exception ex){ throw new RuntimeException(ex); }} /** * Throw a null exception if no element is found * @param Element * @param timeout * @param elementType * @return*/ private By isElementLoaded(String element, long timeout,String ... elementType){ By elementLocator = null; int count = 4; long partTimeout = timeout/count;for(int i=0; i<count; i++) {
            elementLocator = waitingForElementLoad(element, partTimeout, elementType);
            if(null ! = elementLocator){break;
            }else if(null == elementLocator && (count-1) == I) {// Element for null throws an exception log.error("Web page element: {} could not be located",element); }}returnelementLocator; } `Copy the code

It is mentioned in the overview that Selenide is itself a secondary encapsulation of Selenium, so Selenide operations on elements are much smoother than Selenium. Selenide has optimized page loading, and adding waitUntil judgment in click, input and other operation interfaces can maximize the waiting for the loading of an element, thus improving the stability of test cases.

2.2 Unified entry for element positioning

If you are familiar with UI automation use case design, you will know that selenide&Selenium operates on an element, and it is essential to describe the location of the element. Generally speaking, it tells the interface to operate on the element in the current page. There are many ways to locate an element, such as ID, name, CSS, xpath, etc., corresponding to different locating methods selenide&Selenium also provides different interfaces in processing. This is obviously not the best from a maintenance point of view. The best practice is for the use case designer to focus only on element positioning and manipulation of the invocation of events, and which channel the event implementation goes through is best sensorless and maintenance-free. The framework encapsulates a method called by the driver that parses a string describing an element to automatically determine whether it is an ID, CSS, or xpath.

2.3 Failed Test Case Retry

Uncertain factors such as network causes will lead to test case failure, which is generally regarded as invalid. In order to improve the credibility of test report, a retry mechanism for failed use cases is added. The idea is to implement a listener for the test results of a use case. When the listener listens for a fail result, it triggers a retry. The failed use case can be retried up to three times.

3. Element positioning

UI automation use cases can actually be divided into two parts: 1. Location elements; 2. Call the interface to manipulate the element. There are many ways to locate an element, including ID, name, CSS, and xpath. In the actual design, which positioning method to choose will generally be considered more in the perspective of maintenance, because the current server performance configuration is very good, so running a Web-UI use case can not consider the performance problem. In terms of maintenance cost, ID and name will be preferred, followed by CSS and xpath.

We can’t guarantee that every element of a Web system will give you a unique ID or a unique name, but it would be nice to work with front-end development, as we usually have to deal with the absence of id and name attributes. At this point we can use CSS styles, many times CSS styles can meet our positioning needs. Of course, if none of these are provided to us, we can only choose xpath. Advantages of using xpath 1. Easy to obtain, mainstream browsers as long as open “View” can be easily obtained by copy; 2. Elements on a page can be described using xpath; Disadvantages, instability, and heavy use can impose a heavy burden on use case maintenance. Xpath generally needs to be re-maintained as long as the front end makes a small adjustment on the page. In the case of having to use xpath, some optimization can be made on xpath to reduce the amount of maintenance in the future, and the path length of xpath can be reduced to improve the stability. Here are some of the most commonly used types in practice:

  1. Rely on their own attribute text positioning, such as //input[@value= ‘XXXXX’]
  2. Contains indicative characters, such as //input[contains(text(), ‘indicative character’)]
  3. Ingenious use of retrieve, such as //*[@id= ‘app-container’]/ retrieve ::input

CI integration

Once the use case design is complete, integration construction can be added to make the UI automation use cases work in the integration environment. Test reports are presented using Reportng. Jenkins plugins can present reports well, so Reportng + Jenkins is a good combination.

  1. Build a Jenkins.
  2. A server for running UI automation use cases.
  3. Configure the server as one of Jenkins’ nodes.
  4. Jenkins creates a job. The plug-ins used in the job include Git, Excute shell, Editable Email Notification, and Publish HTML Reports. Editable Email Notification, which supports email notifications, is a good plugin. Support HTML report format, attachment function.

Common error

Some problems are often encountered in the process of using Bee. Here is a summary to facilitate debugging.

  1. Some pages do not scroll. Sometimes you can’t show everything on one screen. In theory, Selenide or Selenium can automatically perform scrolling to find an element in a page, but sometimes scrolling doesn’t work, and you need to implement scrolling to find elements in test cases. Void scrollToElement(String Element,String… elementType)
  2. Some input fields do not operate properly by the input interface. In practice in the calendar control encountered, element positioning and everything is correct, but it is not the normal operation. Void triggerInput(String element,String… ElementType), which acts as a trigger and can be used as an attempt in a similar situation.
  3. Buttons cannot be operated by the click interface. The button element is properly positioned. You also see the Button property in the Check window.<button type="button" class="zent-btn-primary zent-btn-large zent-btn">Void clickByText(String text)
  4. When selenide or Selenium does not work, it is most likely that the browser has been upgraded. Solution: Upgrade the browser driver
  5. The element is not visible. An element that appears normally on a page but is not visible to the tool needs to be visible under the following conditions: Visibility! =hidden ; display! =none; opacity! = 0; Both height and width are greater than 0; For the input tag, there is no hidden attribute. The screenshot is an example of opacity=0.

Void clickByJs(String Element,String… elementType)

conclusion

Bee is based on the open source tools to do some optimization, so far Bee has made more efforts in the driver layer, data layer, business layer and use case layer of the solution has a lot of room for improvement. There are two main ways to implement a Web-UI automation use case: recording and code implementation. Both methods have their advantages and disadvantages.

Bee is not perfect yet, and further efforts are needed. Thank you for supporting Bee development all the time, you have praise, you have Bee.