Giới thiệu
Selenium grid là một trong các bộ testing tool của Selenium. Nó giúp chạy nhiều kịch bản test trên nhiều device, browser, máy trong cùng một lúc.
Có hai lý do chính để bạn cân nhắc việc sử dụng Selenium Grid cho các dự án của mình đó là:
- Các kịch bản test của bạn yêu cầu phải được kiểm tra trên nhiều trình duyệt khác nhau, nhiều hệ điều hành và trên nhiều máy test khác nhau trong cùng một lúc. Việc này để đảm bảo là các ứng dụng của bạn tương thích với các hệ điều hành cùng với các môi trường hoạt động khác nhau.
- Hai là, để tiết kiệm thời gian thực hiện bộ test case. Ví dụ, ứng dụng của bạn cần phải test trên 4 trình duyệt khác nhau, thông thường cùng với 1 test case bạn phải chạy 4 lần, nhưng với Selenium Grid thì bạn chỉ cần chạy 1 lần!
Hub và Node trong Selenium Grid
Hai thành phần cơ bản trong Selenium Grid gồm có Hub và các Node.
Trong selenium grid, Hub đóng vai trò là một máy tính trung tâm, nơi mà các kịch bản kiểm thử của bạn được load tới đó.Hub ở đây có vai trò là tìm các node có điều kiện tương ứng với yêu cầu đầu vào của bạn và chuyển các test case tới đúng môi trường cần chạy đó
Mỗi Grid chỉ nên có một Hub, và Hub này được khởi chạy trên một máy duy nhất.
Nodes là các máy test được kết nối với máy Hub, nó sẽ thực hiện run các kịch bản kiểm thử mà bạn đã load lên Hub. Trong một grid bạn có thể xây dựng một hoặc nhiều node.
Đặt vấn đề
Làm sao để biết node nào đang available để chỉ định run test case trên node đó ?
Tìm hiểu
Ta thấy selenium grid có hiển thị trạng thái node nhưng chỉ ở giao diện web chứ ko có support api nào để get theo kiểu json.
Tuy nhiên ở selenium có support một số tính năng sau:
- Xây dựng một new servlet
- Cung cấp một Prioritizer
- Provide a new Capability Matcher
- Provide a new RemoteProxy
Để giải quyết vấn đề ở trên ta chỉ cần export một api get list free node bằng cách sử dụng servlet
Version thực hiện
Java: jdk 8
Selenium: 3.141.59
Cách thực hiện
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>selenium-grid-extend</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-server</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
</dependencies>
</project>
Để get status node ta sử dụng kế thừa từ class RegistryBasedServlet
package selenium.extend.hub.servlet;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import java.io.IOException;
import java.util.Iterator;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.openqa.grid.common.exception.GridException;
import org.openqa.grid.internal.GridRegistry;
import org.openqa.grid.internal.ProxySet;
import org.openqa.grid.internal.RemoteProxy;
import org.openqa.grid.web.servlet.RegistryBasedServlet;
public class AllNodesState extends RegistryBasedServlet {
public AllNodesState() {
this(null);
}
public AllNodesState(GridRegistry registry) {
super(registry);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
process(request, response);
}
protected void process(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.setStatus(200);
try {
JsonObject res = getResponse(request);
response.getWriter().print(res);
response.getWriter().close();
} catch (JsonSyntaxException e) {
throw new GridException(e.getMessage());
}
}
private JsonObject getResponse(HttpServletRequest request) {
ProxySet proxies = super.getRegistry().getAllProxies();
return getNodes(proxies);
}
private JsonObject getNodes(ProxySet proxies) {
Iterator<RemoteProxy> itr = proxies.iterator();
Gson gson = new Gson();
JsonArray freeProxies = new JsonArray();
JsonArray busyProxies = new JsonArray();
while (itr.hasNext()) {
RemoteProxy proxy = itr.next();
JsonObject proxyJson = new JsonObject();
proxyJson.add("nodeName", gson.toJsonTree(proxy.getOriginalRegistrationRequest().getConfiguration().capabilities.get(0).asMap().get("nodeName")));
proxyJson.add("udid", gson.toJsonTree(proxy.getOriginalRegistrationRequest().getConfiguration().capabilities.get(0).asMap().get("udid")));
proxyJson.add("platform", gson.toJsonTree(proxy.getOriginalRegistrationRequest().getConfiguration().capabilities.get(0).asMap().get("platform")));
proxyJson.add("browserName", gson.toJsonTree(proxy.getOriginalRegistrationRequest().getConfiguration().capabilities.get(0).asMap().get("browserName")));
System.out.println("node info" + proxy.getOriginalRegistrationRequest().getConfiguration().capabilities);
if (!proxy.isBusy()) {
freeProxies.add(proxyJson);
} else {
busyProxies.add(proxyJson);
}
}
JsonObject nodeJson = new JsonObject();
nodeJson.add("freeNodes", freeProxies);
nodeJson.add("busyNodes", busyProxies);
return nodeJson;
}
}
Start Hub bằng command line
java -cp selenium-grid-extend-1.0-SNAPSHOT.jar:selenium-server-standalone-3.141.59.jar:gson-2.8.6.jar org.openqa.grid.selenium.GridLauncherV3 -role hub -servlets "selenium.extend.hub.servlet.AllNodesState"
Start node
Check kết quả
Kết quả hiện thị trên browser
Như vậy có thể lấy được trạng thái các node đang kết nối tới hub một cách dễ dàng
Reference
https://www.slideshare.net/seleniumconf/introduction-to-seleniumgridworkshop