junit4 creating test suite with specific test methods

狂风中的少年 提交于 2020-01-04 02:15:12

问题


In junit4 I want to execute specific test methods from different classes i.e want create a test suite with specific test methods from different classes.

Lets say I have 2 classes:

public class Test_Login {
    @Test
    public void test_Login_001(){
        System.out.println("test_Login_001");
    }

    @Test
    public void test_Login_002(){
        System.out.println("test_Login_002");
    }

    @Test
    public void test_Login_003(){
        System.out.println("test_Login_003");
    }
}


public class Logout {   

    @Test
    public void test_Logout_001(){  
        System.out.println("test_Logout_001");  
    }

    @Test
    public void test_Logout_002(){
        System.out.println("test_Logout_002");
    }

    @Test
    public void test_Logout_003(){
        System.out.println("test_Logout_003");
    }
}

From the above classes I want to execute test methods test_Login_001 , test_Login_003 , test_Logout_002 only.

How this can be achieved in junit4 ?


回答1:


You need to create an org.junit.runner.Request and pass it to the JunitCore runner, or actually to any Runner.

JUnitCore junitRunner = new JUnitCore();
Request request = Request.method(Logout.class, "test_Logout_002");
Result result = junitRunner.run(request);

I actually created an Annotation and can search for methods with those annotations and dynamically create Request and run them

public class TestsSuite {

public static void main(String[] args) throws Exception {
    Class annotation = MyTestAnnotation.class;
    JUnitCore junitRunner = new JUnitCore();
    Class testClass = Test_Login.class;
    Method[] methods = testClass.getMethods();
    for (Method method : methods) {
        if (method.isAnnotationPresent(annotation)) {
            if (method.isAnnotationPresent(org.junit.Test.class)) {
                Request request = Request.method(testClass, method.getName());
                Result result = junitRunner.run(request);
                System.out.println(result.wasSuccessful());
            }
        }
    }
}

}




回答2:


Since JUnit 4.8 introduced Categories there exists a clean solution, create a TestSuite:

@RunWith(Categories.class)
@IncludeCategory(MustHaveTests.class)
@SuiteClasses( { Test_Login.class, Test_Logout.class }) 
public class MustHaveTestsTestSuite {
    public interface MustHaveTests { /* category marker */ }

}

And add the @Category(MustHaveTests.class) above every test you would like to run with the TestSuite, e.g.:

@Category(MustHaveTests.class)
@Test
public void test_Login_001(){
    System.out.println("test_Login_001");
}

When running the TestSuite only the MustHaveTests-"tagged" tests will be executed. More Details on @Category: https://github.com/junit-team/junit4/wiki/categories




回答3:


This might not be the slickest implementation, but I solved a similar problem by created a new @SuiteMethods annotation as follows:

SuiteMethods.java

@Retention(RUNTIME)
@Target(TYPE)
public @interface SuiteMethods {
    String[] value() default {""};
}

FilteredSuite.java

public class FilteredSuite extends Categories {

    private static String[] TEST_METHODS_TO_RUN = {""};  // default behavior is to run all methods 

    private static Class<?> extractMethodNamesFromAnnotation(Class<?> clazz) {
        SuiteMethods methodsAnnotation = clazz.getAnnotation(SuiteMethods.class);
        if (methodsAnnotation != null) {
            // if our MethodsAnnotation was specified, use it's value as our methods filter
            TEST_METHODS_TO_RUN = methodsAnnotation.value();
        }        
        return clazz;
    }

    public static Filter getCustomFilter() {
        Filter f = new Filter() {

            @Override
            public boolean shouldRun(Description desc) {
                String methodName = desc.getMethodName();
                for (String subString : TEST_METHODS_TO_RUN) {
                    if (methodName == null || methodName.contains(subString)) {
                        return true;
                    }
                }
                return false;
            }

            @Override
            public String describe() {
                return null;
            }
        };
        return f;
    }

    public FilteredSuite(Class<?> arg0, RunnerBuilder arg1) throws InitializationError {
        super(extractMethodNamesFromAnnotation(arg0), arg1);            
    }

    @Override
    public void filter(Filter arg0) throws NoTestsRemainException {
        // At test suite startup, JUnit framework calls this method to install CategoryFilter.
        // Throw away the given filter and install our own method name filter 
        super.filter(getCustomFilter());
    }
}

A Usage Example

@RunWith(FilteredSuite.class)
@SuiteClasses({
    GroupRestTest.class,
    ScenarioRestTest.class
})
@SuiteMethods({
    "testReadOnlyFlag",
    "testSheetWriteData",
    "testAddScenarioMeta"
})
public class SubsetTestSuite {
}


来源:https://stackoverflow.com/questions/15240475/junit4-creating-test-suite-with-specific-test-methods

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!