当程序具有全局变量时,如何运行N个测试用例?

时间:2019-07-15 09:08:35

标签: java loops testing global-variables

由于该程序具有一些全局变量,所以我认为它不是循环N次,而是从用户那里接受N,其中N是测试用例的数量。

我尝试在main中接受N,然后添加一个运行main主体N次的for循环,但这是行不通的,并且总是会出错。

代码如下:(要打印按字母顺序排列的下一个字符串的排列)

 import java.util.*; 
public class Permu 
{ 
    // Returns true if str[curr] does not matches with any of the  
    // characters after str[start]  
    static String x[];static int i=0;
    static String sort(String s)
    {
        char a[]=s.toCharArray();
        Arrays.sort(a);
        return String.valueOf(a);
    }

    static boolean shouldSwap(char str[], int start, int curr) { 
        for (int i = start; i < curr; i++) { 
            if (str[i] == str[curr]) { 
                return false; 
            } 
        } 
        return true; 
    }
    // Prints all distinct permutations in str[0..n-1]  
    static void findPermutations(char str[], int index, int n) { 

        if (index >= n) { 
            if(i<x.length)
            x[i++]=String.valueOf(str);
        } 

        for (int i = index; i < n; i++) { 

            // Proceed further for str[i] only if it  
            // doesn't match with any of the characters  
            // after str[index]  
            boolean check = shouldSwap(str, index, i); 
            if (check) { 
                swap(str, index, i); 
                findPermutations(str, index + 1, n); 
                swap(str, index, i); 
            } 
        } 
    } 

    static void swap(char[] str, int i, int j) { 
        char c = str[i]; 
        str[i] = str[j]; 
        str[j] = c; 
    } 

    // Driver code 
    public static void main(String[] args) { 
        Scanner sc=new Scanner(System.in);
        int t=sc.nextInt();
        sc.nextLine();
        for(int j=0;j<t;j++)
        {
        String s1=sc.nextLine();
        String s=sort(s1);
        char str[]=s.toCharArray();
        int n = str.length; int nf=1;
        for(int i=1;i<=n;i++)
        {
            nf=nf*i;
        }
        x=new String[nf];
        Arrays.fill(x," ");
        findPermutations(str,0,n);
        boolean flag=false;
        for(int i=0;i<x.length;i++)
        {
            if(x[i].equals(s1)&&(i+1)<x.length)
            {
                System.out.println(x[i+1]);
                flag=true;
            }            
        }
        if(flag==false)
        System.out.println("no answer");
        }
    } 
} 

如何解决此错误?我不想重新编写整个程序。

1 个答案:

答案 0 :(得分:0)

显然最好的方法是重构,但是,如果您愿意,可以这样做:

public class Main {

    static int globalVar = 0;

    static class MainLoader extends ClassLoader {
        @Override
        public Class<?> loadClass(String name) throws ClassNotFoundException {
            if (!name.equals(Main.class.getSimpleName()))
                return super.loadClass(name);
            try(InputStream in = ClassLoader.getSystemResourceAsStream(Main.class.getCanonicalName().replace('.', '/') + ".class")) {
                byte[] buff = in.readAllBytes();
                return defineClass(Main.class.getCanonicalName(), buff, 0, buff.length);
            } catch (IOException e) {
                throw new ClassNotFoundException();
            }
        }
    }

    public int methodToTest() {
        return globalVar += 1;
    }

    static Object wrapCreateInstance(Class<?> c) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        return c.getConstructor().newInstance();
    }

    static int wrapMethodToTestCall(Object main) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        return (int) main.getClass().getDeclaredMethod("methodToTest").invoke(main);
    }

    public static void main(String[] args) throws Exception {
        Class<?> loader1 = new MainLoader().loadClass("Main");
        Class<?> loader2 = new MainLoader().loadClass("Main");

        Object main1 = wrapCreateInstance(loader1);
        Object main2 = wrapCreateInstance(loader2);

        System.out.printf("loader1 call return %d%n", wrapMethodToTestCall(main1));
        System.out.printf("loader2 call return %d%n", wrapMethodToTestCall(main2));
        System.out.printf("loader1 call return %d%n", wrapMethodToTestCall(main1));
        System.out.printf("loader2 call return %d%n", wrapMethodToTestCall(main2));

        System.out.printf("loader1 call return %d%n", wrapMethodToTestCall(main1));
        System.out.printf("loader1 call return %d%n", wrapMethodToTestCall(main1));
        System.out.printf("loader1 call return %d%n", wrapMethodToTestCall(main1));
        System.out.printf("loader2 call return %d%n", wrapMethodToTestCall(main2));
    }

}

运行时,您会得到:

loader1 call return 1
loader2 call return 1
loader1 call return 2
loader2 call return 2
loader1 call return 3
loader1 call return 4
loader1 call return 5
loader2 call return 3

您可以加载任意数量的类,每个线程用于测试您的代码。

但是,如果您的静态代码将全局状态调用到其他类中怎么办?您应该删除if (!name.equals(Main.class.getSimpleName()))并重新加载所有类。最好的测试方法(不进行重构)可能是运行多台 JVM 机器,每个线程用于测试您的代码。

我建议您将代码重构为可测试的,否则,请为每个不同的测试运行多个 JVM