|
缘由有时我们需要测试某个方法,需要频繁的修改这个方法,但又不想重新去run整个程序,怎么做呢?
一个正常的appium测试用例- package com.dynamicclassloader;
- import java.io.File;
- import java.net.URL;
- import org.junit.After;
- import org.junit.Before;
- import org.junit.Test;
- import org.openqa.selenium.WebElement;
- import org.openqa.selenium.remote.DesiredCapabilities;
- import com.dynamicclassloader.DynamicEngine;
- import com.my.Utils;
- import io.appium.java_client.android.AndroidDriver;
- import io.appium.java_client.remote.AndroidMobileCapabilityType;
- import io.appium.java_client.remote.AutomationName;
- import io.appium.java_client.remote.MobileCapabilityType;
- public class CommonTest {
- private AndroidDriver<?> driver;
- public DesiredCapabilities capabilities = new DesiredCapabilities();
- public String location = "C:/Users/test.apk";
- public String pkgName = "";
- public String activityName = "";
- public String getSN() {
- String sn = Utils.runCMD(new String[]{"adb", "devices"}).split("\n")[1].split("\t")[0];
- return sn;
- }
- public void updatePkgActivity() {
- String pkgInfo = Utils.runCMD(new String[]{"aapt", "dump", "badging", location});
- String pkgStart = "package: name='";
- pkgName = pkgInfo.substring(pkgInfo.indexOf(pkgStart) + pkgStart.length(), pkgInfo.indexOf("' version"));
- String activityStart = "launchable-activity: name='";
- activityName = pkgInfo.substring(pkgInfo.indexOf(activityStart) + activityStart.length(), pkgInfo.indexOf("' label=''"));
- }
- public void updateCapabilites() {
- File app = new File(location);
- capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, getSN());
- updatePkgActivity();
- capabilities.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, pkgName);
- capabilities.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, activityName);
- capabilities.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 300);
- if (Utils.runCMD(new String[]{"adb", "shell", "pm", "path", pkgName}).equals("")) {
- capabilities.setCapability(MobileCapabilityType.APP, app.getAbsolutePath());
- }
- capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.ANDROID_UIAUTOMATOR2);
- }
- @Before
- public void setUp() throws Exception {
- updateCapabilites();
- driver = new AndroidDriver<WebElement>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
- }
- @Test
- public void stepTest() {
- TouchAction ta = new TouchAction(driver);
- ta.tap(306, 1852).perform();
- }
- @After
- public void tearDown() throws Exception {
- driver.quit();
- }
- }
- 当我修改stepTest后,重新运行时,就会发现appium日志又刷刷地从头开始创建driver了,虽然driver已经创建完成了
- 动态加载方法
- Utils类中访问获取程序内部资源的方法
- public String getStep(String fileName) {
- String step = "";
- InputStream is = getClass().getResourceAsStream(fileName);
- BufferedReader br = new BufferedReader(new InputStreamReader(is));
- String s = "";
- try {
- while((s = br.readLine()) != null) {
- step += s;
- // System.out.println(s);
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- return step;
- }
- 修改后的stepTest方法
- @Test
- public void stepTest() {
- while (true) {
- String source;
- DynamicEngine de = DynamicEngine.getInstance();
- source = new Utils().getStep("AndroidStep.txt");
- try {
- System.out.println("test");
- Class clazz = de.javaCodeToObject("com.carl.AndroidStep", source);
- clazz.getMethod("runStep", AndroidDriver.class).invoke(clazz, driver);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- package com.dynamicclassloader;
- import java.io.File;
- import java.lang.reflect.Method;
- import java.net.URL;
- import java.net.URLClassLoader;
- import java.util.ArrayList;
- import java.util.List;
- import javax.tools.*;
- /**
- * 在Java中最好的方法是使用StandardJavaFileManager类。
- * 这个类可以很好地控制输入、输出,并且可以通过DiagnosticListener得到诊断信息,
- * 而DiagnosticCollector类就是listener的实现。
- * 使用StandardJavaFileManager需要两步。
- * 首先建立一个DiagnosticCollector实例以及通过JavaCompiler的getStandardFileManager()方法得到一个StandardFileManager对象。
- * 最后通过CompilationTask中的call方法编译源程序。
- */
- public class DynamicEngine {
- //单例
- private static DynamicEngine ourInstance = new DynamicEngine();
- public static DynamicEngine getInstance() {
- return ourInstance;
- }
- private URLClassLoader parentClassLoader;
- private String classpath;
- private DynamicEngine() {
- //获取类加载器
- this.parentClassLoader = (URLClassLoader) this.getClass().getClassLoader();
- //创建classpath
- this.buildClassPath();
- }
- /**
- * @MethodName : 创建classpath
- */
- private void buildClassPath() {
- this.classpath = null;
- StringBuilder sb = new StringBuilder();
- for (URL url : this.parentClassLoader.getURLs()) {
- String p = url.getFile();
- sb.append(p).append(File.pathSeparator);
- }
- this.classpath = sb.toString();
- //System.out.println("classpath:" + this.classpath);
- }
- /**
- * @MethodName : 编译java代码到Object
- * @Description : TODO
- * @param fullClassName 类名
- * @param javaCode 类代码
- * @return Object
- * @throws Exception
- */
- public Class javaCodeToObject(String fullClassName, String javaCode) throws Exception {
- long start = System.currentTimeMillis(); //记录开始编译时间
- // Object instance = null;
- //获取系统编译器
- JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
- // 建立DiagnosticCollector对象
- DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
- // 建立用于保存被编译文件名的对象
- // 每个文件被保存在一个从JavaFileObject继承的类中
- ClassFileManager fileManager = new ClassFileManager(compiler.getStandardFileManager(diagnostics, null, null));
- List<JavaFileObject> jfiles = new ArrayList<JavaFileObject>();
- jfiles.add(new StringSourceJavaObject(fullClassName, javaCode));
- //使用编译选项可以改变默认编译行为。编译选项是一个元素为String类型的Iterable集合
- List<String> options = new ArrayList<String>();
- options.add("-encoding");
- options.add("UTF-8");
- options.add("-classpath");
- options.add(this.classpath);
- JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics, options, null, jfiles);
- // 编译源程序
- boolean success = task.call();
- Class clazz = null;
- if (success) {
- //如果编译成功,用类加载器加载该类
- JavaClassObject jco = fileManager.getJavaClassObject();
- DynamicClassLoader dynamicClassLoader = new DynamicClassLoader(this.parentClassLoader);
- //String source = "package com.carl.test;public class Sourceee { public static void main(String[] args) {System.out.println(\"Hello World!\");} }";
- clazz = dynamicClassLoader.loadClass(fullClassName, jco);
- // instance = clazz.newInstance();
- for (Method m: clazz.getDeclaredMethods()) {
- System.out.println("method name: " + m.getName());
- // Class<?> classType = Class.forName("java.lang.String");
- // m.invoke(clazz, Array.newInstance(classType, 0));
- }
- } else {
- //如果想得到具体的编译错误,可以对Diagnostics进行扫描
- String error = "";
- for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
- error += compilePrint(diagnostic);
- }
- }
- long end = System.currentTimeMillis();
- return clazz;
- // System.out.println("javaCodeToObject use:"+(end-start)+"ms");
- // return instance;
- }
复制代码
|
|