当前位置:网站首页>Interface automation framework scaffold - use reflection mechanism to realize the unified initiator of the interface
Interface automation framework scaffold - use reflection mechanism to realize the unified initiator of the interface
2022-06-28 10:10:00 【Software quality assurance】
Continue to adhere to the original output , Click on the blue word to follow me
author : Software quality assurance
You know :https://www.zhihu.com/people/iloverain1024
The return path of interface automation framework is platformization 、 Page operability , Not used by a few test students who understand the code . therefore , The front end needs a unified interface to invoke services , Forward the service to be called to the back end , Actually trigger the service initiated by the user .
One 、 summary
During program operation ,Java The runtime system always maintains a type identifier called runtime for all objects . This information tracks the class to which each object belongs . The virtual machine uses the runtime type information to select the corresponding method to execute .
JAVA The reflection mechanism is in the running state , For any class , Can know all the properties and methods of this class ; For any object , Can call any of its methods and properties ; This dynamically acquired information and the function of dynamically invoking methods of objects are called reflection mechanisms .
Especially when adding new classes in design or run , The ability to quickly apply development tools to dynamically query newly added classes . The reflection mechanism can be used to :
The ability to analyze classes at run time .
View objects at run time , for example , Write a toString Method for all classes .
Implementation of general array operation code .

Use Java Reflection , Just import JDK Built in java.lang.reflect The class in the package , No need to introduce additional Maven To configure .

Two 、 appetizer
Let's start with a very simple example , This example checks a simple at run time Java Object properties . Create a simple Person class , It's just name and age attribute , There is no way .Person The categories are as follows :
public class Person {private String name;private int age;}
The following code uses Java Reflection to get all the properties of this class . Instantiate a Person Object and use Object As declaration type :
private static List<String> getFieldNames(Field[] fields) {List<String> fieldNames = new ArrayList<>();for (Field field : fields)fieldNames.add(field.getName());return fieldNames;}@Testpublic void givenObject_whenGetsFieldNamesAtRuntime_thenCorrect() {Object person = new Person();Field[] fields = person.getClass().getDeclaredFields();List<String> actualFieldNames = getFieldNames(fields);assertTrue(Arrays.asList("name", "age").containsAll(actualFieldNames));}
Pass this test case, We can get from person Object to get an array of attribute objects , Even if the reference to the object is the parent type of the object (Object).
3、 ... and 、 Search class
In this section , We'll talk about Java Reflection API Basic usage . Pass the test case Be familiar with how to use reflection API Get information about the object , For example, the class name of the object 、 Modifier 、 attribute 、 Method 、 Implemented interfaces, etc .
3.1 Project preparation
Take animals as objects , First define the behavior interface of animal eating , This interface defines Animal The object's eating behavior . Then let's create an implementation Eating Interface abstraction Animal class ..
Eating Interface :
public interface Eating {String eats();}
Here is the implementation Eating Abstract class of interface Animal Realization :
public abstract class Animal implements Eating {public static String CATEGORY = "domestic";private String name;protected abstract String getSound();// constructor, standard getters and setters omitted}
Create another one called Locomotion To describe how animals move :
public interface Locomotion {String getLocomotion();}
Create a file called Goat The abstract class of , It inherited Animal And implement Locomotion Interface . Because the superclass implements Eating, therefore Goat You must also implement the methods of this interface :
public class Goat extends Animal implements Locomotion {@Overrideprotected String getSound() {return "bleat";}@Overridepublic String getLocomotion() {return "walks";}@Overridepublic String eats() {return "grass";}}
OK, everything , Use Java Reflection to get the Java All kinds of information about the object .
3.2. Class name
Let's start with Class Get the name of the object :
@Testpublic void givenObject_whenGetsClassName_thenCorrect() {Object goat = new Goat("goat");Class<?> clazz = goat.getClass();assertEquals("Goat", clazz.getSimpleName());assertEquals("com.baeldung.reflection.Goat", clazz.getName());assertEquals("com.baeldung.reflection.Goat", clazz.getCanonicalName());}
Class Of getSimpleName Method returns the basic name of the object , The other two methods return their full class names .
If we only know its full class name , See if you can create one Goat Class object :
@Testpublic void givenClassName_whenCreatesObject_thenCorrect(){Class<?> clazz = Class.forName("com.baeldung.reflection.Goat");assertEquals("Goat", clazz.getSimpleName());assertEquals("com.baeldung.reflection.Goat", clazz.getName());assertEquals("com.baeldung.reflection.Goat", clazz.getCanonicalName());}
We give static methods forName The parameter of should contain class package information , otherwise , We're going to get one ClassNotFoundException.
3.3. Class modifier
We can call getModifiers Method to get the class modifier , This method returns a Integer.
java.lang.reflect.Modifier Class provides static methods to analyze the returned Integer Is there a specific modifier .
Let's look at some of the class modifiers defined earlier :
@Testpublic void givenClass_whenRecognisesModifiers_thenCorrect() {try {Class<?> goatClass = Class.forName("com.baeldung.reflection.Goat");Class<?> animalClass = Class.forName("com.baeldung.reflection.Animal");int goatMods = goatClass.getModifiers();int animalMods = animalClass.getModifiers();assertTrue(Modifier.isPublic(goatMods));assertTrue(Modifier.isAbstract(animalMods));assertTrue(Modifier.isPublic(animalMods));} catch (ClassNotFoundException e){e.printStackTrace();}}
Of course, we can also get the information introduced in the project through this method jar Class modifier for .
3.4. Package
We can also get information about packages of any class or object , By calling the class object getPackage Method returns .
@Testpublic void givenClass_whenGetsPackageInfo_thenCorrect() {Goat goat = new Goat("goat");Class<?> goatClass = goat.getClass();Package pkg = goatClass.getPackage();assertEquals("com.baeldung.reflection", pkg.getName());}
3.3. Superclass
in many instances , Especially when using library classes or Java The built-in class of , We may not know the superclass of the object we are using in advance .
But we can use Java Reflection to get any Java The class of the superclass , The following code to get Goat Superclass of .
@Testpublic void givenClass_whenGetsSuperClass_thenCorrect() {Goat goat = new Goat("goat");String str = "any string";Class<?> goatClass = goat.getClass();Class<?> goatSuperClass = goatClass.getSuperclass();assertEquals("Animal", goatSuperClass.getSimpleName());assertEquals("Object", str.getClass().getSuperclass().getSimpleName());}
3.6. Implemented interface
Use Java Reflection , We can also get a list of interfaces implemented by a given class . Let's get Goat Classes and Animal The class type of the interface implemented by the abstract class :
@Testpublic void givenClass_whenGetsImplementedInterfaces_thenCorrect(){Class<?> goatClass = Class.forName("com.baeldung.reflection.Goat");Class<?> animalClass = Class.forName("com.baeldung.reflection.Animal");Class<?>[] goatInterfaces = goatClass.getInterfaces();Class<?>[] animalInterfaces = animalClass.getInterfaces();assertEquals(1, goatInterfaces.length);assertEquals(1, animalInterfaces.length);assertEquals("Locomotion", goatInterfaces[0].getSimpleName());assertEquals("Eating", animalInterfaces[0].getSimpleName());}
Notice from the assertion that , Each class implements only one interface . Check the names of these interfaces , We found that Goat Realized Locomotion and Animal Realized Eating.
We can find out Goat Abstract class Animal Subclasses of , Interface methods are also implemented eats(),Goat In fact, it has also realized Eating Interface .
But here's the thing , Only classes are explicitly declared to use implements Only those interfaces implemented by the keyword will appear in the returned array .
therefore , Even if a class implements interface methods ( The inherited parent class implements the interface method ), But it is not used directly implements Keyword to declare the interface , The interface will not appear in the returned interface array .
3.7. Constructors 、 Methods and properties
Use Java Reflection , We can also get constructors and methods and properties of any object class .
private static List<String> getMethodNames(Method[] methods) {List<String> methodNames = new ArrayList<>();for (Method method : methods)methodNames.add(method.getName());return methodNames;}
Let's see how to get Goat Class constructor :
@Testpublic void givenClass_whenGetsConstructor_thenCorrect(){Class<?> goatClass = Class.forName("com.baeldung.reflection.Goat");Constructor<?>[] constructors = goatClass.getConstructors();assertEquals(1, constructors.length);assertEquals("com.baeldung.reflection.Goat", constructors[0].getName());}
We can also get Animal Attributes of a class :
@Testpublic void givenClass_whenGetsFields_thenCorrect(){Class<?> animalClass = Class.forName("com.baeldung.reflection.Animal");Field[] fields = animalClass.getDeclaredFields();List<String> actualFields = getFieldNames(fields);assertEquals(2, actualFields.size());assertTrue(actualFields.containsAll(Arrays.asList("name", "CATEGORY")));}
We can similarly obtain Animal Class method :
@Testpublic void givenClass_whenGetsMethods_thenCorrect(){Class<?> animalClass = Class.forName("com.baeldung.reflection.Animal");Method[] methods = animalClass.getDeclaredMethods();List<String> actualMethods = getMethodNames(methods);assertEquals(4, actualMethods.size());assertTrue(actualMethods.containsAll(Arrays.asList("getName","setName", "getSound")));}
Four 、 Application in interface automation platform
The return path of interface automation framework is platformization 、 Page operability , Not used by a few test students who understand the code . therefore , The front end needs a unified interface to invoke services , Forward the service to be called to the back end , Actually trigger the service initiated by the user . You can refer to the following flow chart .

For example, meituan interface automation test platform Lego, The user will service name 、 test method、request And so on , After initiation, the service initiation interface of the backend will be unified .

Another example is Taobao open platform , It is also implemented in the same way .
https://open.taobao.com/new/apitesttool?spm=a219a.15212433.0.0.1c41669aDvRvXZ&apiName=taobao.appstore.subscribe.get

therefore , Implementation of interface test platform , The reflection mechanism is very important .( Of course, some automated test platforms may not be Java Language development , But there are also reflections )
Let me demonstrate with a simple example , The project structure is as follows :

1. Develop two service(API)
public class CreateService {public boolean create(String name){if (null !=name){System.out.println("-----create success----");return true;}System.out.println("-----create failure----");return false;}}public class QueryService {public boolean query(String name){if (null !=name){System.out.println("-----query success----");return true;}System.out.println("-----query failure----");return false;}}
Use reflection mechanism to realize unified interface to call out services , The input parameter is the class name 、 The method of being transferred 、 Methodical request
public class Invoke {public void invokeProxy(String serviceName, String methodName, String request) {try {Class<?> serviceClass = Class.forName(serviceName);Object service = serviceClass.getDeclaredConstructor().newInstance();Method method = serviceClass.getMethod(methodName, String.class);method.invoke(service, request);} catch (ClassNotFoundException e){e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();}}
test Invoke.invokeProxy Interface
@Testpublic void testInvokeProxy(){String serviceName = "cn.qa.reflect.demo.service.CreateService";String request = "testName";String methodname = "create";invokeProxy(serviceName, methodName, request);}
test result
-----create success----ok, This implements a simple unified interface to call out services .
Like it , Just click on it. Zanhe is looking at Let's go
- END -
Scan the code below to pay attention to Software quality assurance , Learn and grow with quality gentleman 、 Common progress , Being a professional is the most expensive Tester!
Previous recommendation
Talk to self-management at work
Experience sharing | Test Engineer transformation test development process
Chat UI Automated PageObject Design patterns
边栏推荐
- How to distinguish and define DQL, DML, DDL and DCL in SQL
- The introduction of flink-sql-mysql-cdc-2.2.1 has solved many dependency conflicts?
- ECS MySQL query is slow
- flink cep 跳过策略 AfterMatchSkipStrategy.skipPastLastEvent() 匹配过的不再匹配 碧坑指南
- 纵观jBPM从jBPM3到jBPM5以及Activiti
- Proxy mode (proxy)
- DolphinScheduler使用系统时间
- 为什么 Istio 要使用 SPIRE 做身份认证?
- 读取pdf图片并识别内容
- 如图 用sql行转列 图一原表,图二希望转换后
猜你喜欢

一文读懂 12种卷积方法(含1x1卷积、转置卷积和深度可分离卷积等)

An error is reported when uninstalling Oracle
![QT signal and slot communication mechanism (when multiple windows communicate back and forth [parent and child windows])](/img/17/57ffb7393b71eddc5ac92ae3944338.jpg)
QT signal and slot communication mechanism (when multiple windows communicate back and forth [parent and child windows])

使用 ABAP 操作 Excel 的几种方法

我大抵是卷上瘾了,横竖睡不着!竟让一个Bug,搞我两次!

用 Compose 实现个空调,为你的夏日带去清凉

sqlcmd 连接数据库报错

【OpenCV 例程200篇】213. 绘制圆形

再見!IE瀏覽器,這條路由Edge替IE繼續走下去

第六天 脚本与动画系统
随机推荐
JSON数据与List集合之间的正确转换
函数的分文件编写
Django数据库操作以及问题解决
Numpy array: join, flatten, and add dimensions
2020-10-27
Missed the golden three silver four, found a job for 4 months, interviewed 15 companies, and finally got 3 offers, ranking P7+
股票开户用中金证券经理发的开户二维码安全吗?知道的给说一下吧
Bridge mode
学习机器学习的最佳路径是什么
接口自动化框架脚手架-利用反射机制实现接口统一发起端
ffmpeg录音录像
【OpenCV 例程200篇】213. 绘制圆形
【云驻共创】DWS告警服务DMS详细介绍和集群连接方式简介
Chapter 5 trees and binary trees
用 Compose 实现个空调,为你的夏日带去清凉
==And eqauls()
增量快照 必须要求mysql表有主键的吗?
mysql打不开,闪退
Starting from full power to accelerate brand renewal, Chang'an electric and electrification products sound the "assembly number"
2022-06-27:给出一个长度为n的01串,现在请你找到两个区间, 使得这两个区间中,1的个数相等,0的个数也相等, 这两个区间可以相交,但是不可以完全重叠