我正在实现一些基本的排序算法(出于学习的目的),并想为它们编写单元测试。所有排序程序都有以下通用 api
...
public static void sort(Comparable[] a);
...
public static boolean isSorted(Comparable[] a);
...
public static boolean isSorted(Comparable[] a),int from ,int to;
...
因此,我编写了以下测试来测试 SelectionSort 中的 isSorted() 方法
public class SelectionSortTests {
String[] a ;
@After
public void tearDown() throws Exception {
a = null;
}
@Test
public void arraySortedSingleElement(){
a = new String[]{"A"};
Assert.assertTrue(SelectionSort.isSorted(a));
}
@Test
public void arraySortedDistinctElements(){
a = new String[]{"A","B","C","D"};
Assert.assertTrue(SelectionSort.isSorted(a));
}
@Test
public void arrayNotSorted(){
a = new String[]{"A","B","C","B"};
Assert.assertFalse(SelectionSort.isSorted(a));
}
...
}
现在我觉得如果我要为说 InsertionSort、ShellSort 等编写测试,它们看起来会一样..只有被测类的名称会改变..
那么,我应该如何组织测试呢?套件是答案还是我可以使用反射做得更好 - 可以编写一个驱动程序,我可以向其中添加要测试的类的名称列表,并且驱动程序调用通过将类名传递给它来运行公共单元测试。 .
我意识到这是一种常见的情况..想知道如何在没有唾沫或玻璃胶带的情况下处理这种情况
更新:感谢@BevinQ 和@Matthew Farwell,我尝试使用参数化单元测试来解决这个问题。使用反射来调用静态方法..似乎工作:)虽然我认为它仍然可以重构以避免重复代码
@RunWith(Parameterized.class)
public class ParameterizedSortTests {
private Class classToTest;
private Method methodToTest;
public ParameterizedSortTests(String packageName,String classToTest) {
super();
try {
this.classToTest = Class.forName(packageName+"."+classToTest);
} catch (ClassNotFoundException e) {
System.out.println("failed to get class!!");
e.printStackTrace();
}
}
//method return collection of class names to be tested
@Parameterized.Parameters
public static List<Object[]> classesToTest(){
return Arrays.asList(new Object[][]{
{"elemsorts","SelectionSort"} ,
{"elemsorts","InsertionSort"}
});
}
public void setMethod(String method,Class...args){
try {
this.methodToTest = this.classToTest.getMethod(method, args);
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
@Test
public void arrayIsSorted(){
setMethod("isSorted",Comparable[].class);
String[] a = new String[]{"A","B","C","D"};
Boolean arraySorted = null;
try {
arraySorted = (Boolean)this.methodToTest.invoke(null, new Object[]{a});
System.out.println(this.methodToTest+"returned :"+arraySorted);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
Assert.assertTrue(arraySorted);
}
@Test
public void arrayIsNotSorted(){
setMethod("isSorted",Comparable[].class);
String[] a = new String[]{"A","B","C","B"};
Boolean arraySorted = null;
try {
arraySorted = (Boolean)this.methodToTest.invoke(null, new Object[]{a});
System.out.println(this.methodToTest+"returned :"+arraySorted);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//System.out.println("arraySorted="+arraySorted);
Assert.assertFalse(arraySorted);
}
}