Подтвердить что ты не робот

Как изолировать от установленных библиотек в hg-репо для тестирования?

Как я могу использовать локальные библиотеки репозитория hg для тестирования изоляции из уже установленных библиотек?

Установленный пакет обработки perl и локальный репозиторий hg имеют одинаковую структуру

    +-- lib
        |-- modA.pm
        |-- modB.pm
    +-- bin
        |-- example.pl
    +-- t
        |-- modA.t
        |-- modB.t

установлены библиотеки и добавлен путь к @PERL5

/nfs_share/perl/
env|grep -i perl
PERL5:/usr/local/perl:/nfs_share/perl

local hg repo at:

/data/user/hg/perl

modB.pm

#!/usr/bin/perl
use modA;
sub modB_compare{
    my (x,y) = @_;
    # .....
    return x-y;
}

бен/example.pl

use FindBin qw($Bin);
use lib "${Bin}/lib/";
use modA, modB;
# if this call is from local lib
my $result = modB_compare(x,y);
# if sub being called from production or local hg?
my $result2 = modA_method();
# from local hg repo or from production lib?!

Если бы я должен был модифицировать и протестировать локальное репозиторию hg, нет никаких гарантий, что я вызывал lib из локального репо, а не из производственной библиотеки.

Каковы потенциальные решения для изоляции библиотек для тестирования в локальном репозитории hg?

4b9b3361

Ответ 1

Короткий ответ: для тестов просто используйте prove -l.

Если бы я должен был модифицировать и протестировать локальное репозиторию hg, нет никаких гарантий, что я вызывал lib из локального репо, а не из производственной библиотеки.

На самом деле, существует для проблемы, которую вы определили.

Если вы знаете, что ./lib/modA.pm существует и ./lib/ в @INC, тогда будет загружен ./lib/modA.pm, и любая версия системы perl не будет *.

Ваш оператор use lib делает это для вас, как описано в perlvar @INC и require.

Однако для тестов это обычная практика не до use lib, но вместо используйте -I флаг в perl (perl -Ilib t/modA.t) или, лучше, prove, который также имеет флаг -l, поэтому вы можете просто выполнить prove -l и выполнить все тесты в t/ с помощью модулей в ./lib.

NB: вы также можете посмотреть ExtUtils::MakeMaker или Module::Build::Tiny, которые помогают с задачами распределения, и вы можете рассмотреть Dist:: Zilla или (для более быстрого запуска) Dist::Milla

Если вы просто хотите проверить, что происходит, вы можете проверить, какие файлы были загружены в выражениях use или require, посмотрев %INC.

Если вам абсолютно необходимо контролировать, какие модули доступны, например, потому что вы хотите протестировать другое поведение в зависимости от того, установлены ли сторонние модули (а не ваш собственный код), я предлагаю изучить perlbrew. Это поможет вам скомпилировать ваш собственный perl (почти любой неопределенно недавней версии), который не использует библиотеки из системы perl, но вместо этого имеет свои собственные библиотеки, используя local::lib; вы можете переключаться между несколькими установленными perls. Единственными исключениями являются библиотеки, которые упакованы вместе с perl; вы можете получить их список из Module::Corelist.

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


* ОК, строго, lib должен появляться в @INC перед системными perl lib-каталогами, потому что происходит то, что perl проходит через @INC по порядку и находит файлы, соответствующие имени пакета, которое вы попросили нагрузка; все методы, которые вы использовали, и что я говорю в этом ответе, будут уверены, что ваш каталог lib появится раньше в @INC, а затем ваш системный perl libs.

Ответ 2

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

В результате - для такого рода сценариев я использую Docker. С риском упрощения бит это способ упаковки вашего экземпляра приложения с его зависимостями в мини-виртуальную машину.

Вы создаете образ из файла докеров, который очень похож на файл make, за исключением того, что он "сводится" к изображению, которое вы можете запустить, включая приложение и все его зависимости.

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

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

Но в результате у вас очень чистая среда и почти никогда не приходится беспокоиться о вещах, о которых вы беспокоитесь.

Вы даже можете безопасно запускать свой dev/ref/prod на одном и том же физическом жесте и просто связывать/сопоставлять различные ресурсы (тома/порты и т.д.) для дифференциации.