Test::Alien(3)
π Test::Alien β the manual page, but make it cute π
okay bestie, so this is Test::Alien from the perl user-contributed docs. it's version 2.88 and it's literally the testing toolbox for Alien modules. no cap. let's get into it π«Ά
β¨ NAME β¨
Test::Alien β testing tools for Alien modules. that's it, that's the whole name. iconic.
πΈ VERSION πΈ
version 2.88. she's current, she's thriving π
π SYNOPSIS π
okay so three whole vibes here. buckle up.
testing the commands that come with your Alien:
use Test2::V0;
use Test::Alien;
use Alien::patch;
alien_ok 'Alien::patch';
run_ok([ 'patch', '--version' ])
->success
# we only accept the version written
# by Larry ...
->out_like(qr{Larry Wall});
done_testing;
testing that your library works with XS:
use Test2::V0;
use Test::Alien;
use Alien::Editline;
alien_ok 'Alien::Editline';
my $xs = do { local $/; <DATA> };
xs_ok $xs, with_subtest {
my($module) = @_;
ok $module->version;
};
done_testing;
__DATA__
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include <editline/readline.h>
const char *
version(const char *class)
{
return rl_library_version;
}
MODULE = TA_MODULE PACKAGE = TA_MODULE
const char *version(class);
const char *class;
testing that your library works with FFI::Platypus:
use Test2::V0;
use Test::Alien;
use Alien::LibYAML;
alien_ok 'Alien::LibYAML';
ffi_ok { symbols => ['yaml_get_version'] }, with_subtest {
my($ffi) = @_;
my $get_version = $ffi->function(yaml_get_version => ['int*','int*','int*'] => 'void');
$get_version->call(\my $major, \my $minor, \my $patch);
like $major, qr{[0-9]+};
like $minor, qr{[0-9]+};
like $patch, qr{[0-9]+};
};
done_testing;
π¦ DESCRIPTION π¦
so this module hands you the tools to test Alien modules. it's got hooks so it plays nice with Alien::Base based modules, but you can also use the synthetic interface to test Alien modules that are not Alien::Base based. and the prerequisites? very modest. lowkey humble of it. π
before this module existed, the best way to test an Alien module was via Test::CChecker. the main downside of that one is that it's heavily influenced by β and uses β ExtUtils::CChecker, which is a tool for checking stuff about your compiler at install time. it was also written back before Alien::Base got as stable as it is today. in particular, Test::CChecker does its testing by creating an executable and running it. but unfortunately Perl uses extensions by creating dynamic libraries and linking them into the Perl process, which is different in subtle and error prone ways π. this module tries to test the libraries the way they'll actually be used, via either XS or FFI::Platypus. it also gives you a mechanism for testing binaries that the various Alien modules provide (like Alien::gmake and Alien::patch, for example).
and here's the slay part: Alien modules can actually be usable without a compiler, or without FFI::Platypus (say the library comes from the system and you're using FFI::Platypus, or you're building from source and you're using XS), so tests with missing prerequisites get automatically skipped. for example, xs_ok will automatically skip itself if a compiler isn't found, and ffi_ok will automatically skip itself if FFI::Platypus isn't installed. considerate queen behavior fr fr π
π FUNCTIONS π
π alien_ok
alien_ok $alien, $message;
alien_ok $alien;
loads the given Alien instance or class. checks that the instance or class conforms to the same interface as Alien::Base. it'll be used by subsequent tests. the $alien module only needs to provide these methods to conform to the Alien::Base interface:
cflagsβ a string containing the compiler flags.libsβ a string containing the linker and library flags.dynamic_libsβ a list of dynamic libraries. returns an empty list if the Alien module doesn't provide this.bin_dirβ the directory containing tool binaries. returns an empty list if the Alien module doesn't provide this.
if your Alien module doesn't conform to this interface, then you can create a synthetic Alien module using the synthetic function. problem solved bestie π
π§ synthetic
my $alien = synthetic \%config;
creates a synthetic Alien module which you can pass into alien_ok. \%config can contain these keys (and all of them are optional, so no pressure):
cflagsβ a string containing the compiler flags.cflags_staticβ a string containing the static compiler flags (optional).libsβ a string containing the linker and library flags.libs_staticβ a string containing the static linker flags (optional).dynamic_libsβ a list reference containing the dynamic libraries.bin_dirβ tool binary directory.runtime_propβ runtime properties.
see Test::Alien::Synthetic for more deets β¨
πΈ run_ok
my $run = run_ok $command;
my $run = run_ok $command, $message;
runs the given command, falling back on any Alien::Base#bin_dir methods provided by the Alien modules you specified with alien_ok.
$command can be either a string or an array reference.
okay so it only fails if the command cannot be found, or if it's killed by a signal! that's the whole list. that's it.
returns a Test::Alien::Run object, which you can use to test the exit status, output and standard error.
and it always returns an instance of Test::Alien::Run, even if the command couldn't be found. consistent queen π
π xs_ok
xs_ok $xs;
xs_ok $xs, $message;
compiles, links the given XS code, and attaches it to Perl. the whole glow-up β¨
if you use the special module name TA_MODULE in your XS code, it'll be replaced by an automatically generated package name. this is handy if you wanna pass the same XS code to multiple calls to xs_ok without the later calls replacing the earlier ones. iykyk.
$xs can be either a string containing the XS code, or a hash reference with these keys:
xsβ the XS code. this is the only required element.pxsβ extra ExtUtils::ParseXS arguments passed in as a hash reference.cbuilder_checkβ the compile check that should be done prior to attempting to build. should be one ofhave_compilerorhave_cplusplus. defaults tohave_compiler.cbuilder_configβ hash to override values normally provided byConfig.cbuilder_compileβ extra The ExtUtils::CBuilder arguments passed in as a hash reference.cbuilder_linkβ extra The ExtUtils::CBuilder arguments passed in as a hash reference.verboseβ spew copious debug information via test note.
you can use the with_subtest keyword to conditionally run a subtest if the xs_ok call succeeds. if xs_ok doesn't work, then the subtest gets automatically skipped. like so:
xs_ok $xs, with_subtest {
# skipped if $xs fails for some reason
my($module) = @_;
is $module->foo, 1;
};
the module name detected during the XS parsing phase gets passed into the subtest. super helpful when you're using a generated module name π«Ά
if you need to test XS C++ interfaces, see Test::Alien::CPP.
caveats:xs_okuses ExtUtils::ParseXS, which may callexitunder certain error conditions. while that's not really a good thing to happen in the middle of a test, it usually indicates a real failure condition, and it should return a failure condition, so the test should still fail overall. π
[version 2.53]
as of version 2.53, xs_ok will only remove temporary generated files if the test is successful by default. you can force either always or never removing the temporary generated files using the TEST_ALIEN_ALWAYS_KEEP environment variable (peep "ENVIRONMENT" below π).
π ffi_ok
ffi_ok;
ffi_ok \%opt;
ffi_ok \%opt, $message;
tests that FFI::Platypus works.
\%opt is a hash reference with these keys (all optional, live your life):
symbolsβ list references of symbols that must be found for the test to succeed.ignore_not_foundβ ignores symbols that aren't found. this affects functions accessed viaFFI::Platypus#attachandFFI::Platypus#functionmethods, and does not influence thesymbolskey above.langβ set the language. used primarily for language specific native types.apiβ set the API.api = 1requires FFI::Platypus0.99or later. this option was added with Test::Alien version1.90, so your use line should include this version as a safeguard to make sure it works:
use Test::Alien 1.90;
...
ffi_ok ...;
same as with xs_ok above, you can use the with_subtest keyword to specify a subtest to be run if ffi_ok succeeds (it'll skip otherwise). the FFI::Platypus instance gets passed into the subtest as the first argument. for example:
ffi_ok with_subtest {
my($ffi) = @_;
is $ffi->function(foo => [] => 'void')->call, 42;
};
π helper_ok
helper_ok $name;
helper_ok $name, $message;
tests that the given helper has been defined. short and sweet β¨
π plugin_ok
[version 2.52]
plugin_ok $plugin_name, $message;
plugin_ok [$plugin_name, @args], $message;
this applies an Alien::Build::Plugin to the interpolator used by helper_ok, interpolate_template_is and interpolate_run_ok, so you can test with any helpers that plugin provides. useful, for example, for getting %{configure} from Alien::Build::Plugin::Build::Autoconf. chef's kiss π
π§ interpolate_template_is
interpolate_template_is $template, $string;
interpolate_template_is $template, $string, $message;
interpolate_template_is $template, $regex;
interpolate_template_is $template, $regex, $message;
tests that the given template, when evaluated with the appropriate helpers, will match either the given string or regular expression. π
β interpolate_run_ok
[version 2.52]
my $run = interpolate_run_ok $command;
my $run = interpolate_run_ok $command, $message;
this is the same as run_ok, except it runs the command through the interpolator first. tiny lil upgrade, big lil difference π
π₯ ENVIRONMENT π₯
TEST_ALIEN_ALWAYS_KEEPβ if this is defined then it'll override the built in logic that decides if the temporary files generated byxs_okshould be kept when the test file terminates. if set to true, the generated files will always be kept. if set to false, then they'll always be removed.TEST_ALIEN_ALIENS_MISSINGβ by default, this module will warn you if some tools are used without first invokingalien_ok. this is usually a mistake, but if you really do wanna use one of these tools with no aliens loaded, you can set this environment variable to false. (living dangerously, we respect it π)
π SEE ALSO π
- Alien
- Alien::Base
- Alien::Build
- alienfile
- Test2
- Test::Alien::Run
- Test::Alien::CanCompile
- Test::Alien::CanPlatypus
- Test::Alien::Synthetic
- Test::Alien::CPP
more of this page coming in part 2, don't go anywhere bestie π«Άβ¨
π AUTHOR π
Okay so this whole thing was brought to you by:
- Author: Graham Ollis
<plicease@cpan.org>
And bestie, the contributor list is stacked. Like, genuinely iconic roster energy:
- Diab Jerius (DJERIUS)
- Roy Storey (KIWIROY)
- Ilya Pavlov
- David Mertens (run4flat)
- Mark Nunberg (mordy, mnunberg)
- Christian Walde (Mithaldu)
- Brian Wightman (MidLifeXis)
- Zaki Mughal (zmughal)
- mohawk (mohawk2, ETJ)
- Vikas N Kumar (vikasnkumar)
- Flavio Poletti (polettix)
- Salvador FandiΓ±o (salva)
- Gianni Ceccarelli (dakkar)
- Pavel Shaydo (zwon, trinitum)
- Kang-min Liu (εεΊ·ζ°, gugod)
- Nicholas Shipp (nshp)
- Juan JuliΓ‘n Merelo GuervΓ³s (JJ)
- Joel Berger (JBERGER)
- Petr PΓsaΕ (ppisar)
- Lance Wicks (LANCEW)
- Ahmad Fatoum (a3f, ATHREEF)
- JosΓ© JoaquΓn Atria (JJATRIA)
- Duke Leto (LETO)
- Shoichi Kaji (SKAJI)
- Shawn Laffan (SLAFFAN)
- Paul Evans (leonerd, PEVANS)
- HΓ₯kon HΓ¦gland (hakonhagland, HAKONH)
- nick nauwelaerts (INPHOBIA)
- Florian Weimer
- Marcel Telka (mtelka)
Every single one of them, no skips, we appreciate all of y'all fr fr π
π COPYRIGHT AND LICENSE π
This software is copyright (c) 2011-2022 by Graham Ollis.
It's free software β you can redistribute it and/or modify it under the exact same terms as the Perl 5 programming language system itself. So basically, same vibe as Perl 5, same rules, go wild (respectfully). π
And that's a wrap on Test::Alien(3), bestie!! π¦ This page ships as part of perl v5.42.3, dated 2026-09-21 β that's the version-and-date energy we're closing on. Go test your Alien stuff, slay, and remember: every option, every default, every single contributor name stayed exactly where it belongs. π
β¨
π¦ where this page comes from
- fedora 43: perl-Alien-Build 2.88-1.fc43 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- fedora 44: perl-Alien-Build 2.88-1.fc44 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms