Java и JUnit, найдите недостающие декораторы @Test - PullRequest
2 голосов
/ 26 февраля 2020

Допустим, у нас есть проект, полный модульных тестов (тысячи), и все они должны выглядеть следующим образом

@Test
public void testExceptionInBla() {
   // some test
}

Но в одном случае кто-то забыл поместить декоратор @Test поверх теста.

Какой простой способ определить эти тесты, не просматривая весь код вручную?

Я хочу найти такой код, это тест без @Test:

public void testExceptionInBla() {
   // some test
}

Ответы [ 3 ]

3 голосов
/ 26 февраля 2020

Я был бы вами, я бы посмотрел на какое-то правило сонара, здесь я нашел что-то, что может соответствовать требованию: https://rules.sonarsource.com/java/RSPEC-2187

1 голос
/ 26 февраля 2020

Но в одном случае кто-то забыл поставить декоратор @Test поверх теста.

И

Я хочу найти такой код , это тест без @Test:

public void testExceptionInBla() { // some test }

Аннотирование метода с помощью @Test или указание префикса test в имени метода примерно одинаково в условия последствий, если разработчик забудет это сделать.
Если @Test сегодня так, то это не случайно.
Аннотация @Test дает два реальных преимущества для префикса test:

1) проверяется при тестировании компиляции. Например, @Tast вызовет ошибку компиляции, а tastWhen...() - нет.

2) @Test делает имя метода теста более понятным: оно позволяет сосредоточиться на сценарии с функциональным языком. should_throw_exception_if_blabla() звучит более значимым, чем test_should_throw_exception_if_blabla().

О вашей проблеме: как обеспечить эффективное выполнение тестов, я бы по-другому. Как правило, вы хотите, чтобы выполнение модульных тестов охватывало минимальный уровень исходного кода приложения (хотя вы можете go вниз на уровне пакета или класса, если это имеет смысл).
И это цель инструментов покрытия (например, Jacoco) ) чтобы сделать эту работу. Вы даже можете добавить правила, чтобы сделать сборку неудачной, если уровень охвата классов, принадлежащих к какому-либо пакету, не покрыт хотя бы на указанном минимальном уровне ( посмотрите на этот пост ).


Небольшое добавление:
Если вы действительно гарантируете, что методы тестирования правильно аннотированы, у вас есть способ:
1) вам нужно выбрать соглашение для методов тестирования: например, все экземпляры, а не частные методы в тестовом классе, являются тестовыми методами.
2) Создайте правило Sonar, которое извлекает все не частные методы экземпляра тестовых классов, и убедитесь, что все эти методы помечены @Test.
3). Добавьте это правило в ваши правила сонара.

0 голосов
/ 26 февраля 2020

Я тоже go за линтер здесь, но вы можете реализовать что-то в Java. Представьте, что вы хотите, чтобы модульный тест подтвердил, все ли потенциальные методы тестирования были выполнены. Вы можете создать модульный тест, используя Java Reflection API. Пример ниже:

Тестовый класс, для которого я хочу знать, пропустил ли я потенциальный метод теста:

public class TestClass {

  @Test
  public void testDontShowMe() {
    // my test with annotation
  }

  public void testShowMe() {
    // my test without annotation
  }

  public void dontShowMeCauseNoPrefix() {
    // my test without test prefix
  }

  private void someUtilityMethod() {
    // a test private utility method
  }
}

Тестовый класс, который собирается проверить, что потенциальный метод тестирования не был пропущено:

public class CheckNoForgottenTests {

  @Test
  public void testNoMissingTests() {
    List<Method> nonAnnotatedMethod = Arrays
        .asList(TestClass.class.getDeclaredMethods()).stream()
        .filter(m -> Modifier.isPublic(m.getModifiers())
                && !m.getName().startsWith("test") 
                && m.getDeclaredAnnotation(Test.class) == null)
        .collect(Collectors.toList());
    nonAnnotatedMethod.forEach(m -> System.out.println("TestClass potential missed test: " + m.getName()));
    assertEquals(0, nonAnnotatedMethod.size());
  }

}

Применяемый здесь фильтр проверяет:

  • Если метод опубликован c AND
  • Если имя метода начинается с "test" (вид соглашения) И
  • Если метод не имеет org.junit.Test аннотации

, вы можете адаптировать условия в зависимости от ваших потребностей

Это пример. Здесь многое можно улучшить. Этот пример проверяет только один данный тестовый класс, конечно, он может быть изменен для работы с заданным списком классов.

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

...