Тот же проект, та же ветка, две машины: модульные тесты, дающие противоречивые результаты - PullRequest
0 голосов
/ 25 января 2020

Я действительно не уверен, какой код вставить сюда. Я включил ссылку на мой GitHub ниже, на указанный файл c с ошибкой.

Так что внезапно начался сбой модульного теста, который ранее работал нормально. Нет никакого смысла, провал. Я использую служебную программу Spring Mock MVC для имитации вызовов веб-API, и мои тесты с этим инструментом в основном вращаются вокруг определенных c веб-логик c, таких как мои правила безопасности. Правила безопасности очень важны для меня в этих тестах, у меня есть модульные тесты для всех правил доступа ко всем моим API.

В любом случае, этот тест, который должен проверять успешно аутентифицированный запрос, теперь возвращая 401, что приводит к сбою теста. Глядя на код, я не могу найти ничего плохого в этом. Я передаю действительный токен API. Однако я не верю, что в этом виновата какая-либо из моих логин c.

Причина, по которой я это говорю, заключается в том, что я провел тест. Два компьютера, оба на разрабатываемой ветке моего проекта. Я удалил весь файл .m2 с обеих машин, выполнил чистую компиляцию и запустил тесты. На одной машине все тесты проходят. На другом компьютере этот тест не пройден.

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

Это подтверждается тем фактом, что, если я только запускаю этот тест файл (mvn clean test -Dtest = VideoFileControllerTest), он работает на обеих машинах.

Итак ... что бы это могло быть? Я в растерянности, потому что я чувствовал, что между тестами я все вычищал должным образом, обычно я достаточно хорош в этом. Будем благодарны за советы и отзывы.

https://github.com/craigmiller160/VideoManagerServer/blob/develop/src/test/kotlin/io/craigmiller160/videomanagerserver/controller/VideoFileControllerTest.kt

testAddVideoFile ()

Ответы [ 2 ]

2 голосов
/ 25 января 2020

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

Тесты начали проваливаться после того, как я рандомизировал порядок, изменив достоверность maven. конфигурации. Я добавил следующий фрагмент в раздел сборки вашего pom.xml, чтобы рандомизировать тесты:

<build>
...
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <runOrder>random</runOrder>
    </configuration>
</plugin>
...
</build>

Я десять раз выполнил команду mvn clean test, используя следующее (linux) bash скрипт (если вы используете windows, скрипт может работать с помощью powershell):

#!/bin/bash

for i in {1..10}
do
  mvn clean test
  if [[ "$?" -ne 0 ]] ; then # if the exit code from mvn clean install was different than 0
    echo "Error during test ${i}" >> results.txt
  else
    echo "Test ${i} went fine" >> results.txt
  fi
done

Без фрагмента плагина файл results.txt просто содержал десять строк Test x went fine, а после применения плагина около половины испытаний не удалось. К сожалению, все рандомизированные тесты успешно выполняются при использовании mvn clean test -Dtest=VideoFileControllerTest, поэтому я предполагаю, что заражение происходит где-то еще в вашем коде.

Надеюсь, вышесказанное поможет вам лучше понять неудачу теста. Я бы посоветовал найти виновного по @Ignore -полной половине активных тестовых классов и запустить тесты. Если все тесты пройдены успешно, повторите этот процесс на второй половине и продолжайте разрезать активные тесты пополам, пока не найдете причину сбоя. Обязательно включите в провал тест, хотя.

[править]

Вы можете добавить @DirtiesContext к соответствующим классам / методам тестирования к предотвратить повторное использование ApplicationContext между тестами.

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

Хорошо, спасибо за совет, я понял это.

Итак, основная цель моих тестов контроллера состояла в том, чтобы проверить мои логики API c, включая аутентификацию. Это означало, что была логика c, которая выполняла статические c вызовы метода для SecurityContextHolder. У меня был другой тестовый класс, который также тестировал логи c с участием SecurityContextHolder, и он делал это:

@Mock
    private lateinit var securityContext: SecurityContext

    @Before
    fun setup() {
        SecurityContextHolder.setContext(securityContext)
    }

Так что он устанавливал фиктивный объект Mockito в качестве контекста безопасности. После долгих исследований я обнаружил, что все мои логины аутентификации c работали нормально на тесте, который возвращал 401 на моем ноутбуке (но не на моем рабочем столе). Я также заметил, что тестовый файл с приведенным выше фрагментом кода выполнялся непосредственно перед тестированием моего контроллера на моем ноутбуке, но после него на моем рабочем столе.

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

Решением этой проблемы было добавление следующих логик c в файл теста сверху:

@After
    fun after() {
        SecurityContextHolder.clearContext()
    }

Это очистило макет и заставило все снова работать.

...