Как проверить общее выполнение нескольких тестов JUnit 4? - PullRequest
0 голосов
/ 07 января 2020

Желаемый: «Тест тестов»

Представьте себе, что есть некоторая дополнительная «проверка работоспособности», которая может быть выполнена после того, как тестовый класс завершит все свои тесты, которые будут указывать, было ли выполнение теста в целом выполнено успешно , Эта последняя проверка работоспособности может использовать некоторую обобщенную информацию о тестах. Просто в качестве грубого примера: подсчитывается количество вызовов к разделяемому методу, и если после завершения всех тестов это число не превышает некоторого минимального ожидаемого порога, становится ясно, что что-то не так, даже если все отдельные тесты пройдены.

То, что я описал, возможно, относится к «серой области» лучших практик, потому что, хотя оно нарушает doctrine модульных тестов atomi c, окончательная проверка работоспособности на самом деле не является тестирование тестируемого класса; скорее это проверка того, что выполнение теста в целом было успешным: так называемый «тест тестов». Это дополнительная логика c в отношении самих тестов.

Это решение кажется плохим

Один из способов выполнить sh этот «тест тестов» - поместить проверку работоспособности в состояние c @AfterClass метод. Если проверка не удалась, можно вызвать Assert.fail(), что на самом деле работает (удивительно, поскольку я предполагал, что ее можно вызывать только из методов, помеченных @Test, которые по своей природе должны быть методами экземпляра, а не stati c):

public class MyTest {

   [...]

    @AfterClass
    public static void testSufficientCount() {
        if (MyTest.counterVariable < MIN_COUNT) {
            Assert.fail("This fail call actually works. Wow.");
        }
    }

}

Существует множество причин, по которым это решение является клуджем:

  • Предположим, что всего N тестов (где "тест" - это метод экземпляра, аннотированный * * тысяча двадцать-одиной). Когда Assert.fail() является , а не , вызванным в @AfterClass, в IDE, как и ожидалось, сообщается общее количество тестов N. Однако, когда Assert.fail() вызывается в @AfterClass, IDE сообщает всего N + 1 тестов (дополнительным является метод stati c @AfterClass). Дополнительный метод stati c был , а не с аннотацией @Test, поэтому его не следует считать тестом. Кроме того, общее количество тестов не должно зависеть от того, пройдены некоторые тесты или нет.
  • Метод @AfterClass по определению является stati c. Таким образом, доступны только участники c. Это представляет проблему для моей конкретной ситуации c; Я оставлю это утверждение без подробностей, потому что объяснение выходит за рамки вопроса, но в целом было бы наиболее желательно, если бы использовались только члены экземпляра.
  • [Другие причины тоже ...]

Есть ли лучший путь?

Есть ли способ реализовать этот "тест испытаний", который считается хорошей и распространенной практикой? Поддерживает ли JUnit 4 добавление некоторого вида logi c, чтобы гарантировать, что группа модульных тестов внутри класса выполняется должным образом (в некотором роде, если они этого не сделали)? Есть ли название для этой вещи, которую я назвал «тест испытаний»?

1 Ответ

1 голос
/ 09 января 2020

О переменном количестве тестов

Я не думаю, что есть правильное решение ...

О стати c поля

Я пытался следовать вашей пример и, если я хорошо понял, с комбинацией Verifier , TestRule и ClassRule можно использовать только поля экземпляра тестового класса

Вот мой код, из которого можно взять реплику:

public class ATest {

    public int countVariable = 0;

    private static class MyVerifier extends Verifier {

        public int count = 0;

        @Override
        protected void verify() throws Throwable {
            assertTrue(count < 1); // cause new failed test
        //  assertTrue(count >= 1);  // it's all ok
        }

    }

    @ClassRule
    public static MyVerifier v = new MyVerifier();

    private class MyRule implements TestRule {

        ATest a;
        MyVerifier v;

        public MyRule(ATest a, MyVerifier v) {
            this.a = a;
            this.v = v;
        }

        @Override
        public Statement apply(Statement base, Description description) {
            try {

                base.evaluate();
                this.v.count = a.countVariable;
            } catch (Throwable ex) {
                Logger.getLogger(ATest.class.getName()).log(Level.SEVERE, null, ex);
            }
            return base;
        }

    }

    @Rule
    public MyRule rule = new MyRule(this, v);

    @org.junit.Test
    public void testSomeMethod() {
        countVariable++; // modifies instance counter
        assertTrue(true);
    }

    @org.junit.Test
    public void testSomeMethod2() {
        countVariable++; // modifies instance counter
        assertTrue(true);
    }

}

Сказав, что

"тест тестов" не считается обычной и хорошей практикой, потому что, как вы знаете, он нарушает как минимум два из пяти принципов правила FIRST (см. код Клина от дяди Боба Мартина ): тесты должны быть

  • F: Fast
  • I: Независимый
  • R: Повторяемый
  • S: Самопроверка
  • T: Своевременно (связан с TDD практикой)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...