Fitnesse slim框架的DecisionTable类自动保存实例变量到fitnesse变量存储中

假如有2个Class,分别是A和B

public class A {
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}



public class B {
	private A a;
	private int c;

	public A getA() {
		return a;
	}

	public void setA(A a) {
		this.a = a;
	}

	public int getC() {
		return c;
	}

	public void setC(int c) {
		this.c = c;
	}		
}


如果要把A的实例通过B的setA方法传入到B实例中,通过java代码是很容易实现的,但是如果通过fitnesse脚本来完成这个步骤的话,可以通过在slim框架中加入一个AConvert类,或者在Class A中新增一个获取实例的方法,显然,这2种方式都有弊端

弊端1. 如果通过加入AConvert的类实现的话,日后再次碰到类似的问题,还需要增加各种不同的Convert类

弊端2. 类似弊端1,每个Class下都要加入一个获取实例的方法,就会变得太繁琐,而且,如果是jar包中的类,就不能在该类中新增获取实例的方法


较好的解决方法:修改fitnesse源码,影响的Class:fitnesse.slim.SlimExecutionContext

红色部分是实现功能需要加入的代码

public class SlimExecutionContext {
  private final FixtureInteraction interaction;
  private Map instances = new HashMap<>();
  private List libraries = new ArrayList<>();
  private VariableStore variables = new VariableStore();
  private List paths = new ArrayList<>();

  private List auto_increment_variables = new ArrayList<>();

  public SlimExecutionContext(FixtureInteraction interaction) {
    this.interaction = interaction;
  }

  public List getLibraries() {
    return Collections.unmodifiableList(libraries);
  }

  public void addLibrary(Library library) {
    libraries.add(library);
  }

  public void setVariable(String name, MethodExecutionResult value) {
    variables.setSymbol(name, value);
  }

  public MethodExecutionResult getVariable(String name) {
    return variables.getSymbol(name);
  }

  public void setVariable(String name, Object value) {
    setVariable(name, new MethodExecutionResult(value, Object.class));
  }

  public void create(String instanceName, String className, Object[] args)
    throws SlimError, IllegalArgumentException, IllegalAccessException, InvocationTargetException,
    InstantiationException {
    Object potentialActor = variables.getStored(className);
    if (potentialActor != null && !(potentialActor instanceof String)) {
      addToInstancesOrLibrary(instanceName, potentialActor);
    } else {
      String replacedClassName = variables
        .replaceSymbolsInString(className);
      Object instance = interaction.createInstance(paths,
        replacedClassName, replaceSymbols(args));
   

 
  
/**
 * 跑Suite时,会同时跑多个wiki页面的脚本,所以需要回收上个wiki脚本产生的变量存储
 */

       if(MyLog.isNewTest){
        for(String variable : auto_increment_variables){
          variables.getVariables().remove(variable);
        }
        auto_increment_variables.clear();
        MyLog.isNewTest = false;
      }

/**
 * 当使用Slim的DecsionTable生成的实例时,会存储类名(classname)为变量名,对象实例为变量值到slim的上下文中,前端调用变量值,只需要$变量名
 * example: 页面声明一个DesicionTable,|com.test.Hello|,那么系统会增加一个变量名Hello,变量值为Hello实例的存储,如果再次声明DesicionTable,|com.test.Hello|,那么系统会增加一个为变量名Hello1的变量存储,前端调用分别使用$Hello和$Hello1,互不影响
 */

      if (className != null && className.contains(".")) {
        String clzName = instance.getClass().getSimpleName();
        String clz = genClassName(clzName);
        MyLog.debug(String.format("set variable in SlimExecutionContext, variable name: [[%s]], class name: [[%s]]", clz, instance.getClass().getName()));
        auto_increment_variables.add(clz);
        setVariable(clz, instance);

      }


      addToInstancesOrLibrary(instanceName, instance);
    }
  }

  /**
   * 使DecisionTable产生的类实例的变量名不重复,保证一个类可以生成多个实例的变量
   *
   * @param clzName
   * @return
   */
  private String genClassName(String clzName) {
    String tmp = clzName;
    int i = 1;
    while (variables.getVariables().containsKey(tmp)) {
      tmp = clzName + i;
      i++;
    }
    return tmp;
  }


  public void addPath(String path) {
    if (!paths.contains(path)) {
      paths.add(0, path);
    }
  }

  public Object getInstance(String instanceName) {
    Object instance = instances.get(instanceName);
    if (instance != null) {
      return instance;
    }

    for (Library library : libraries) {
      if (library.instanceName.equals(instanceName)) {
        return library.instance;
      }
    }
    throw new SlimError(String.format("message:<<%s %s>>",
      SlimServer.NO_INSTANCE, instanceName));
  }

  private void addToInstancesOrLibrary(String instanceName, Object instance) {
    if (isLibrary(instanceName)) {
      libraries.add(new Library(instanceName, instance));
    } else {
      setInstance(instanceName, instance);
    }
  }

  public void setInstance(String instanceName, Object instance) {
    instances.put(instanceName, instance);
  }

  private boolean isLibrary(String instanceName) {
    return instanceName.startsWith("library");
  }

  public Object[] replaceSymbols(Object[] args) {
    return variables.replaceSymbols(args);
  }

  public FixtureInteraction getInteraction() {
    return interaction;
  }
}


wiki脚本

TdParamData、TdParamData1、TdParamData2是DecisionTable中com.qf.pboc.dao.entity.td.TdParamData类的3个实例,因为申明了3次


!define name1 {1-1}
!define name2 {1-2}
!define name3 {1-3}


|!-com.qf.pboc.dao.entity.td.TdParamData-!|
|name               |mobile               |
|${name1}           |13312312312          |


|!-com.qf.pboc.dao.entity.td.TdParamData-!|
|name               |mobile               |
|${name2}           |14312312312          |


|!-com.qf.pboc.dao.entity.td.TdParamData-!|
|name               |mobile               |
|${name3}           |15312312312          |


|script|common util                  |
|show  |getValue;|$TdParamData|name  |
|show  |getValue;|$TdParamData|mobile|


|script|common util                   |
|show  |getValue;|$TdParamData1|name  |
|show  |getValue;|$TdParamData1|mobile|


|script|common util                   |
|show  |getValue;|$TdParamData2|name  |
|show  |getValue;|$TdParamData2|mobile|




执行结果

Fitnesse slim框架的DecisionTable类自动保存实例变量到fitnesse变量存储中_第1张图片


你可能感兴趣的:(自动化测试,fitnesse)