Perl tests - common parent for tests











up vote
1
down vote

favorite
1












I have a set of tests, always named Module.t, each one starts like this:



use 5.026;
use strict;
use warnings;

use Test::Perl::Critic (-severity => 3);
use Module::Path 'module_path';
use Test::More tests => 8;
use Test::Log4perl;
Test::Log4perl->suppress_logging;

BEGIN { use_ok("My::Module") }
critic_ok(module_path("My::Module"));

... actual tests for this module ...


It's done this way because a bunch of modules are not coded very nicely and in effort to refactor stuff as we go, I'm trying to write tests for individual modules over time. Eg. I can't just enable Perl::Critic for all sources cause it will blow up in my face.



I would like to ideally make a "parent" test for all of these so that when me or a different developer wants to write a new test they will always have all the required stuff. Something like:



use 5.026;
use strict;
use warnings;

# 6 tests because 2 (use_ok and critic_ok) are already in the parent
use parent ParentTest("My::Module", tests => 6);

... actual tests for this module ...


Does perl have a way of doing that?



Disclaimer: I'm a perl noob, so maybe this has a better solution :-)










share|improve this question


























    up vote
    1
    down vote

    favorite
    1












    I have a set of tests, always named Module.t, each one starts like this:



    use 5.026;
    use strict;
    use warnings;

    use Test::Perl::Critic (-severity => 3);
    use Module::Path 'module_path';
    use Test::More tests => 8;
    use Test::Log4perl;
    Test::Log4perl->suppress_logging;

    BEGIN { use_ok("My::Module") }
    critic_ok(module_path("My::Module"));

    ... actual tests for this module ...


    It's done this way because a bunch of modules are not coded very nicely and in effort to refactor stuff as we go, I'm trying to write tests for individual modules over time. Eg. I can't just enable Perl::Critic for all sources cause it will blow up in my face.



    I would like to ideally make a "parent" test for all of these so that when me or a different developer wants to write a new test they will always have all the required stuff. Something like:



    use 5.026;
    use strict;
    use warnings;

    # 6 tests because 2 (use_ok and critic_ok) are already in the parent
    use parent ParentTest("My::Module", tests => 6);

    ... actual tests for this module ...


    Does perl have a way of doing that?



    Disclaimer: I'm a perl noob, so maybe this has a better solution :-)










    share|improve this question
























      up vote
      1
      down vote

      favorite
      1









      up vote
      1
      down vote

      favorite
      1






      1





      I have a set of tests, always named Module.t, each one starts like this:



      use 5.026;
      use strict;
      use warnings;

      use Test::Perl::Critic (-severity => 3);
      use Module::Path 'module_path';
      use Test::More tests => 8;
      use Test::Log4perl;
      Test::Log4perl->suppress_logging;

      BEGIN { use_ok("My::Module") }
      critic_ok(module_path("My::Module"));

      ... actual tests for this module ...


      It's done this way because a bunch of modules are not coded very nicely and in effort to refactor stuff as we go, I'm trying to write tests for individual modules over time. Eg. I can't just enable Perl::Critic for all sources cause it will blow up in my face.



      I would like to ideally make a "parent" test for all of these so that when me or a different developer wants to write a new test they will always have all the required stuff. Something like:



      use 5.026;
      use strict;
      use warnings;

      # 6 tests because 2 (use_ok and critic_ok) are already in the parent
      use parent ParentTest("My::Module", tests => 6);

      ... actual tests for this module ...


      Does perl have a way of doing that?



      Disclaimer: I'm a perl noob, so maybe this has a better solution :-)










      share|improve this question













      I have a set of tests, always named Module.t, each one starts like this:



      use 5.026;
      use strict;
      use warnings;

      use Test::Perl::Critic (-severity => 3);
      use Module::Path 'module_path';
      use Test::More tests => 8;
      use Test::Log4perl;
      Test::Log4perl->suppress_logging;

      BEGIN { use_ok("My::Module") }
      critic_ok(module_path("My::Module"));

      ... actual tests for this module ...


      It's done this way because a bunch of modules are not coded very nicely and in effort to refactor stuff as we go, I'm trying to write tests for individual modules over time. Eg. I can't just enable Perl::Critic for all sources cause it will blow up in my face.



      I would like to ideally make a "parent" test for all of these so that when me or a different developer wants to write a new test they will always have all the required stuff. Something like:



      use 5.026;
      use strict;
      use warnings;

      # 6 tests because 2 (use_ok and critic_ok) are already in the parent
      use parent ParentTest("My::Module", tests => 6);

      ... actual tests for this module ...


      Does perl have a way of doing that?



      Disclaimer: I'm a perl noob, so maybe this has a better solution :-)







      perl unit-testing testing






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 10 at 3:20









      lukash

      494314




      494314
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          4
          down vote



          accepted










          Sounds like you just want a helper module that loads some other modules and runs some initial tests for you.



          Something like:



          # ParentTest.pm
          package ParentTest;
          use strict;
          use warnings;

          use Test::Perl::Critic (-severity => 3);
          use Module::Path 'module_path';
          use Test::More;
          use Test::Log4perl;

          sub import {
          my (undef, $module, %args) = @_;

          $args{tests} += 2;

          plan %args;
          Test::Log4perl->suppress_logging;
          use_ok $module;
          critic_ok module_path $module;

          @_ = 'Test::More';
          goto +Test::More->can('import');
          }

          1


          Usage would be:



          use ParentTest "My::Module", tests => 6;


          This is all untested, but the idea is:




          • We want to run some code to set up the initial test plan and run some tests.

          • We also want to export everything that Test::More exports, so our caller doesn't have to use Test::More themselves.


          • use Some::Module @args is equivalent to BEGIN { require "Some/Module.pm"; Some::Module->import(@args); }, so we can just put our custom logic in the import method.

          • We start by ignoring the first argument (which is a class name because import is called as a class method) and assigning the remaining arguments to $module and %args.

          • We increment $args{tests} by 2 to account for the two extra tests we perform automatically (if tests wasn't passed in, it is implicitly created here).

          • We pass %args to plan from Test::More, which is nice for setting up a test plan outside of the initial use line.

          • We perform the initial tests.

          • We tail call Test::More::import, erasing our own stack frame. This makes it look like our caller did Test::More->import(), which exports all the Test::More utility functions to them.

          • The unary + in goto +Test::More->... has no real effect, but it helps distinguish between the goto LABEL and goto EXPRESSION syntactic forms. We want the latter interpretation.






          share|improve this answer























          • this is perfect, I submitted an edit to add &{} for the goto. I also added code to set/increate tests by 2 as use_ok and critic_ok are 2 tests already. I have not figured out how to make that nicer, can't seem to find a way to convert array to hash in-line without a variable. Feel free to prettify that part :-)) Thanks!
            – lukash
            Nov 10 at 5:04












          • @lukash I simplified the tests + 2 logic. Why add &{ }?
            – melpomene
            Nov 10 at 5:14










          • &{ } was added because without it I get Bareword found where operator expected at ... line .., near "goto Test::More" (Do you need to predeclare goto?)
            – lukash
            Nov 10 at 5:36










          • @melpomene, I agree with lukash. I tested your code with 5.10 to 5.28, and none worked. You need goto &{ Test::More->can('import') } or goto(Test::More->can('import')) for your code to compile.
            – ikegami
            Nov 10 at 5:55










          • @lukash Should be fixed now. Took me a while to get the prerequisites installed to actually test this code.
            – melpomene
            Nov 10 at 6:01











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














           

          draft saved


          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53235746%2fperl-tests-common-parent-for-tests%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          4
          down vote



          accepted










          Sounds like you just want a helper module that loads some other modules and runs some initial tests for you.



          Something like:



          # ParentTest.pm
          package ParentTest;
          use strict;
          use warnings;

          use Test::Perl::Critic (-severity => 3);
          use Module::Path 'module_path';
          use Test::More;
          use Test::Log4perl;

          sub import {
          my (undef, $module, %args) = @_;

          $args{tests} += 2;

          plan %args;
          Test::Log4perl->suppress_logging;
          use_ok $module;
          critic_ok module_path $module;

          @_ = 'Test::More';
          goto +Test::More->can('import');
          }

          1


          Usage would be:



          use ParentTest "My::Module", tests => 6;


          This is all untested, but the idea is:




          • We want to run some code to set up the initial test plan and run some tests.

          • We also want to export everything that Test::More exports, so our caller doesn't have to use Test::More themselves.


          • use Some::Module @args is equivalent to BEGIN { require "Some/Module.pm"; Some::Module->import(@args); }, so we can just put our custom logic in the import method.

          • We start by ignoring the first argument (which is a class name because import is called as a class method) and assigning the remaining arguments to $module and %args.

          • We increment $args{tests} by 2 to account for the two extra tests we perform automatically (if tests wasn't passed in, it is implicitly created here).

          • We pass %args to plan from Test::More, which is nice for setting up a test plan outside of the initial use line.

          • We perform the initial tests.

          • We tail call Test::More::import, erasing our own stack frame. This makes it look like our caller did Test::More->import(), which exports all the Test::More utility functions to them.

          • The unary + in goto +Test::More->... has no real effect, but it helps distinguish between the goto LABEL and goto EXPRESSION syntactic forms. We want the latter interpretation.






          share|improve this answer























          • this is perfect, I submitted an edit to add &{} for the goto. I also added code to set/increate tests by 2 as use_ok and critic_ok are 2 tests already. I have not figured out how to make that nicer, can't seem to find a way to convert array to hash in-line without a variable. Feel free to prettify that part :-)) Thanks!
            – lukash
            Nov 10 at 5:04












          • @lukash I simplified the tests + 2 logic. Why add &{ }?
            – melpomene
            Nov 10 at 5:14










          • &{ } was added because without it I get Bareword found where operator expected at ... line .., near "goto Test::More" (Do you need to predeclare goto?)
            – lukash
            Nov 10 at 5:36










          • @melpomene, I agree with lukash. I tested your code with 5.10 to 5.28, and none worked. You need goto &{ Test::More->can('import') } or goto(Test::More->can('import')) for your code to compile.
            – ikegami
            Nov 10 at 5:55










          • @lukash Should be fixed now. Took me a while to get the prerequisites installed to actually test this code.
            – melpomene
            Nov 10 at 6:01















          up vote
          4
          down vote



          accepted










          Sounds like you just want a helper module that loads some other modules and runs some initial tests for you.



          Something like:



          # ParentTest.pm
          package ParentTest;
          use strict;
          use warnings;

          use Test::Perl::Critic (-severity => 3);
          use Module::Path 'module_path';
          use Test::More;
          use Test::Log4perl;

          sub import {
          my (undef, $module, %args) = @_;

          $args{tests} += 2;

          plan %args;
          Test::Log4perl->suppress_logging;
          use_ok $module;
          critic_ok module_path $module;

          @_ = 'Test::More';
          goto +Test::More->can('import');
          }

          1


          Usage would be:



          use ParentTest "My::Module", tests => 6;


          This is all untested, but the idea is:




          • We want to run some code to set up the initial test plan and run some tests.

          • We also want to export everything that Test::More exports, so our caller doesn't have to use Test::More themselves.


          • use Some::Module @args is equivalent to BEGIN { require "Some/Module.pm"; Some::Module->import(@args); }, so we can just put our custom logic in the import method.

          • We start by ignoring the first argument (which is a class name because import is called as a class method) and assigning the remaining arguments to $module and %args.

          • We increment $args{tests} by 2 to account for the two extra tests we perform automatically (if tests wasn't passed in, it is implicitly created here).

          • We pass %args to plan from Test::More, which is nice for setting up a test plan outside of the initial use line.

          • We perform the initial tests.

          • We tail call Test::More::import, erasing our own stack frame. This makes it look like our caller did Test::More->import(), which exports all the Test::More utility functions to them.

          • The unary + in goto +Test::More->... has no real effect, but it helps distinguish between the goto LABEL and goto EXPRESSION syntactic forms. We want the latter interpretation.






          share|improve this answer























          • this is perfect, I submitted an edit to add &{} for the goto. I also added code to set/increate tests by 2 as use_ok and critic_ok are 2 tests already. I have not figured out how to make that nicer, can't seem to find a way to convert array to hash in-line without a variable. Feel free to prettify that part :-)) Thanks!
            – lukash
            Nov 10 at 5:04












          • @lukash I simplified the tests + 2 logic. Why add &{ }?
            – melpomene
            Nov 10 at 5:14










          • &{ } was added because without it I get Bareword found where operator expected at ... line .., near "goto Test::More" (Do you need to predeclare goto?)
            – lukash
            Nov 10 at 5:36










          • @melpomene, I agree with lukash. I tested your code with 5.10 to 5.28, and none worked. You need goto &{ Test::More->can('import') } or goto(Test::More->can('import')) for your code to compile.
            – ikegami
            Nov 10 at 5:55










          • @lukash Should be fixed now. Took me a while to get the prerequisites installed to actually test this code.
            – melpomene
            Nov 10 at 6:01













          up vote
          4
          down vote



          accepted







          up vote
          4
          down vote



          accepted






          Sounds like you just want a helper module that loads some other modules and runs some initial tests for you.



          Something like:



          # ParentTest.pm
          package ParentTest;
          use strict;
          use warnings;

          use Test::Perl::Critic (-severity => 3);
          use Module::Path 'module_path';
          use Test::More;
          use Test::Log4perl;

          sub import {
          my (undef, $module, %args) = @_;

          $args{tests} += 2;

          plan %args;
          Test::Log4perl->suppress_logging;
          use_ok $module;
          critic_ok module_path $module;

          @_ = 'Test::More';
          goto +Test::More->can('import');
          }

          1


          Usage would be:



          use ParentTest "My::Module", tests => 6;


          This is all untested, but the idea is:




          • We want to run some code to set up the initial test plan and run some tests.

          • We also want to export everything that Test::More exports, so our caller doesn't have to use Test::More themselves.


          • use Some::Module @args is equivalent to BEGIN { require "Some/Module.pm"; Some::Module->import(@args); }, so we can just put our custom logic in the import method.

          • We start by ignoring the first argument (which is a class name because import is called as a class method) and assigning the remaining arguments to $module and %args.

          • We increment $args{tests} by 2 to account for the two extra tests we perform automatically (if tests wasn't passed in, it is implicitly created here).

          • We pass %args to plan from Test::More, which is nice for setting up a test plan outside of the initial use line.

          • We perform the initial tests.

          • We tail call Test::More::import, erasing our own stack frame. This makes it look like our caller did Test::More->import(), which exports all the Test::More utility functions to them.

          • The unary + in goto +Test::More->... has no real effect, but it helps distinguish between the goto LABEL and goto EXPRESSION syntactic forms. We want the latter interpretation.






          share|improve this answer














          Sounds like you just want a helper module that loads some other modules and runs some initial tests for you.



          Something like:



          # ParentTest.pm
          package ParentTest;
          use strict;
          use warnings;

          use Test::Perl::Critic (-severity => 3);
          use Module::Path 'module_path';
          use Test::More;
          use Test::Log4perl;

          sub import {
          my (undef, $module, %args) = @_;

          $args{tests} += 2;

          plan %args;
          Test::Log4perl->suppress_logging;
          use_ok $module;
          critic_ok module_path $module;

          @_ = 'Test::More';
          goto +Test::More->can('import');
          }

          1


          Usage would be:



          use ParentTest "My::Module", tests => 6;


          This is all untested, but the idea is:




          • We want to run some code to set up the initial test plan and run some tests.

          • We also want to export everything that Test::More exports, so our caller doesn't have to use Test::More themselves.


          • use Some::Module @args is equivalent to BEGIN { require "Some/Module.pm"; Some::Module->import(@args); }, so we can just put our custom logic in the import method.

          • We start by ignoring the first argument (which is a class name because import is called as a class method) and assigning the remaining arguments to $module and %args.

          • We increment $args{tests} by 2 to account for the two extra tests we perform automatically (if tests wasn't passed in, it is implicitly created here).

          • We pass %args to plan from Test::More, which is nice for setting up a test plan outside of the initial use line.

          • We perform the initial tests.

          • We tail call Test::More::import, erasing our own stack frame. This makes it look like our caller did Test::More->import(), which exports all the Test::More utility functions to them.

          • The unary + in goto +Test::More->... has no real effect, but it helps distinguish between the goto LABEL and goto EXPRESSION syntactic forms. We want the latter interpretation.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 10 at 6:01

























          answered Nov 10 at 3:48









          melpomene

          56.6k54487




          56.6k54487












          • this is perfect, I submitted an edit to add &{} for the goto. I also added code to set/increate tests by 2 as use_ok and critic_ok are 2 tests already. I have not figured out how to make that nicer, can't seem to find a way to convert array to hash in-line without a variable. Feel free to prettify that part :-)) Thanks!
            – lukash
            Nov 10 at 5:04












          • @lukash I simplified the tests + 2 logic. Why add &{ }?
            – melpomene
            Nov 10 at 5:14










          • &{ } was added because without it I get Bareword found where operator expected at ... line .., near "goto Test::More" (Do you need to predeclare goto?)
            – lukash
            Nov 10 at 5:36










          • @melpomene, I agree with lukash. I tested your code with 5.10 to 5.28, and none worked. You need goto &{ Test::More->can('import') } or goto(Test::More->can('import')) for your code to compile.
            – ikegami
            Nov 10 at 5:55










          • @lukash Should be fixed now. Took me a while to get the prerequisites installed to actually test this code.
            – melpomene
            Nov 10 at 6:01


















          • this is perfect, I submitted an edit to add &{} for the goto. I also added code to set/increate tests by 2 as use_ok and critic_ok are 2 tests already. I have not figured out how to make that nicer, can't seem to find a way to convert array to hash in-line without a variable. Feel free to prettify that part :-)) Thanks!
            – lukash
            Nov 10 at 5:04












          • @lukash I simplified the tests + 2 logic. Why add &{ }?
            – melpomene
            Nov 10 at 5:14










          • &{ } was added because without it I get Bareword found where operator expected at ... line .., near "goto Test::More" (Do you need to predeclare goto?)
            – lukash
            Nov 10 at 5:36










          • @melpomene, I agree with lukash. I tested your code with 5.10 to 5.28, and none worked. You need goto &{ Test::More->can('import') } or goto(Test::More->can('import')) for your code to compile.
            – ikegami
            Nov 10 at 5:55










          • @lukash Should be fixed now. Took me a while to get the prerequisites installed to actually test this code.
            – melpomene
            Nov 10 at 6:01
















          this is perfect, I submitted an edit to add &{} for the goto. I also added code to set/increate tests by 2 as use_ok and critic_ok are 2 tests already. I have not figured out how to make that nicer, can't seem to find a way to convert array to hash in-line without a variable. Feel free to prettify that part :-)) Thanks!
          – lukash
          Nov 10 at 5:04






          this is perfect, I submitted an edit to add &{} for the goto. I also added code to set/increate tests by 2 as use_ok and critic_ok are 2 tests already. I have not figured out how to make that nicer, can't seem to find a way to convert array to hash in-line without a variable. Feel free to prettify that part :-)) Thanks!
          – lukash
          Nov 10 at 5:04














          @lukash I simplified the tests + 2 logic. Why add &{ }?
          – melpomene
          Nov 10 at 5:14




          @lukash I simplified the tests + 2 logic. Why add &{ }?
          – melpomene
          Nov 10 at 5:14












          &{ } was added because without it I get Bareword found where operator expected at ... line .., near "goto Test::More" (Do you need to predeclare goto?)
          – lukash
          Nov 10 at 5:36




          &{ } was added because without it I get Bareword found where operator expected at ... line .., near "goto Test::More" (Do you need to predeclare goto?)
          – lukash
          Nov 10 at 5:36












          @melpomene, I agree with lukash. I tested your code with 5.10 to 5.28, and none worked. You need goto &{ Test::More->can('import') } or goto(Test::More->can('import')) for your code to compile.
          – ikegami
          Nov 10 at 5:55




          @melpomene, I agree with lukash. I tested your code with 5.10 to 5.28, and none worked. You need goto &{ Test::More->can('import') } or goto(Test::More->can('import')) for your code to compile.
          – ikegami
          Nov 10 at 5:55












          @lukash Should be fixed now. Took me a while to get the prerequisites installed to actually test this code.
          – melpomene
          Nov 10 at 6:01




          @lukash Should be fixed now. Took me a while to get the prerequisites installed to actually test this code.
          – melpomene
          Nov 10 at 6:01


















           

          draft saved


          draft discarded



















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53235746%2fperl-tests-common-parent-for-tests%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Guess what letter conforming each word

          Port of Spain

          Run scheduled task as local user group (not BUILTIN)