BATS — Как принудительно выполнить проверку на наличие программы на сбой?

#bats-core

#bats-ядро

Вопрос:

У меня есть функция, которая проверяет как наличие файла, так и его исполняемый файл.

 is_command() {
  [[ -x "$(command -v "$1" 2> /dev/null)" ]] amp;amp; return 0
  return 1
}
  

У меня есть скрипт, который требует dos2unix .

 is_command 'dos2unix' || { echo 'dos2unix is required'; exit 1}
  

Поскольку dos2unix установлен в /usr/bin , я не могу просто удалить установленный путь PATH . Я также не хочу (и в любом случае не могу) временно переименовывать фактическую программу dos2unix.

Я попытался установить запись в BASH_CMDS, и она работает из командной строки:

 $ hash -r ; BASH_CMDS['dos2unix']='/no/such/dir/dos2unix' ; [[ -x "$(command -v dos2unix 2> /dev/null)" ]] ; echo $?
1
  

Но этот тест не работает. assert_output не соответствует (это сообщение об использовании позже в программе).

  @test 'dos2unix does not exist' {
   hash -r
   BASH_CMDS['dos2unix']='/no/such/dir/dos2unix'
   note "dos2unix: $(command -v dos2unix)"
   run ds
   assert_failure
   assert_output 'dos2unix is required'
 }
  

Как я могу заставить это работать? и почему это не работает?

Редактировать: сделайте assert_output соответствующим сгенерированной ошибке.

Комментарии:

1. Мне нужно было бы изучить это более подробно, но я думаю, что это связано с областью действия BASH_CMDS. Мое первое предположение заключается в том, что если бы вы установили BASH_CMDS['dos2unix']='/no/such/dir/dos2unix' в том же файле, где is_command находится, тест пройдет. Я должен был бы подумать об этом на мгновение, чтобы понять, как сделать это правильно, подумал.

2. Я немного подумал и добавил ответ. Не забудьте проголосовать и принять, если мое решение работает для вас 👍

Ответ №1:

Допустим, ваш тестируемый файл выглядит следующим образом:

 #!/usr/bin/env bash

ds() {

    is_command() {
      [[ -x "$("${command}" -v "$1" 2> /dev/null)" ]] amp;amp; return 0
      return 1
    }

    is_command 'dos2unix' || { echo 'dos2unix is required'; exit 1; }

    exit 0;
}
  

Вам придется каким-то образом «загрузить» этот код в свой тест, прежде чем его можно будет запустить.

Чаще load всего для этого используется функция BATS. Однако эта (или аналогичная настройка) нарушает область действия BASH_CMDS .

Это можно решить, выбрав файл из глобальной области видимости:

 #!/usr/bin/env bats

source "${BATS_TEST_DIRNAME}/ds.sh" # <-- This part is important

@test 'dos2unix does not exist' {
    hash -r

    BASH_CMDS['dos2unix']='/no/such/dir/dos2unix'

    run ds

   assert_failure
   assert_output 'dos2unix is required'
}
  

Когда я запускаю ваш исходный код, он действительно завершается с ошибкой. С source этим тест проходит для меня.

Если это не решит вашу проблему, могут (также) происходить другие вещи…

Комментарии:

1. Я рассмотрю это, спасибо. На данный момент я был перенаправлен, так что пройдет некоторое время, прежде чем я вернусь к этому.

2. Не беспокойтесь, дайте мне знать, когда до этого дойдет 😊