2014-11-20 2 views
2

Моя проблема, короче говоря, это то, что я хочу запустить несколько тестов JUnit из командной строки, и я хотел бы быть в состоянии видеть:Получение списка тестов из командной JUnit линии

  • список всех тесты (независимо от того, побежали они или нет).
  • Список всех пройденных тестов.
  • Список всех тестов, которые не удалось

Поводом для первой пули, потому что я считаю, если один тест вызывает System.exit, другие не будут работать, я все еще хочу знать об этих тестах , даже если они не запускались.

Допустим, у меня есть тестовый класс:

import junit.framework.TestCase; 
    public class ALoadOfTests extends TestCase { 

    public void testFoo() { 
     int a = 5; 
     int b = 10; 
     int result = a + b; 
     assertEquals(15, result); 
    } 

    public void testBar() { 
     fail(); 
    } 

    public void testBaz() { 
     fail(); 
    }  
} 

Если я бегу это с помощью команды:

javac -cp ".;C:\Users\username\Desktop\Test\junit-4.11.jar;C:\Users\username\Desktop\Test\hamcrest-core-1.3.jar" ALoadOfTests.java 
java -cp ".;C:\Users\username\Desktop\Test\junit-4.11.jar;C:\Users\username\Desktop\Test\hamcrest-core-1.3.jar" junit.textui.TestRunner ALoadOfTsts 

Выход является:

.F.F. 
Time: 0.002 
There were 2 failures: 
1) testBar(ALoadOfTests)junit.framework.AssertionFailedError 
     at ALoadOfTests.testBar(ALoadOfTests.java:12) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
2) testBaz(ALoadOfTests)junit.framework.AssertionFailedError 
     at ALoadOfTests.testBaz(ALoadOfTests.java:16) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 

FAILURES!!! 
Tests run: 3, Failures: 2, Errors: 0 

Проблема здесь состоит в том, что на выходе не указывается имя testFoo, которое существует и передается. Кроме того, если я меняю один из них использовать System.exit, то мы не получаем много сообщений вообще, мы просто получаем:

.F.F. 

В идеале, чтобы быть в состоянии получить всю информацию, мне нужно, если сначала я смогу распечатать список тестовых имен, прежде чем запускать какие-либо тесты (и любой шанс на System.exit), я могу увидеть, что прошло, а что не удалось (или не запускалось).

Если бы я мог получить вывод, что только выглядит подобно:

Tests: 
testFoo 
TestBar 
TestBaz 
Results: 
TestFoo(passed) 
TestBar(failed:reason) 

Тогда я мог бы смело предположить:

TestFoo passed 
TestBar failed 
TestBaz never ran, probably because some test called system.exit. 

Возможно ли это с помощью пользовательского бегуна? Если да, то любые подсказки о том, с чего начать, будем очень благодарны.

К сожалению, у меня нет контроля над кодом, следует предположить, что он может содержать System.exit, возможно, в каждом методе. У меня также мало контроля над тестами, поэтому распечатка имен тестов в методе настройки не идеальна.

Спасибо,

ответ

3

Изменение OUTPUT JUnit

Как описано в этом blog вы можете написать свой собственный тест слушателя и распечатать свои собственные сообщения, когда тесты проходят или не.

public class ExecutionListener extends RunListener 
{ 
... //feel free to override other methods too 

/** 
* Called when an atomic test has finished, whether the test succeeds or fails. 
* */ 
public void testFinished(Description description) throws java.lang.Exception 
{ 
    System.out.println("Finished execution of test case : "+ description.getMethodName()); 
} 

/** 
* Called when an atomic test fails. 
* */ 
public void testFailure(Failure failure) throws java.lang.Exception 
{ 
    System.out.println("Execution of test case failed : "+ failure.getMessage()); 
} 

/** 
* Called when a test will not be run, generally because a test method is annotated with Ignore. 
* */ 
public void testIgnored(Description description) throws java.lang.Exception 
{ 
    System.out.println("Execution of test case ignored : "+ description.getMethodName()); 
} 

}

Затем написать свой собственный класс с основным для запуска JUnit (вместо запуска junit.jar)

public class ExecuteWithRunListener 
{ 
    public static void main(String[] args) 
    { 
     JUnitCore runner = new JUnitCore(); 
     //Adding listener here 
     runner.addListener(new ExecutionListener()); 
     runner.run(TestFeatureOne.class, TestFeatureTwo.class); 
    } 
} 

Как предотвратить вызовы из системы.выход из фактического выхода

Ваши тесты могут использовать свои собственные SecurityManager, чтобы предотвратить звонки System.exit от каких-либо действий. Приведенный ниже код будет делать какие-либо вызовы на System.exit() бросить специальное исключение, которое мы можем поймать в наших тестах, чтобы убедиться, что мы назвали выход и также захватить то, что код выхода был:

public static final SecurityManager NON_EXITABLE_MANAGER = new SecurityManager(){ 

    @Override 
    public void checkPermission(Permission perm) { 
     //allow everything 
    } 
    /** 
    * Throws a {@link TriedToExitException} instead of exiting. 
    * <p/> 
    * {@inheritDoc} 
    */ 
    @Override 
    public void checkExit(int status) { 
     throw new TriedToExitException(status); 
    } 

}; 

public static final class TriedToExitException extends SecurityException{ 
    private static final long serialVersionUID = 1L; 
    private final int exitCode; 

    public TriedToExitException(int exitCode){ 
     this.exitCode=exitCode; 
    } 

    @Override 
    public String getMessage() { 
     return String.format("tried to System.exit(%d)",exitCode); 
    } 

    public int getExitCode() { 
     return exitCode; 
    } 

} 

Тогда в вашем модульные тесты вы заменяете SecurityManager нашей версией, которая останавливает вызовы для выхода (и сохраняет старый SecurityManager, чтобы мы могли его восстановить после теста)

private SecurityManager previousManager=null; 


@Before 
protected void replaceManager() throws Throwable { 
    previousManager = System.getSecurityManager(); 
    System.setSecurityManager(NON_EXITABLE_MANAGER); 
} 

@After 
protected void restoreManager() { 
    System.setSecurityManager(previousManager); 
} 

@Test 
    public void testCallToExit() throws IOException{ 

     try{ 
      //something that calls System.exit 
      fail("should call exit"); 
     }catch(TriedToExitException e){ 
      //make sure we get correct exit code 
      assertEquals(-1, e.getExitCode()); 

     } 
    } 
Смежные вопросы